Spring Integration - FolderClosedException - spring

I am trying to filter incoming mail messages - if the mail body contains, for example, 'github.com', the application will not reply automatically. So I tried writing an IntegrationFlow for that (please see code below). I am not sure how to handle it since it seems like the Transformer cannot open the inbox folder, which seems to be Java Mail API issue?
#Bean
open fun flow(): IntegrationFlow
{
return IntegrationFlows
.from("emailReceiveChannel")
.transform(transformer())
.filter("#messageFilter.containsDomainNames('payload')")
.handle(MessageHandler(MailServiceImpl(javaMailSender(), mailStore())))
.get()
}
where transfomer() is:
#Bean
#Transformer(inputChannel = "emailReceiveChannel", outputChannel = "outputChannel")
open fun transformer(): org.springframework.integration.transformer.Transformer
{
return MailToStringTransformer()
}
and the messageFilter:
#Component
class MessageFilter
{
#Filter
open fun containsDomainNames(messageBody: String): Boolean
{
return messageBody.contains("github.com") ||
messageBody.contains("trello.com") ||
messageBody.contains("bitbucket.com")
}
}
.
#Bean
#InboundChannelAdapter(autoStartup = "true", value = "emailReceiveChannel", poller = (arrayOf(Poller(fixedDelay = "10000", maxMessagesPerPoll = "10"))))
open fun mailReceivingMessageSource(mailReceiver: ImapMailReceiver): MailReceivingMessageSource
{
return MailReceivingMessageSource(mailReceiver)
}
#Bean
open fun pollingConsumer(): PollingConsumer
{
return PollingConsumer(emailReceiveChannel(), MessageHandler(MailServiceImpl(javaMailSender(), mailStore())))
}
#Bean
open fun outputChannel(): PollableChannel
{
return QueueChannel()
}
#Bean
open fun emailReceiveChannel(): PollableChannel
{
return QueueChannel(10)
}
Stacktrace:
2018-01-20 13:05:53.840 ERROR 8204 --- [ask-scheduler-6] o.s.integration.handler.LoggingHandler : org.springframework.integration.transformer.MessageTransformationException: failed to transform mail message; nested exception is javax.mail.FolderClosedException, failedMessage=GenericMessage [payload=org.springframework.integration.mail.AbstractMailReceiver$IntegrationMimeMessage#3f0ef4a2, headers={id=e9eff05d-e9af-70e4-73f7-c4d39c740291, timestamp=1516449953838}]
at org.springframework.integration.mail.transformer.AbstractMailMessageTransformer.transform(AbstractMailMessageTransformer.java:83)
at org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:89)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:131)
at org.springframework.integration.endpoint.PollingConsumer.handleMessage(PollingConsumer.java:129)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:271)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.lambda$run$0(AbstractPollingEndpoint.java:372)
at org.springframework.integration.util.ErrorHandlingTaskExecutor.lambda$execute$0(ErrorHandlingTaskExecutor.java:53)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:51)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:366)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:83)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.mail.FolderClosedException
at com.sun.mail.imap.IMAPMessage.getProtocol(IMAPMessage.java:153)
at com.sun.mail.imap.IMAPBodyPart.loadHeaders(IMAPBodyPart.java:390)
at com.sun.mail.imap.IMAPBodyPart.getNonMatchingHeaderLines(IMAPBodyPart.java:371)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1536)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:948)
at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:538)
at org.springframework.integration.mail.transformer.MailToStringTransformer.doTransform(MailToStringTransformer.java:62)
at org.springframework.integration.mail.transformer.AbstractMailMessageTransformer.transform(AbstractMailMessageTransformer.java:80)
... 19 more

I have the same problem in mail-attachments project of:
https://github.com/spring-projects/spring-integration
I resolved it with
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-bom</artifactId>
<version>4.3.19.RELEASE</version>
<scope>import</scope>
<type>pom</type>
</dependency>
instead of
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-bom</artifactId>
<version>5.1.3.RELEASE</version>
<scope>import</scope>
<type>pom</type>
</dependency>
EDIT: It's ok also with version 5.1.3.RELEASE but it's necessary:
simple-content="true" in mail:inbound-channel-adapter

This issue are corresponding with integration lib update, that is why downgrade of this lib is helpfull, but the right way is to add one more java mail property: simpleContent.
Please read docs: https://docs.spring.io/spring-integration/api/org/springframework/integration/mail/AbstractMailReceiver.html#setSimpleContent-boolean-
Also my code snippet:
#Bean
public IntegrationFlow userEmailFlow(EmailProperties props,
EmailToUserTransformer emailToUserTransformer,
UserMessageHandler userMessageHandler) {
return IntegrationFlows
.from(Mail.imapInboundAdapter(props.getImapUrl())
.javaMailProperties(p -> p.put("mail.debug", "false")
.put("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory")
.put("mail.imap.socketFactory.fallback", "false")
.put("mail.store.protocol", "imaps"))
.shouldMarkMessagesAsRead(false)
.shouldDeleteMessages(false)
.simpleContent(true),
e -> e.poller(Pollers.fixedDelay(props.getPollRate())))
.transform(emailToUserTransformer)
.handle(userMessageHandler)
.get();
}

Related

Use ElasticSearch client in non web application with Spring

I'm creating a non web application with Spring that will read data from Kafka and write it in ElasticSearch, i included the following dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
And the following configuration class:
#Configuration
public class ElasticSearchConfig extends AbstractElasticsearchConfiguration{
#Bean
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder().connectedTo("localhost:9200")
.build();
return RestClients.create(clientConfiguration).rest();
}
}
When i execute the following code:
#Override
public void run(String... args) throws Exception {
IndexRequest request = new IndexRequest("test-transactions");
request.id("2");
request.source("{\"name\":\"Sammie\"," + "\"lastname\":\"Goldner\"," + "\"username\":\"hugh.vonrueden\","
+ "\"amount\":9622235.2009}", XContentType.JSON);
client.index(request, RequestOptions.DEFAULT);
}
I get the following exception:
Caused by: java.lang.ClassNotFoundException: org.springframework.http.HttpHeaders
at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_251]
at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[na:1.8.0_251]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355) ~[na:1.8.0_251]
at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[na:1.8.0_251]
... 46 common frames omitted
If i include the following dependency the code works fine:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
But it brings a lot of other functionalities that i don't want in my code, is there any other way to configure spring-boot-starter-data-elasticsearch in a non web application?
Thanks.

Spring Boot test tries to initialize cache2k for the 2nd time and fails

After adding cache2k to my project some #SpringBootTest's stopped working with an error:
java.lang.IllegalStateException: Cache already created: 'cache'
Below I provide the minimal example to reproduce:
Go to start.spring.io and create a simplest Maven project with Cache starter, then add cache2k dependencies:
<properties>
<java.version>1.8</java.version>
<cache2k-version>1.2.2.Final</cache2k-version>
</properties>
<dependencies>
<dependency>
<groupId>org.cache2k</groupId>
<artifactId>cache2k-api</artifactId>
<version>${cache2k-version}</version>
</dependency>
<dependency>
<groupId>org.cache2k</groupId>
<artifactId>cache2k-core</artifactId>
<version>${cache2k-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.cache2k</groupId>
<artifactId>cache2k-spring</artifactId>
<version>${cache2k-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Now configure the simplest cache:
#SpringBootApplication
#EnableCaching
public class CachingDemoApplication {
public static void main(String[] args) {
SpringApplication.run(CachingDemoApplication.class, args);
}
#Bean
public CacheManager springCacheManager() {
SpringCache2kCacheManager cacheManager = new SpringCache2kCacheManager();
cacheManager.addCaches(b -> b.name("cache"));
return cacheManager;
}
}
And add any service (which we will #MockBean in one of our tests:
#Service
public class SomeService {
public String getString() {
System.out.println("Executing service method");
return "foo";
}
}
Now two #SpringBootTest tests are required to reproduce the issue:
#SpringBootTest
#RunWith(SpringRunner.class)
public class SpringBootAppTest {
#Test
public void getString() {
System.out.println("Empty test");
}
}
#RunWith(SpringRunner.class)
#SpringBootTest
public class WithMockedBeanTest {
#MockBean
SomeService service;
#Test
public void contextLoads() {
}
}
Notice that the 2nd test has mocked #MockBean. This causes an error (stacktrace below).
Caused by: java.lang.IllegalStateException: Cache already created: 'cache'
at org.cache2k.core.CacheManagerImpl.newCache(CacheManagerImpl.java:174)
at org.cache2k.core.InternalCache2kBuilder.buildAsIs(InternalCache2kBuilder.java:239)
at org.cache2k.core.InternalCache2kBuilder.build(InternalCache2kBuilder.java:182)
at org.cache2k.core.Cache2kCoreProviderImpl.createCache(Cache2kCoreProviderImpl.java:215)
at org.cache2k.Cache2kBuilder.build(Cache2kBuilder.java:837)
at org.cache2k.extra.spring.SpringCache2kCacheManager.buildAndWrap(SpringCache2kCacheManager.java:205)
at org.cache2k.extra.spring.SpringCache2kCacheManager.lambda$addCache$2(SpringCache2kCacheManager.java:143)
at java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1853)
at org.cache2k.extra.spring.SpringCache2kCacheManager.addCache(SpringCache2kCacheManager.java:141)
at org.cache2k.extra.spring.SpringCache2kCacheManager.addCaches(SpringCache2kCacheManager.java:132)
at com.example.cachingdemo.CachingDemoApplication.springCacheManager(CachingDemoApplication.java:23)
at com.example.cachingdemo.CachingDemoApplication$$EnhancerBySpringCGLIB$$2dce99ca.CGLIB$springCacheManager$0(<generated>)
at com.example.cachingdemo.CachingDemoApplication$$EnhancerBySpringCGLIB$$2dce99ca$$FastClassBySpringCGLIB$$bbd240c0.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363)
at com.example.cachingdemo.CachingDemoApplication$$EnhancerBySpringCGLIB$$2dce99ca.springCacheManager(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 52 more
If you remove #MockBean, both tests will pass.
How can I avoid this error in my test suite?
Your second test represents a different ApplicationContext altogether so the test framework will initiate a dedicated one for it. If cache2k is stateful (for instance sharing the CacheManager for a given classloader if it already exists), the second context will attempt to create a new CacheManager while the first one is still active.
You either need to flag one of the test as dirty (see #DirtiesContext) which will close the context and shut down the CacheManager, or you can replace the cache infrastructure by an option that does not require all that, see #AutoConfigureCache.
If cache2k works in such a way that it requires you to dirty the context, I'd highly recommend to swap it using the later options.
Since I do not want any custom behavior in test, but just want to get rid of this error, the solution is to create CacheManager using unique name like this:
#Bean
public CacheManager springCacheManager() {
SpringCache2kCacheManager cacheManager = new SpringCache2kCacheManager("spring-" + hashCode());
cacheManager.addCaches(b -> b.name("cache"));
return cacheManager;
}
I encountered the same error when using cache2k with Spring Dev Tools, and ended up with the following code as the solution:
#Bean
public CacheManager cacheManager() {
SpringCache2kCacheManager cacheManager = new SpringCache2kCacheManager();
// To avoid the "Caused by: java.lang.IllegalStateException: Cache already created:"
// error when Spring DevTools is enabled and code reloaded
if (cacheManager.getCacheNames().stream()
.filter(name -> name.equals("cache"))
.count() == 0) {
cacheManager.addCaches(
b -> b.name("cache")
);
}
return cacheManager;
}

Spring Integration JMS Inbound Gateway reply channel has no subscriber

I have test with JMS Inbound Gateway in Spring Integration 5.1.3
But I got error as following:
Caused by: org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:138) ~[spring-integration-core-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:105) ~[spring-integration-core-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73) ~[spring-integration-core-5.1.3.RELEASE.jar:5.1.3.RELEASE]
POM:
<dependencies>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jms</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
</dependencies>
I configure the Inbound Gateway as following:
#Bean
JmsInboundGateway jmsInboundGateway(
MessageChannel errorChannel,
ConnectionFactory connectionFactory,
DetailJmsProperties properties) {
final Listener listener = properties.getListener();
return Jms
.inboundGateway(connectionFactory)
.destination("request-queue")
.requestChannel("inputChannel")
.replyChannel("outputChannel")
.defaultReplyQueueName("response-queue")
.get();
}
And, the Service Activator:
#ServiceActivator(inputChannel = "inputChannel", outputChannel = "outputChannel")
public String process(String request) {
String response = null;
try {
LOGGER.info("Received message content: [{}]", request);
response = request + " was processed";
}
catch (Exception e) {
LOGGER.error("Error", e);
}
return response;
}
By the way, it works only if I remove outputChannel = "outputChannel" in Service Activator.
Is there any explanation for this issue, do I have any misunderstanding ?
You can't use DSL factories (Jms) like that, they are intended for use in a DSL flow
#Bean
IntegrationFLow flow()
return IntegrationFlows.from(jmsInboundGateway())
.handle("service", "process")
.get();
The DSL processing does all the wiring.
It works without the channel because a component without an output channel routes the reply to the replyChannel header.
If you don't want to use the DSL, you must wire up the inbound gateway directly as a bean instead of using the Jms factory.

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 Boot client to connect to existing JBoss EAP7 ActiveMQ

I've been searching the web but I cannot find an example on how to connect to ActiveMQ on JBoss (up and running) with a Spring-Boot client.
There'se a lot of tutorials from Spring but using an embedded Broker.
Any pointers would be great!
Thanks in advance,
ML
With the info provided, I've got this:
#Configuration
#SpringBootApplication
#EnableJms
public class Application {
#Bean
ActiveMQConnectionFactory activeMQConnectionFactory() {
final String host = "http://127.0.0.1:8080";
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(host);
factory.setUserName("user");
factory.setPassword("pwd");
factory.setTrustAllPackages(true);
return factory;
}
#Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
// This provides all boot's default to this factory, including the
// message converter
configurer.configure(factory, connectionFactory);
// You could still override some of Boot's default if necessary.
return factory;
}
#Bean // Serialize message content to json using TextMessage
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
public static void main(String[] args) {
// Launch the application
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
// Send a message with a POJO - the template reuse the message converter
System.out.println("Sending an email message.");
jmsTemplate.convertAndSend("TestQ", new Email("info#example.com", "Hello"));
}
}
my dependencies in pom.xml:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-optional</artifactId>
<version>5.7.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
But I've got this exception:
2017-06-01 17:55:54.176 INFO 2053 --- [ main] hello.Application : Started Application in 2.02 seconds (JVM running for 5.215)
Sending an email message.
[WARNING]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:527)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Could not create Transport. Reason: java.lang.IllegalArgumentException: Invalid connect parameters: {wireFormat.host=127.0.0.1}
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:316)
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:487)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:570)
at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:658)
at hello.Application.main(Application.java:69)
... 6 more
Caused by: javax.jms.JMSException: Could not create Transport. Reason: java.lang.IllegalArgumentException: Invalid connect parameters: {wireFormat.host=127.0.0.1}
at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:36)
at org.apache.activemq.ActiveMQConnectionFactory.createTransport(ActiveMQConnectionFactory.java:333)
at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:346)
at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:304)
at org.apache.activemq.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:244)
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:180)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:474)
... 9 more
Caused by: java.lang.IllegalArgumentException: Invalid connect parameters: {wireFormat.host=127.0.0.1}
at org.apache.activemq.transport.TransportFactory.doConnect(TransportFactory.java:126)
at org.apache.activemq.transport.TransportFactory.connect(TransportFactory.java:65)
at org.apache.activemq.ActiveMQConnectionFactory.createTransport(ActiveMQConnectionFactory.java:331)
... 14 more
I don't know what is this:
Caused by: java.lang.IllegalArgumentException: Invalid connect
parameters: {wireFormat.host=127.0.0.1}
thanks
For configuration, but change the broker url to your external ActiveMQ server: see http://activemq.apache.org/uri-protocols.html for different protocols (e.g. tcp). You may also need to include a user and password.
I started with this tutorial https://spring.io/guides/gs/messaging-jms/ and made my own edits to get it to work the way I wanted with ActiveMQ, you can also look here for other options: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-messaging.html. There are a few different ways to do this in Spring.
Also included the factory bean as well. From here, I use #JmsListener annotation to listen for messages and jmstemplate to post messages.
import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
#Configuration
#EnableJms
public class JMSConfiguration {
private static final Logger logger = LoggerFactory.getLogger(JMSConfiguration.class);
#Bean ActiveMQConnectionFactory activeMQConnectionFactory() {
ActiveMQConnectionFactory factory =
new ActiveMQConnectionFactory("tcp://somehost:61616");
factory.setTrustAllPackages(true);
return factory;
}
#Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
// This provides all boot's default to this factory, including the
// message converter
configurer.configure(factory, connectionFactory);
// You could still override some of Boot's default if necessary.
return factory;
}
}
Dependencies: spring-boot-starter-activemq
Spring version: 1.4.3.RELEASE

Resources