Spring IntegrationFlow Http.inboundGateway ambiguous parameter type - spring

I'm trying to convert the following spring integration sample to a Java Config version. https://github.com/dsyer/http-amqp-tunnel
We need a slightly modified version of this project to work in a production environment. My problem is that I keep getting the following exception when starting the application.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'httpInboundGateway' defined in org.springframework.platform.proxy.TunnelApplication: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.integration.dsl.IntegrationFlow]: Factory method 'httpInboundGateway' threw exception; nested exception is java.lang.IllegalArgumentException: Found ambiguous parameter type [class [Ljava.lang.String;] for method match: [public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.multipartResolver(org.springframework.web.multipart.MultipartResolver), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.replyMapper(org.springframework.integration.mapping.OutboundMessageMapper), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.autoStartup(boolean), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.mappedResponseHeaders(java.lang.String[]), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.phase(int), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.crossOrigin(org.springframework.integration.dsl.support.Consumer), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.errorChannel(java.lang.String), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.headerMapper(org.springframework.integration.mapping.HeaderMapper), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.requestMapper(org.springframework.integration.mapping.InboundMessageMapper), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.messageConverters(org.springframework.http.converter.HttpMessageConverter[]), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.requestTimeout(long), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.payloadExpression(org.springframework.expression.Expression), public java.lang.Class org.springframework.integration.dsl.core.IntegrationComponentSpec.getObjectType(), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.requestPayloadType(java.lang.Class), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.payloadFunction(org.springframework.integration.dsl.support.Function), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.errorChannel(org.springframework.messaging.MessageChannel)]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.platform.proxy.TestServerApplication.main(TestServerApplication.java:11) [classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.integration.dsl.IntegrationFlow]: Factory method 'httpInboundGateway' threw exception; nested exception is java.lang.IllegalArgumentException: Found ambiguous parameter type [class [Ljava.lang.String;] for method match: [public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.multipartResolver(org.springframework.web.multipart.MultipartResolver), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.replyMapper(org.springframework.integration.mapping.OutboundMessageMapper), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.autoStartup(boolean), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.mappedResponseHeaders(java.lang.String[]), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.phase(int), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.crossOrigin(org.springframework.integration.dsl.support.Consumer), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.errorChannel(java.lang.String), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.headerMapper(org.springframework.integration.mapping.HeaderMapper), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.requestMapper(org.springframework.integration.mapping.InboundMessageMapper), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.messageConverters(org.springframework.http.converter.HttpMessageConverter[]), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.requestTimeout(long), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.payloadExpression(org.springframework.expression.Expression), public java.lang.Class org.springframework.integration.dsl.core.IntegrationComponentSpec.getObjectType(), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.requestPayloadType(java.lang.Class), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.payloadFunction(org.springframework.integration.dsl.support.Function), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.errorChannel(org.springframework.messaging.MessageChannel)]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
... 18 common frames omitted
Caused by: java.lang.IllegalArgumentException: Found ambiguous parameter type [class [Ljava.lang.String;] for method match: [public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.multipartResolver(org.springframework.web.multipart.MultipartResolver), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.replyMapper(org.springframework.integration.mapping.OutboundMessageMapper), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.autoStartup(boolean), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.mappedResponseHeaders(java.lang.String[]), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.phase(int), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.crossOrigin(org.springframework.integration.dsl.support.Consumer), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.errorChannel(java.lang.String), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.headerMapper(org.springframework.integration.mapping.HeaderMapper), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.requestMapper(org.springframework.integration.mapping.InboundMessageMapper), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.messageConverters(org.springframework.http.converter.HttpMessageConverter[]), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.requestTimeout(long), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.payloadExpression(org.springframework.expression.Expression), public java.lang.Class org.springframework.integration.dsl.core.IntegrationComponentSpec.getObjectType(), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.requestPayloadType(java.lang.Class), public org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec org.springframework.integration.dsl.http.BaseHttpInboundEndpointSpec.payloadFunction(org.springframework.integration.dsl.support.Function), public org.springframework.integration.dsl.core.MessagingGatewaySpec org.springframework.integration.dsl.core.MessagingGatewaySpec.errorChannel(org.springframework.messaging.MessageChannel)]
at org.springframework.util.Assert.isNull(Assert.java:92) ~[spring-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.integration.util.MessagingMethodInvokerHelper.findHandlerMethodsForTarget(MessagingMethodInvokerHelper.java:497) ~[spring-integration-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.util.MessagingMethodInvokerHelper.<init>(MessagingMethodInvokerHelper.java:226) ~[spring-integration-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.util.MessagingMethodInvokerHelper.<init>(MessagingMethodInvokerHelper.java:149) ~[spring-integration-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.util.MessagingMethodInvokerHelper.<init>(MessagingMethodInvokerHelper.java:144) ~[spring-integration-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.handler.MethodInvokingMessageProcessor.<init>(MethodInvokingMessageProcessor.java:60) ~[spring-integration-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.handler.ServiceActivatingHandler.<init>(ServiceActivatingHandler.java:37) ~[spring-integration-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:985) ~[spring-integration-java-dsl-1.2.1.RELEASE.jar:na]
at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:964) ~[spring-integration-java-dsl-1.2.1.RELEASE.jar:na]
at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:950) ~[spring-integration-java-dsl-1.2.1.RELEASE.jar:na]
at org.springframework.platform.proxy.TunnelApplication.httpInboundGateway(TunnelApplication.java:93) ~[classes/:na]
at org.springframework.platform.proxy.TunnelApplication$$EnhancerBySpringCGLIB$$4e2cc6e6.CGLIB$httpInboundGateway$3(<generated>) ~[classes/:na]
at org.springframework.platform.proxy.TunnelApplication$$EnhancerBySpringCGLIB$$4e2cc6e6$$FastClassBySpringCGLIB$$e8c73d4b.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.platform.proxy.TunnelApplication$$EnhancerBySpringCGLIB$$4e2cc6e6.httpInboundGateway(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_66]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_66]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
... 19 common frames omitted
Here's my modified version of TunnelApplication. The original can be found in the project link above.
package org.springframework.platform.proxy;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.*;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.dsl.*;
import org.springframework.integration.dsl.amqp.Amqp;
import org.springframework.integration.dsl.http.Http;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.support.HttpRequestHandlerServlet;
#Configuration
#ComponentScan
#EnableAutoConfiguration
#EnableIntegration
public class TunnelApplication
{
public static void main(String[] args)
{
SpringApplication.run(TunnelApplication.class, args);
}
#Value("${urlExpression}")
private String urlExpression;
#Value("${outboundQueue}")
private String outboundQueue;
#Value("${inboundQueue}")
private String inboundQueue;
#Autowired
private ConnectionFactory rabbitConnectionFactory;
#Bean
public Queue requestQueue()
{
return new Queue(outboundQueue, true, false, true);
}
#Bean
public Queue targetQueue()
{
return new Queue(inboundQueue, true, false, true);
}
#Bean
public ServletRegistrationBean httpInboundGatewayServletRegistration()
{
ServletRegistrationBean bean = new ServletRegistrationBean(httpInboundGatewayServlet(), "/tunnel/*");
bean.setName("httpInboundGateway");
return bean;
}
#Bean
public HttpRequestHandlerServlet httpInboundGatewayServlet()
{
return new HttpRequestHandlerServlet();
}
#Bean
public RestTemplate safeRestTemplate()
{
return new RestTemplate();
}
#Bean
public Jackson2JsonMessageConverter jsonMessageConverter()
{
return new Jackson2JsonMessageConverter();
}
#Bean
public AmqpTemplate amqpTemplate()
{
RabbitTemplate result = new RabbitTemplate(rabbitConnectionFactory);
result.setMessageConverter(jsonMessageConverter());
return result;
}
#Bean
public IntegrationFlow httpInboundGateway()
{
return IntegrationFlows.from("outbound")
.handle(Http.inboundGateway("/tunnel"))
.get();
}
#Bean
public IntegrationFlow amqpOutbound(AmqpTemplate amqpTemplate)
{
return IntegrationFlows.from("outbound")
.handle(
Amqp.outboundAdapter(amqpTemplate)
.mappedRequestHeaders("http_*")
.routingKeyExpression("headers['routingKey']")
)
.get();
}
#Bean
public IntegrationFlow amqpInboundGateway(ConnectionFactory connectionFactory)
{
return IntegrationFlows.from("inbound").handle
(
Amqp.inboundGateway(connectionFactory, inboundQueue)
.mappedRequestHeaders("http_*")
.messageConverter(jsonMessageConverter())
)
.get();
}
#Bean
public IntegrationFlow httpOutboundGateway()
{
return IntegrationFlows.from("inbound").handle(Http.outboundGateway(urlExpression)).get();
}
}
When I run TunnelApplication I get the above error. My maven pom file has been modified as follows. The main difference being that I'm using spring boot 1.5.1 and the original project uses 1.1.4.BUILD-SNAPSHOT.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.redi</groupId>
<artifactId>redi-parent</artifactId>
<version>5.0.0</version>
</parent>
<artifactId>http-amqp-tunnel</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>HTTP AMQP Tunnel</name>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-http</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jmx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>org.springframework.platform.proxy.TunnelApplication</start-class>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I'd really appreciate some guidance. This is my first spring integration project and I feel like I'm close.
Thanks in advance for your help.
Revised Configuration
package org.springframework.platform.proxy;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.*;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.dsl.*;
import org.springframework.integration.dsl.amqp.Amqp;
import org.springframework.integration.dsl.http.Http;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.support.HttpRequestHandlerServlet;
#Configuration
#ComponentScan
#EnableAutoConfiguration
#EnableIntegration
public class TunnelApplication
{
public static void main(String[] args)
{
SpringApplication.run(TunnelApplication.class, args);
}
#Value("${urlExpression}")
private String urlExpression;
#Value("${outboundQueue}")
private String outboundQueue;
#Value("${inboundQueue}")
private String inboundQueue;
#Autowired
private ConnectionFactory rabbitConnectionFactory;
#Bean
public Queue requestQueue()
{
return new Queue(outboundQueue, true, false, true);
}
#Bean
public Queue targetQueue()
{
return new Queue(inboundQueue, true, false, true);
}
#Bean
public ServletRegistrationBean httpInboundGatewayServletRegistration()
{
ServletRegistrationBean bean = new ServletRegistrationBean(httpInboundGatewayServlet(), "/tunnel/*");
bean.setName("httpInboundGateway");
return bean;
}
#Bean
public HttpRequestHandlerServlet httpInboundGatewayServlet()
{
return new HttpRequestHandlerServlet();
}
#Bean
public RestTemplate safeRestTemplate()
{
return new RestTemplate();
}
#Bean
public Jackson2JsonMessageConverter jsonMessageConverter()
{
return new Jackson2JsonMessageConverter();
}
#Bean
public AmqpTemplate amqpTemplate()
{
RabbitTemplate result = new RabbitTemplate(rabbitConnectionFactory);
result.setMessageConverter(jsonMessageConverter());
return result;
}
#Bean
public IntegrationFlow httpInboundGateway()
{
return IntegrationFlows.from(Http.inboundGateway("/tunnel")).channel("outbound")
.get();
}
#Bean
public IntegrationFlow amqpOutbound(AmqpTemplate amqpTemplate)
{
return IntegrationFlows.from("outbound")
.handle(
Amqp.outboundAdapter(amqpTemplate)
.mappedRequestHeaders("http_*")
.routingKeyExpression("headers['routingKey']")
)
.get();
}
#Bean
public IntegrationFlow amqpInboundGateway(ConnectionFactory connectionFactory)
{
return IntegrationFlows.from
(
Amqp.inboundGateway(connectionFactory, inboundQueue)
.mappedRequestHeaders("http_*")
.messageConverter(jsonMessageConverter())
)
.channel("inbound")
.get();
}
#Bean
public IntegrationFlow httpOutboundGateway()
{
return IntegrationFlows.from("inbound").handle(Http.outboundGateway(urlExpression)).get();
}
The error I am now getting when I navigate to http://localhost:9000/tunnel is the following:
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'httpInboundGateway' is expected to be of type 'org.springframework.web.HttpRequestHandler' but was actually of type 'org.springframework.integration.dsl.StandardIntegrationFlow'
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:378) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1087) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.web.context.support.HttpRequestHandlerServlet.init(HttpRequestHandlerServlet.java:57) ~[spring-web-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at javax.servlet.GenericServlet.init(GenericServlet.java:158) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1183) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
at
}

.handle(Http.inboundGateway("/tunnel"))
You can't invoke an inbound gateway from a .handle() method.
Inbound endpoints are not consumers.
It looks like it should be .from(Http.in...).
You have the same issue with the amqp inbound endpoint.

Related

Spring-boot 2.7.0 with jax-ws 1.9 WSServletContextListener Unable to start embedded Tomcat

What do I do wrong with JAX-WS and SPRING-BOOT?
I use jaxws-spring v1.9, spring-boot-starter-parent v2.7.0.
I don`t have web.xml.
I have #WebService() #SOAPBinding()
My problem is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
but file is in /src/main/resource/WEB-INF/sun-jaxws.xml
2022-08-04 16:47:58.026 ERROR 20076 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:165) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577) ~[spring-context-5.3.20.jar:5.3.20]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.0.jar:2.7.0]
at com.thecloud.telecom.TelecomApplication.main(TelecomApplication.java:14) ~[classes/:na]
Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:142) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:479) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:211) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:184) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:162) ~[spring-boot-2.7.0.jar:2.7.0]
... 8 common frames omitted
Caused by: java.lang.IllegalStateException: StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[] failed to start
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.rethrowDeferredStartupExceptions(TomcatWebServer.java:187) ~[spring-boot-2.7.0.jar:2.7.0]
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:126) ~[spring-boot-2.7.0.jar:2.7.0]
... 13 common frames omitted
Disconnected from the target VM, address: '127.0.0.1:52298', transport: 'socket'
Process finished with exit code 1
It happens when I try to use
JaxWsListener
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import com.sun.xml.ws.transport.http.servlet.WSServletContextListener;
#WebListener
public class JaxWsListener implements ServletContextAttributeListener, ServletContextListener {
private final WSServletContextListener listener;
public JaxWsListener() {
this.listener = new WSServletContextListener();
}
#Override
public void attributeAdded(ServletContextAttributeEvent event) {
listener.attributeAdded(event);
}
#Override
public void attributeRemoved(ServletContextAttributeEvent event) {
listener.attributeRemoved(event);
}
#Override
public void attributeReplaced(ServletContextAttributeEvent event) {
listener.attributeReplaced(event);
}
#Override
public void contextInitialized(ServletContextEvent sce) {
listener.contextInitialized(sce);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
listener.contextDestroyed(sce);
}
}
without this Listener spring-boot (tomcat) started well.
for JAX-WS as well I use this class :
JaxWsServlet
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.xml.ws.transport.http.servlet.WSServlet;
import lombok.extern.log4j.Log4j2;
#Log4j2
#WebServlet(name = "JaxWsServlet", urlPatterns = JaxWsServlet.URL_PATTERN, loadOnStartup = 1)
public class JaxWsServlet extends WSServlet {
public static final String URL_PATTERN = "/jaxws";
public JaxWsServlet() {
LOG.debug("CREATE {}", this.getClass().getSimpleName());
}
#Override
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
LOG.debug("JAX-WS Init");
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException {
super.doPost(request, response);
LOG.debug("JAX-WS DoPost");
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
super.doGet(request, response);
LOG.debug("JAX-WS DoGet");
}
}
as well I have /WEB-INF/soap-jaxws.xml
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
version="2.0">
<endpoint name="SoapService"
implementation="com.ws.endpoint.SoapService"
url-pattern="/ws/call1" />
<endpoint name="SoapService2"
implementation="com.ws.endpoint.SoapService2"
url-pattern="/ws/call2" />
</endpoints>
this file parsed in the WSServletContextListener - it is hard coded there.
I solved this issue by putting /WEB-INF/sun-jaxws.xml into **/srv/main/resources/META-INF/resources/**WEB-INF/sun-jaxrs.xml
this helped me
It is enough to have in your spring-boot application:
/WEB-INF/sun-jaxws.xml - BCS it is HARDCODED in the jax-ws
#WebService
#WebListener
spring-boot-starter-parent:2.7.0
org.jvnet.jax-ws-commons.spring:jaxws-spring:1.9 - with exclusions
#Service
#WebService(
name = "SoapService",
endpointInterface = "com.ws.service.SoapService")
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public class SoapService
implements ISoapService { ....
and #WebListener (look at it above)
#WebListener
public class JaxWsListener implements ServletContextAttributeListener, ServletContextListener {
private final WSServletContextListener listener;
........
You do not need #WebServlet
pom.xml:
<dependency>
<groupId>org.jvnet.jax-ws-commons.spring</groupId>
<artifactId>jaxws-spring</artifactId>
<version>1.9</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
</exclusion>
<!-- ? -->
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.xml.stream.buffer</groupId>
<artifactId>streambuffer</artifactId>
</exclusion>
<exclusion>
<groupId>org.jvnet.staxex</groupId>
<artifactId>stax-ex</artifactId>
</exclusion>
</exclusions>
</dependency>

Spring couldn't create bean of Implemented IgniteRepository

I am using spring boot and Ignite Database
I have created only one Repository and I am setting data in Pojo to save using IgniteRepository
Here are the required dependency for Ignite with Spring: Ignite Version :: 2.0.0
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-core</artifactId>
<version>${ignite.version}</version>
</dependency>
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-spring</artifactId>
<version>${ignite.version}</version>
</dependency>
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-indexing</artifactId>
<version>${ignite.version}</version>
</dependency>
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-spring-data</artifactId>
<version>${ignite.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.195</version>
</dependency>
Here I am using H2 database dependencies If I don't use it I receive another error which is completely unknown.
IgniteConfiguration :
#Configuration
#EnableIgniteRepositories(excludeFilters = {
#ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {
TempRepository.class, GarageRepository.class, CarRepository.class,
IncidentRepository.class, MachineRepository.class, MileageRepository.class,
LicenseRepository.class})
})
public class IgniteSpringConfiguration {
#Bean
public Ignite igniteInstance() {
IgniteConfiguration cfg = new IgniteConfiguration();
// Setting some custom name for the node.
cfg.setIgniteInstanceName("eventInsights");
// Enabling peer-class loading feature.
cfg.setPeerClassLoadingEnabled(true);
// Defining and creating a new cache to be used by Ignite Spring Data
// repository.
CacheConfiguration<Long, User> userCacheConfig = new CacheConfiguration<Long, User>("UserCacheConfig");
// Setting SQL schema for the cache.
userCacheConfig.setIndexedTypes(Long.class, User.class);
cfg.setCacheConfiguration(new CacheConfiguration[] {
userCacheConfig,
});
return Ignition.start(cfg);
}
}
UserRepository Interface:
#RepositoryConfig(cacheName = "UserCacheConfig")
public interface UserRepository extends IgniteRepository<User, Long>{
User findByEmail(String email);
}
Now Main Class::
private static UserRepository userRepo;
private static AnnotationConfigApplicationContext ctx;
public static void main(String[] args) {
ctx = new AnnotationConfigApplicationContext();
ctx.register(IgniteSpringConfiguration.class);
ctx.refresh();
userRepo= ctx.getBean(UserRepository.class);
User user=new User();
user.setEmail("george.paul01#xyz.com");
user.setId(1L);
user.setPassword("password");
userRepo.save(user);
User getUser=userRepo.findByEmail("george.paul01#xyz.com");
if(getUser!=null) {
System.out.println(getUser.getEmail());
System.out.println(getUser.getPassword());
}
else {
System.out.println("User name is not found");
}
}
User Pojo:
public class User implements Serializable
{
private static final long serialVersionUID = 1L;
public Long id;
#QuerySqlField(index = true)
private String password;
#QuerySqlField(index = true)
private String email;
//getters and setters method here I am skipping in my question
}
After running I am getting error :
Exception in thread "main"
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'userRepository': Unsatisfied dependency
expressed through constructor parameter 0; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
'java.lang.Class>' available: expected at least 1 bean which qualifies as autowire
candidate. Dependency annotations: {} at
org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
at
org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1193)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1095)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
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:742)
at
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at
com.mphasis.springreact.services.admin.AdminController.main(AdminController.java:14)
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
'java.lang.Class>' available: expected at least 1 bean which qualifies as autowire
candidate. Dependency annotations: {} 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.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
at
org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
... 13 more
#RepositoryConfig does not declare #Repository or #Component. Guess it doesn't get component scanned. Try:
#Component
#RepositoryConfig(cacheName = "UserCacheConfig")
public interface UserRepository extends IgniteRepository<User, Long>{
User findByEmail(String email);
}

Spring Boot Runs on Tomcat 8.5.x but not 8.0.37 java.lang.NoClassDefFoundError: org/apache/coyote/UpgradeProtocol

relatively new to Spring so I am guessing I am not doing something correctly. I have been converting an older java soap service to spring. I am able to run it locally on tomcat 8.5 and up, but when I run it on tomcat 8.0.37 (which is what the server I will deploy it to is on) I get the error below. I came across this error in another project, but realized in the other project I was unnecessarily creating a servlet, so once I ripped out the servlet code I was good to go. In this instance I need to create a servlet. The error is looking for "org/apache/coyote/UpgradeProtocol" which is not in Tomcat 8.0.37. Not sure what in my code is trying to use it. Any suggestions are appreciated, thanks.
Tomcat dependencies in pom...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.7.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
error...
2019-01-17 16:05:12,539 SEVERE Class= org.apache.catalina.core.ContainerBase Method= addChildInternal Message= ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/exampleServices]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:162)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:940)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1816)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
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.BeanCreationException: Error creating bean with name 'containerFactory' defined in class path resource [com/removed/exampleServices/exampleServicesConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory]: Factory method 'containerFactory' threw exception; nested exception is java.lang.NoClassDefFoundError: org/apache/coyote/UpgradeProtocol
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:591)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1246)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1096)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:535)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:759)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:548)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:386)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:157)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:137)
at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:91)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:172)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5303)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
config class below, I assume the issue is with how I am creating my TomcatServletWebServerFactory or my ServletRegistrationBean
#ComponentScan({"com.example.exampleservices", "com.example.examplesoapservices"})
#Configuration
#EnableAWSF
public class exampleservicesConfiguration {
static {
// Statically initialize SystemImpl so it doesn't slow down first
// request
try {
SystemImpl.getInstance();
} catch (exampleException e) {
throw new RuntimeException(e);
}
}
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new WSSpringServlet(), "/exampleservicesSOAP/*", "/exampleservicesSOAPV3/*");
//ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new WSSpringServlet(), "/exampleservicesPort/*", "/exampleservicesPortV3/*");
servletRegistrationBean.setEnabled(true);
servletRegistrationBean.setLoadOnStartup(0);
return servletRegistrationBean;
}
#Bean
#SneakyThrows
public SpringBinding springBinding(exampleservicesSOAPImpl exampleservicesSOAPImpl, AWSFHandlers awsfHandlers) throws Exception {
SpringBinding springBinding = new SpringBinding();
springBinding.setUrl("/exampleservicesSOAP");
SpringService springService = new SpringService();
springService.setBean(exampleservicesSOAPImpl);
springService.setHandlers(awsfHandlers.getAwsfHandlers());
springBinding.setService(springService.getObject());
return springBinding;
}
#Bean
#SneakyThrows
public SpringBinding springBindingV3(exampleservicesSOAPV3Impl exampleservicesSOAPV3Impl, AWSFHandlers awsfHandlers) throws Exception {
SpringBinding springBinding = new SpringBinding();
springBinding.setUrl("/exampleservicesSOAPV3");
SpringService springService = new SpringService();
springService.setBean(exampleservicesSOAPV3Impl);
springService.setHandlers(awsfHandlers.getAwsfHandlers());
springBinding.setService(springService.getObject());
return springBinding;
}
#Bean
public Executor threadPoolTaskExecutor(){
return new ThreadPoolTaskExecutor();
}
#Bean
public TomcatServletWebServerFactory containerFactory() {
return new TomcatServletWebServerFactory () {
protected void customizeConnector(Connector connector) {
super.customizeConnector(connector);
}
};
}
#Bean
public Jaxb2Marshaller jaxb2Marshaller() {
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setContextPath(exJAXBContext.JAXB_CONTEXT_PATH);
return jaxb2Marshaller;
}
#Bean
private static JAXBContext initContext() {
try {
return JAXBContext.newInstance(BasicServiceComponents.eesvcof.getClass().getPackage().getName() + ":" + BasicServiceComponents.eesvcofV3.getClass().getPackage().getName());
} catch (JAXBException e) {
e.printStackTrace();
return null;
}
}
private static final JAXBContext context = initContext();
#Bean
public Marshaller marshaller() {
Marshaller marshaller = null;
try {
marshaller = this.context.createMarshaller();
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//any setters
return marshaller;
}
#Bean
public Unmarshaller unmarshaller() {
Unmarshaller unmarshaller = null;
try {
unmarshaller = this.context.createUnmarshaller();
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//any setters
return unmarshaller;
}
}
Well , most probably it is because Spring Boot 2.0 series requires Tomcat 8.5 which is mentioned in the release note. That UpgradeProtocol is something related to HTTP2 which does not exist in Tomcat 8.0 , so your best bet is try to disable HTTP2 in the application.properties :
server.http2.enabled=false
So the code that was breaking is
#Bean
public TomcatServletWebServerFactory containerFactory() {
return new TomcatServletWebServerFactory () {
protected void customizeConnector(Connector connector) {
super.customizeConnector(connector);
}
};
}
When I was testing before I was commenting this out and when I would run locally I would get a different error. Someone I work with suggested removing this bean (I guess it is not needed with spring 2) and also removing my pom code that specifies the tomcat version. This worked. So locally spring is managing my Tomcat version. I believe spring sets Tomcat to 8.5.35 for the spring 2.0.7 release. When I deploy my code it now runs fine on Tomcat 8.0.35. So you do not need that bean, and when running locally just let spring set your own Tomcat version. I am not sure why that bean works on Tomcat 8.5.35 but I don't need it anyways.

Spring Java Config Error creating bean with name 'entityManagerFactory' defined in class path resource

I'm trying to convert the xml application configuration files to Java based configuration.
I'm encountering a problem with the entityManager. It worked well with persistence.xml and web.xml
<!-- Entity Manager -->
<jee:jndi-lookup id="entityManagerFactory" jndi-name="jdbc/derby"></jee:jndi-lookup>
I use
Spring 3.2
maven 3
Java 7
glassfish embedded 3.1.1
Spring Data JPA 1.4.2
Could you help me ? Thank you !
Stack trace
mai 27, 2014 11:19:57 PM org.apache.catalina.core.ContainerBase addChildInternal
Grave: ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [com/marc/embeddedglassfish/config/PersistenceContext.class]: Invocation of init method failed; nested exception is java.lang.reflect.UndeclaredThrowableException
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5389)
at com.sun.enterprise.web.WebModule.start(WebModule.java:498)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:917)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:901)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:733)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2000)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1651)
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:109)
at org.glassfish.internal.data.EngineRef.start(EngineRef.java:130)
at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:269)
at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:294)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:462)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:382)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:355)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1064)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1244)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1232)
at com.sun.enterprise.admin.cli.embeddable.DeployerImpl.deploy(DeployerImpl.java:129)
at com.sun.enterprise.admin.cli.embeddable.DeployerImpl.deploy(DeployerImpl.java:105)
at org.glassfish.maven.PluginUtil.doDeploy(PluginUtil.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.glassfish.maven.AbstractDeployMojo.doDeploy(AbstractDeployMojo.java:239)
at org.glassfish.maven.RunMojo.execute(RunMojo.java:68)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:107)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:319)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:534)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [com/marc/embeddedglassfish/config/PersistenceContext.class]: Invocation of init method failed; nested exception is java.lang.reflect.UndeclaredThrowableException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1486)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1117)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:922)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:383)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:4750)
at com.sun.enterprise.web.WebModule.contextListenerStart(WebModule.java:550)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5366)
... 49 more
Caused by: java.lang.reflect.UndeclaredThrowableException
at com.sun.proxy.$Proxy147.addTransformer(Unknown Source)
at org.eclipse.persistence.jpa.PersistenceProvider.createContainerEntityManagerFactory(PersistenceProvider.java:231)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:287)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1483)
... 64 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager$Jpa2PersistenceUnitInfoDecorator.invoke(DefaultPersistenceUnitManager.java:617)
... 70 more
Caused by: java.lang.IllegalStateException: Cannot apply class transformer without LoadTimeWeaver specified
at org.springframework.orm.jpa.persistenceunit.SpringPersistenceUnitInfo.addTransformer(SpringPersistenceUnitInfo.java:109)
... 75 more
PersistenceContext.java
package com.marc.embeddedglassfish.config;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.support.AbstractPlatformTransactionManager;
import com.marc.springmvc3.dao.PersonDAO;
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = {"com.marc.springmvc3.repositories"})
public class PersistenceContext {
/* glassfish requires "java:app/"
Deployment Descriptor. An application-scoped resource is defined in the glassfish-resources.xml deployment descriptor file.
This file is placed in the META-INF directory of the module or application archive. For web applications or modules,
this file is placed in the WEB-INF directory. If any submodule archives of an enterprise application archive have their
own glassfish-resources.xml files, the resource definitions are scoped to those modules only. For more information about
the glassfish-resources.xml file, see Appendix B, GlassFish Server Deployment Descriptor Files and Appendix C, Elements of the
GlassFish Server Deployment Descriptors.
Naming. Application-scoped resource JNDI names begin with java:app or java:module. If one of these prefixes is not specified
in the JNDI name, it is added. For example, application-scoped databases have JNDI names in the following format:
java:app/jdbc/DataSourceName or java:module/jdbc/DataSourceName. This is in accordance with the naming scopes introduced
in the Java EE 6 Specification.
http://docs.oracle.com/cd/E18930_01/html/821-2417/giydj.html
oracle glassfish application deployment guide
*/
#Bean
public DataSource dataSource() {
final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
dsLookup.setResourceRef(true);
DataSource dataSource = dsLookup.getDataSource("java:app/jdbc/TestDB");
return dataSource;
}
#Bean
public PersonDAO personDao() {
PersonDAO personDao = new PersonDAO();
personDao.setDataSource(dataSource());
return personDao;
}
#Bean
public AbstractPlatformTransactionManager transactionManager() {
return new JpaTransactionManager(entityManagerFactory());
}
#Bean
public DataSource dataSourceForEntityManager() {
final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
dsLookup.setResourceRef(true);
// "jdbc/__TimerPool" is defined by default in embedded glassfish
DataSource dataSource = dsLookup.getDataSource("jdbc/__TimerPool");
return dataSource;
}
#Bean
public EntityManagerFactory entityManagerFactory() {
final LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
EclipseLinkJpaVendorAdapter vendor = new EclipseLinkJpaVendorAdapter();
vendor.setDatabase(Database.DERBY);
vendor.setGenerateDdl(true);
vendor.setShowSql(true);
entityManagerFactoryBean.setJpaVendorAdapter(vendor);
entityManagerFactoryBean.setJtaDataSource(dataSourceForEntityManager());
entityManagerFactoryBean.setPackagesToScan(new String[] { "com.marc.springmvc3.model" });
final Properties props = new Properties();
props.setProperty("javax.persistence.jdbc.driver", "org.apache.derby.jdbc.EmbeddedDriver");
props.setProperty("eclipselink.target-database", "DERBY");
props.setProperty("eclipselink.ddl-generation", "drop-and-create-table");
props.setProperty("eclipselink.logging.level.sql", "FINEST");
props.setProperty("eclipselink.logging.parameters", "true");
entityManagerFactoryBean.setJpaProperties(props);
entityManagerFactoryBean.afterPropertiesSet();
return entityManagerFactoryBean.getObject();
}
}
PersonService.java
package com.marc.springmvc3.service;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import com.marc.springmvc3.model.Person;
import com.marc.springmvc3.repositories.PersonRepository;
#Service
public class PersonService {
#Inject
private PersonRepository repository;
#Inject
private List<Person> persons;
public List<Person> getAllPersons() {
Person person = new Person();
person.setFirstName("Lucky");
person.setName("Luke");
repository.save(person);
person.setFirstName("");
person.setName("");
Person dbPerson = repository.findOne(person.getId());
persons.add(dbPerson);
return persons;
}
}
PersonRepository.java
package com.marc.springmvc3.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import com.marc.springmvc3.model.Person;
public interface PersonRepository extends JpaRepository<Person, Integer> {
}
Initiliazer
package com.marc.embeddedglassfish.initializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class EmbeddedGlassfishInitializer implements WebApplicationInitializer {
private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
private static final String DISPATCHER_SERVLET_MAPPING = "/";
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.marc.embeddedglassfish.config");
return context;
}
}
I solved it
The interesting part of the stack trace is at the end:
Caused by: java.lang.IllegalStateException: Cannot apply class transformer without LoadTimeWeaver specified
The explaination here helped me : EclipseLinkJpaVendorAdapter instead of HibernateJpaVendorAdapter issue
I still don't know how to get an EntitManagerFactory from glassfish as JNDI in the Java based application context configuration. Any idea ?
It should be:
#Bean
public FactoryBean<EntityManagerFactory> entityManagerFactory() {
...
entityManagerFactoryBean.setJpaProperties(props);
return entityManagerFactoryBean;
}
#Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
It's not recommended to instantiate any FactoryBean directly from code: there is need just rely on Spring contaier.
To use a FactoryBean result it is nessary to follow with parameter injection strategy.

How to Spring 3.2 + hibernate 4 on javaconfig correctly

I want to make test in Spring 3.2 + Hibernate 4 + javaconfig
Content of build.gradle is the next:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.gradle.api.plugins:gradle-tomcat-plugin:0.9.9'
}
}
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'war'
apply plugin: 'tomcat'
ext.springVersion = '3.2.4.RELEASE'
ext.springMobileVersion = '1.1.0.RELEASE'
ext.thymeleafVersion = '2.0.19'
ext.aspectJVersion = '1.6.9'
ext.cglibVersion = '2.2'
ext.slf4jVersion = '1.6.1'
ext.servletJstlVersion = '1.2'
ext.servletApiVersion = '3.0.1'
ext.servletJspVersion = '2.1'
ext.junitVersion = '4.11'
ext.tomcatVersion = '7.0.42'
ext.pgsqlVersion = '9.1-901.jdbc4'
ext.mockiteoCoreVersion = '1.9.5'
ext.mailVersion = '1.4.7'
ext.dataBindVersion = '2.2.3'
ext.hbVersion = '4.2.7.Final'
ext.guavaVersion = '15.0'
ext.javassistVersion = '3.18.0-GA'
war {
webInf {
include "src/main/webapp/resources/**"
}
}
dependencies {
compile("org.springframework:spring-context:$springVersion") {
exclude module: 'commons-logging'
}
compile "org.springframework:spring-context-support:$springVersion"
compile "org.springframework:spring-web:$springVersion"
compile "org.springframework:spring-webmvc:$springVersion"
compile "org.springframework.mobile:spring-mobile-device:$springMobileVersion"
compile "org.springframework:spring-tx:$springVersion"
compile "org.springframework:spring-orm:$springVersion"
compile "com.fasterxml.jackson.core:jackson-databind:$dataBindVersion"
compile "javax.mail:mail:$mailVersion"
compile "org.thymeleaf:thymeleaf-spring3:$thymeleafVersion"
compile "org.aspectj:aspectjrt:$aspectJVersion"
compile "cglib:cglib-nodep:$cglibVersion"
compile "javax.inject:javax.inject:1"
compile "org.slf4j:slf4j-api:$slf4jVersion"
compile "org.slf4j:jcl-over-slf4j:$slf4jVersion"
compile "org.slf4j:slf4j-log4j12:$slf4jVersion"
compile "javax.servlet:jstl:$servletJstlVersion"
providedCompile("javax.servlet:javax.servlet-api:$servletApiVersion")
providedCompile("javax.servlet.jsp:jsp-api:$servletJspVersion")
// Persistence
compile "postgresql:postgresql:$pgsqlVersion"
compile "org.hibernate:hibernate-core:$hbVersion"
compile "org.hibernate:hibernate-entitymanager:$hbVersion"
compile "org.apache.tomcat:tomcat-dbcp:$tomcatVersion"
compile "org.javassist:javassist:$javassistVersion"
// Tools
compile "com.google.guava:guava:$guavaVersion"
// TEST
testCompile "junit:junit:$junitVersion"
testCompile "org.mockito:mockito-core:$mockiteoCoreVersion"
testCompile "org.springframework:spring-test:$springVersion"
testCompile "org.hamcrest:hamcrest-core:1.3"
testCompile "org.hamcrest:hamcrest-library:1.3"
testCompile "org.apache.commons:commons-lang3:3.1"
// TOMCAT
tomcat("org.apache.tomcat.embed:tomcat-embed-core:$tomcatVersion",
"org.apache.tomcat.embed:tomcat-embed-logging-juli:$tomcatVersion")
tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:$tomcatVersion") {
exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj'
}
}
repositories {
mavenCentral()
maven { url 'http://repo.spring.io/libs-release' }
}
task wrapper(type: Wrapper) {
gradleVersion = '1.8'
}
PersistenceConfig content is the next:
#Configuration
#EnableTransactionManagement
#PropertySource({ "classpath:pgsql.properties" })
#ComponentScan(basePackages = {"com.example.persistence"})
public class PersistenceConfig
{
#Autowired
private Environment env;
#Bean
public DataSource dataSource()
{
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.user"));
dataSource.setPassword(env.getProperty("jdbc.pass"));
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory()
{
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "com.example.persistence.domain" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public HibernateTransactionManager transactionManager()
{
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory().getObject());
return txManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation()
{
return new PersistenceExceptionTranslationPostProcessor();
}
Properties hibernateProperties() {
return new Properties() {
{
setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
setProperty("hibernate.globally_quoted_identifiers", "true");
}
};
}
}
ProductServiceTest content is the next:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {PersistenceConfig.class})
public class ProductServiceTest
{
private static final Logger LOG = LoggerFactory.getLogger(ProductServiceTest.class);
#Autowired
private ProductService productService;
#Autowired
private ApplicationContext applicationContext;
#Test
public final void listApplicationBeans() throws Exception
{
List<String> beans = Arrays.asList(applicationContext.getBeanDefinitionNames());
for (String bean: beans)
{
LOG.info(String.format("--> App Beans [%s]", bean));
}
}
}
persistence.properties content is the next:
# jdbc
jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://some_address:5432/some_database
jdbc.user=someuser
jdbc.pass=somepassword
# hibernate
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=create-drop
Product content is the next:
#Entity
public class Product implements Serializable
{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name) {
this.name = name;
}
public Product(String name)
{
setName(name);
}
#Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append(Product.class.getSimpleName()).append(" [\n");
builder.append("id = ").append(id).append("\n");
builder.append("name = ").append(name).append("\n");
builder.append("]");
return builder.toString();
}
}
ProductDao content is the next:
import org.springframework.stereotype.Repository;
import com.example.persistence.dao.common.AbstractDao;
import com.example.persistence.domain.Product;
#Repository
public class ProductDao extends AbstractDao<Product>
{
public ProductDao()
{
super();
setClazz(Product.class);
}
}
ProductService content is the next:
#Service
public class ProductService extends AbstractService<Product>
{
#Autowired
private ProductDao dao;
public ProductService()
{
super();
}
#Override
protected IOperation<Product> getDao()
{
return dao;
}
}
Result of gradle clean test:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:122)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:105)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:74)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:312)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:80)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:47)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:103)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:355)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:66)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'productService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.persistence.dao.impl.ProductDao com.example.persistence.service.impl.ProductService.dao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.persistence.dao.impl.ProductDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:120)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:248)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
... 44 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.example.persistence.dao.impl.ProductDao com.example.persistence.service.impl.ProductService.dao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.persistence.dao.impl.ProductDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
... 60 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.persistence.dao.impl.ProductDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:988)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
... 62 more
According to the stacktrace:
Could not autowire field: private com.example.persistence.dao.impl.ProductDao
com.example.persistence.service.impl.ProductService.dao; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException:
When I found such issue I eliminate the following:
The bean is not annotated or not covered by component scan.
You defined
#ComponentScan(basePackages = {"com.example.persistence"})
It covers your package com.example.persistence.dao.impl.ProductDao
Look’s fine here.
Make sure annotations are correct: ProductDao is annotated #Repository
Looks ok.
Make sure that com.example.persistence.dao.impl.ProductDao is in the classpath.
You are executing the command gradle clean test, which means your code will be compiled before test execution (as test depend on the compile task).
If it compiles I guess that ProductDao is in your classpath
Make sure that the JUnit has the required configuration for bootstrapping
spring application context.
#ContextConfiguration
class points to your configurations class.
loader attribute was not defined so spring will use the default DelegatingSmartContextLoader (no #WebAppConfiguration in your configuration and version >3.2).
Looks good to me.
Unfortunately I cannot find any issue and everything looks fine (I hope this check list will help someone).
So I would guess that the issue is somewhere in the missing details; like you have to class of ProductDao under different packages and you are using the wrong one in the ProductService or the wrong interface etc.
Hope this helps
I share with you an example of my Hibernate java configuration.
I hope you love it:
Pre-requirement: pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.0.6.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.1.9.Final</version>
</dependency>
<!-- POSTGRESQL -->
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901-1.jdbc4</version>
</dependency>
</dependencies>
Step 1: application.properties
################### DataSource Configuration ##########################
jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost/curso_db
jdbc.username=alumno
jdbc.password=alumno
#################### Hibernate Configuration ##########################
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql=true
packagesToScan=com.curso.online.model
Step 2: Config.java
package com.curso.online;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
#PropertySources(value = { #PropertySource("classpath:/application.properties") })
#ComponentScan(basePackages = "com.curso.online")
public class Config {
#Value("${jdbc.driverClassName}")
private String KEY_DRIVER_CLASS;
#Value("${jdbc.url}")
private String KEY_JDBC_URL;
#Value("${jdbc.username}")
private String KEY_JDBC_USERNAME;
#Value("${jdbc.password}")
private String KEY_JDBC_PASSWORD;
#Value("${hibernate.dialect}")
private String KEY_HIBERNATE_DIALECT;
#Value("${hibernate.show_sql}")
private String KEY_HBERNATE_SHOW_SQL;
#Value("${packagesToScan}")
private String KEY_ENTITIES_PKG;
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
factory.setDataSource(dataSource());
factory.setPackagesToScan(KEY_ENTITIES_PKG);
factory.setHibernateProperties(hibernateProperties());
return factory;
}
public Properties hibernateProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", KEY_HIBERNATE_DIALECT);
properties.setProperty("hibernate.show_sql", KEY_HBERNATE_SHOW_SQL);
return properties;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(
SessionFactory sessionFactory) {
return new HibernateTransactionManager(sessionFactory);
}
#Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(KEY_DRIVER_CLASS);
dataSource.setUrl(KEY_JDBC_URL);
dataSource.setUsername(KEY_JDBC_USERNAME);
dataSource.setPassword(KEY_JDBC_PASSWORD);
return dataSource;
}
}
I came across a similar problem with my Spring Hibernate project in my test suites.
The only way I could solve the problem was to autowire the class by using its super class as its type (AbstractService in your case) and then use a #Qualifier to tell Spring which child class I am referring to. It will look something like this in your case:
#Qualifier("ProductService")
#Autowired
private AbstractService productService;
It is painful as then in the test function you have to cast productService object to ProductService every time you use a method that belongs to the child class. So if you have already solved this using another solution please share it with us.

Resources