I have tried this solution found in the following questions, but none work in my case:
@Configuration @EnableWebMvc @ComponentScan("myapp.framework.export") public class WebConfig extends MyAppWebConfig { @Override public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) { super.configureContentNegotiation(configurer); } @Override public void configureMessageConverters(final List<HttpMessageConverter<?>> converters) { super.configureMessageConverters(converters); } } Error:
INFO: Initializing Spring FrameworkServlet 'services-rest' 2017-04-11 15:25:52,774|localhost-startStop-1|NO_TID|NO_USER|ERROR|org.springframework.web.servlet.DispatcherServlet.initServletBean|Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xlsHttpMessageConverter': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'myapp.framework.export.ExportXlsModelService<?>[]' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)} at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:321) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:634) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:682) at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:553) at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494) at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:138) at javax.servlet.GenericServlet.init(GenericServlet.java:158) at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1241) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1154) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1041) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4969) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5255) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'myapp.framework.export.ExportXlsModelService<?>[]' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1486) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:518) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:496) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:627) at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:318) ... 29 common frames omitted Apr 11, 2017 3:25:52 PM org.apache.catalina.core.ApplicationContext log SEVERE: StandardWrapper.Throwable org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xlsHttpMessageConverter': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'myapp.framework.export.ExportXlsModelService<?>[]' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)} at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:321) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:634) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:682) at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:553) at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494) at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:138) at javax.servlet.GenericServlet.init(GenericServlet.java:158) at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1241) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1154) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1041) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4969) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5255) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'myapp.framework.export.ExportXlsModelService<?>[]' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1486) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:518) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:496) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:627) at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:318) ... 29 more Apr 11, 2017 3:25:52 PM org.apache.catalina.core.StandardContext loadOnStartup SEVERE: Servlet /myapp threw load() exception org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'myapp.framework.export.ExportXlsModelService<?>[]' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1486) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:518) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:496) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:627) at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:318) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:634) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:682) at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:553) at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494) at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:138) at javax.servlet.GenericServlet.init(GenericServlet.java:158) at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1241) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1154) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1041) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4969) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5255) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Apr 11, 2017 3:25:52 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["http-nio-8080"] Apr 11, 2017 3:25:52 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["ajp-nio-8009"] Apr 11, 2017 3:25:52 PM org.apache.catalina.startup.Catalina start INFO: Server startup in 10565 ms xlsHttpMessageConverter:
package myapp.framework.web.converter; import myapp.framework.export.ExportXlsModelService; import java.io.IOException; import java.io.OutputStream; import javax.annotation.Resource; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.stereotype.Service; @Service public class XlsHttpMessageConverter<T> extends AbstractMyAppHttpMessageConverter<T, ExportXlsModelService<T>> { @Resource private ExportXlsModelService<T>[] exportServices; public XlsHttpMessageConverter() { super(MyAppMediaType.APPLICATION_EXCEL); } @Override protected void ecrireFichier(final T toExport, final OutputStream os) throws IOException, HttpMessageNotWritableException { final ExportXlsModelService<T> exportService = getServiceExport(toExport); final HSSFWorkbook model = exportService.construireXlsModel(toExport); model.write(os); } @Override protected ExportXlsModelService<T>[] getServicesExport() { return exportServices; } } 5 Answers
Answers 1
Try to add classpath*: Prefix to your scan. (read here)
The * means scan in all jars on classpath
UPDATE:
Your converter has package myapp.framework.web.converter but scan checks myapp.framework.export
Answers 2
Spring is unable to find the implementation for ExportXlsModelService interface.
public interface ExportXlsModelService<T> extends ExportModelService<T> { public HSSFWorkbook construireXlsModel(T toExport); } Something like
@Service public class ExportXlsModelServiceImpl1 implements ExportXlsModelService<Model> { @Override public HSSFWorkbook construireXlsModel(Model toExport) { // implementation goes here } } @Service public class ExportXlsModelServiceImpl2 implements ExportXlsModelService<Model> { @Override public HSSFWorkbook construireXlsModel(Model toExport) { // implementation goes here } } Answers 3
I think there is issue in autowiring as Generic class. We have to specify particular Type while autowiring.
Following Reference may be useful:
Answers 4
You can't have a @Service that has a type parameter T, how would Spring know what T should be when it instantiates the bean.
If you have 5 different XlsHttpMessageConverter<T>, you have to declare 5 beans. Unfortunately even if you define each converter as a separate bean, there is no way for Spring to know which ExportXlsModelService<T>[] exportServices; to inject, as it will consider all ExportXlsModelService as candidate regardless of the type parameter (see edit below).
It is however possible to inject a bean of a specific type into a @Bean method, so the following example works (but is very impractical for large number of types).
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.List; import static org.junit.Assert.assertNotNull; @Configuration public class MyConfig { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class); ConverterInjectionTarget bean = ctx.getBean(ConverterInjectionTarget.class); System.out.println("injected Converters = " + bean.converters.size()); for (XlsHttpMessageConverter converter : bean.converters) { assertNotNull(converter.value); } } // correct version of generic bean can be autowired into @Bean method @Bean XlsHttpMessageConverter integerConverter(Injectable<Integer> value) { return new XlsHttpMessageConverter<>(value); } @Bean XlsHttpMessageConverter StringConverter(Injectable<String> value) { return new XlsHttpMessageConverter<String>(value); } @Bean Injectable<Integer> integerDummyBean() { return new Injectable<>(1); } @Bean Injectable<String> stringDummyBean() { return new Injectable<>("hello"); } @Bean ConverterInjectionTarget myBean() { return new ConverterInjectionTarget(); } static class XlsHttpMessageConverter<T> { // impossible to autowire this, it has to be set through the constructor final Injectable<T> value; XlsHttpMessageConverter(Injectable<T> value) { this.value = value; } } static class ConverterInjectionTarget { @Autowired List<XlsHttpMessageConverter> converters; } class Injectable<T> { final T value; Injectable(T value) { this.value = value; } } } If you modify the example and try to autowire the Injectable into XlsHttpMessageConverter you will see that it fails.
The best solution may be to create a BeanFactoryPostProcessor that will create all the ExportXlsModelService instances programmatically, and provide them as input to the XlsHttpMessageConverter instances, which are then registered as singletons.
EDIT One thing I did not mention, is that it is possible to autowire a generic type, but it requires that the bean is defined as a concrete class (not using a @Bean method), so the following would also work (multiple files).
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import java.util.List; import static org.junit.Assert.assertNotNull; @Configuration @ComponentScan("myPackage") public class MyConfig { public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class); ConverterInjectionTarget bean = ctx.getBean(ConverterInjectionTarget.class); System.out.println("injected Converters = " + bean.converters.size()); for (XlsHttpMessageConverter converter : bean.converters) { assertNotNull(converter.value); } } @Bean Injectable<Integer> integerDummyBean() { return new Injectable<>(1); } @Bean Injectable<String> stringDummyBean() { return new Injectable<>("hello"); } @Bean ConverterInjectionTarget myBean() { return new ConverterInjectionTarget(); } static class ConverterInjectionTarget { @Autowired List<XlsHttpMessageConverter> converters; } static class Injectable<T> { final T value; Injectable(T value) { this.value = value; } } } abstract class XlsHttpMessageConverter<T> { // this is possible to autowire because we have a concrete class that spring can read the bytecode from. @Autowired MyConfig.Injectable<T> value; } @Service public class IntegerXlsHttpMessageConverter<T> extends XlsHttpMessageConverter<Integer> { } @Service public class StringXlsHttpMessageConverter extends XlsHttpMessageConverter<String> { } But again this may not be feasible if there are many types.
Answers 5
Did you try using @Import, if the dependent jar has some @Configuration classes, that defines the bean use @Import for aggregating configurations. Link
0 comments:
Post a Comment