I'm trying to set up a STOMP acceptor in my Wildfly 11 based Swarm deployment (using Swarm 2017.12.1 to generate a fat WAR, running via java -jar...), for letting clients send me progress messages, but could not get the acceptor to load, always get this error at server startup:
AMQ222203: Classpath lacks a protocol-manager for protocol STOMP, Protocol being ignored on acceptor TransportConfiguration(name=stomp-acceptor, factory=org-apache-activemq-artemis-core-remoting-impl-netty-NettyAcceptorFactory) ?port=61613&protocols=STOMP
I am using an existing (but adapted) standalone-full.xml configuration to make the switch easier, and everything works fine so far (Java EE wise), but not the STOMP part (JMS works, though).
I've included some dependencies in the WAR's POM to fix previous class loading errors, but now I run out of ideas:
<dependency>
<groupid>org.apache.activemq</groupid>
<artifactid>activemq-rar</artifactid>
<version>5.15.2</version>
<type>rar</type>
</dependency>
<dependency>
<groupid>org.apache.activemq</groupid>
<artifactid>activemq-stomp</artifactid>
<version>5.15.2</version>
</dependency>
<dependency>
<groupid>io.netty</groupid>
<artifactid>netty-all</artifactid>
<version>4.1.5.Final</version>
</dependency>
(so I'm relying on Swarm to figure out needed fragments, which works for the rest)
My configuration for the messaging part looks like this:
<acceptor name="stomp-acceptor" factory-class="org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptorFactory">
<param name="protocols" value="STOMP"/>
<!--param name="connection-ttl" value="30000"/-->
<param name="host" value="${jboss.bind.address:127.0.0.1}"/>
<param name="port" value="61613"/>
<!--param name="stomp-enable-message-id" value="true"/-->
</acceptor>
I've searched Swarm, Artemis and also SO but didn't find a working solution.
Could it be that Wildfly 11 will not work since it's using Artemis 1.5 and Swarm does not yet fully support it?
some resources I found useful so far:
Wildfly-Swarm and connection to external activemq via resource adapter: WFLYCTL0412
Wildfly 11 connection to remote Artemis ActiveMQ server configuration
https://blog.dekstroza.io/wildfly-swarm-to-remote-wildfly-swarm-activemq-broker/
Receiving MQTT message with Wildlfy 11 embedded Apache Artemis
http://docs.wildfly-swarm.io/2017.12.1/#_messaging
http://docs.wildfly-swarm.io/2017.12.1/#_sockets
A friendly and helpful chat on #wildfly-swarm brought an explanation and possible solution, but we'll have to wait for the bugfix, see https://issues.jboss.org/browse/SWARM-1763
Ken Finnigan found out the root cause in an error in the modules configuration for messaging in Wildfly:
The issue is a result of the org.apache.activemq.artemis module.xml defining protocol modules for STOMP, AMQP and HornetQ as optional, so WF Swarm does not pick them up.
Related
I'm currently developing a Spring Boot application that uses ActiveMQ "Classic" to communicate with MQTT enabled devices. The main problem is that I need to have in-memory ActiveMQ because when the Spring Boot application doesn't, all the messages sent to the topics can't be read because the #JmsListener for the topics only work in runtime(because the same is subscriber of the topic in that moment). I could use a docker-compose to create a stack and lock everything when ActiveMQ container is down but I can't use it into the project that I'm actually doing.
So, is there a way to expose the ports of in-memory ActiveMQ or a way to start an ActiveMQ deamon when the Spring Boot project start and stop it when Spring Boot stops?
Here is the application.properties file
# Embedded ActiveMQ Configuration Example
spring.activemq.broker-url=vm://embedded?broker.persistent=false,useShutdownHook=false
spring.activemq.close-timeout=15000
spring.activemq.in-memory=true
spring.activemq.non-blocking-redelivery=false
spring.activemq.password=admin
spring.activemq.user=admin
spring.activemq.send-timeout=0
spring.activemq.packages.trust-all=false
spring.activemq.packages.trusted=com.memorynotfound
spring.activemq.pool.block-if-full=true
spring.activemq.pool.block-if-full-timeout=-1
spring.activemq.pool.create-connection-on-startup=true
spring.activemq.pool.enabled=false
spring.activemq.pool.expiry-timeout=0
spring.activemq.pool.idle-timeout=30000
spring.activemq.pool.max-connections=1
spring.activemq.pool.max-sessions-per-connection=500
spring.activemq.pool.reconnect-on-exception=true
spring.activemq.pool.time-between-expiration-check=-1
spring.activemq.pool.use-anonymous-producers=true
Yes, there are a couple ways to fire up the broker in memory. I've found it helps to understand that ActiveMQ is essentially just a library, so you've got lots of options in how to bootstrap.
ActiveMQ is generally wired together with Spring, so you can generally add it to a spring beans file and get all the config you want (transport connectors, etc)
Sample loading activemq.xml file from classpath (ie. src/main/resources or src/test/reosurces if in a unit test)
import org.apache.activemq.broker.BrokerFactory;
import org.apache.activemq.broker.BrokerService;
...
BrokerService broker = BrokerFactory.createBroker(new URI(xbean:activemq.xml));
Maven
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-spring</artifactId>
</dependency>
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
</dependency>
Alternate Java code1:
EmbeddedActiveMQBroker customizedBroker = new EmbeddedActiveMQBroker("bean:customize-activemq.xml");
ActiveMQ testing
Add'l example:
Embedded ActiveMQ unit test
My Java project runs with Wildfly Swarm. I have to update the project-defaults.yml to use the jmsra library (JMS MQ), but I was not able to find out how to add the jmsra configuration for the project-defaults.yml.
I have seen many posts that deals with ActiveMQ, but I cannot use it.
Do you have any tips or examples to configure Wildfly Swarm with jmsra.rar?
I'm using the version 3.8.1 of Vertx with Java 11.05 and I configured the verticles to use Hazelcast.
Everything works fine and the application runs without any issues. However, I begin to receive the error a thread has been blocked on Hazelcast.
I'm checking the error logs for the verticles and there are not blocked threads in the code or any other issues.
The issue only happens when the application is under load test. Also, the issue not seems to affect the services.
The services are responding without any problems.
Does anyone have the same issue before?
Thanks to tsegismont.
I find a solution to this issue. The original conversation is on google forums. But the answer is to upgrade the version of Hazelcast.
The version that solves the issue is 3.11.
I used this POM call for fix the Hazelcast library.
<!-- specify Hazelcast version default 3.10.5 -->
<!-- https://mvnrepository.com/artifact/com.hazelcast/hazelcast -->
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>3.11.7</version>
</dependency>
If you keep having issues, the problem could be in Hazelcast as something referred to brain split syndrome on the cluster.
https://community.pega.com/knowledgebase/articles/system-administration/split-brain-syndrome-and-cluster-fracturing-faqs
Also, Hazelcast has some specific configuration for the cluster that can help to solve the issue.
Kind regards,
Juan
Recently I tried to deploy a Jersey2 application to Glassfish4.1. I had lots of dependency issues and found a lot of ClassCastException.
Later I found the user guide here: https://jersey.java.net/documentation/latest/modules-and-dependencies.html#servlet-app-glassfish
I have to configure pom.xml like:
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.23.1</version>
<scope>provided</scope>
</dependency>
If you are using Glassfish application server, you don't need to package anything with your application, everything is already included. You just need to declare (provided) dependency on JAX-RS API to be able to compile your application.
My question is that why Glassfish have to provide jersey2 (JSR implementation) itself for application. Why not just let application to choose the JSR implementation it is using?
I also add glassfish-web.xml under WEB-INF:
<glassfish-web-app>
<class-loader delegate="false" />
</glassfish-web-app>
According to the document here (https://docs.oracle.com/cd/E19798-01/821-1752/beagb/index.html):
It will let Glassfish to load classes under WEB-INF/lib/ first. But why does Glassfish still use its own jersey version and javax version?
For javax, I guess Glassfish is a java application version and it only support specific JSR implementations. So when I choose JSR implementation in my application, and I have to find out the correct version of Glassfish.
But why is jersey2 so special that glassfish have to provide it. What if I want to use another version of jersey2?
Updated:
I ran some more tests.
When I deployed a jersey1 application (jersey1 is included in war file) to glassfish4 and asked glassfish4 to delegate class loader process to its parent, and this application works, and application can handle incoming rest requests. Why? I guess since glassfish does not have jersey1 included, it will load jersey1 from libraries inside war file, and glassfish4 is actually working with jersey1. Does this mean I can override glassfish default behavior to let application to choose the JAX-RS implementation.
And if I replaced jersey1 with jersey2 and still let glassfish4 to load libraries from war first, there was an exception thrown:
WebModule[/invoiceLoader]StandardWrapper.Throwable
java.lang.ClassCastException: Cannot cast org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider to org.glassfish.jersey.server.spi.ComponentProvider
at java.lang.Class.cast(Class.java:3369)
at org.glassfish.jersey.internal.ServiceFinder$LazyObjectIterator.hasNext(ServiceFinder.java:713)
at org.glassfish.jersey.server.ApplicationHandler.getRankedComponentProviders(ApplicationHandler.java:743)
at org.glassfish.jersey.server.ApplicationHandler.access$600(ApplicationHandler.java:184)
at org.glassfish.jersey.server.ApplicationHandler$4.get(ApplicationHandler.java:406)
at org.glassfish.jersey.server.ApplicationHandler$4.get(ApplicationHandler.java:399)
at org.glassfish.jersey.internal.util.collection.Values$LazyValueImpl.get(Values.java:340)
at org.glassfish.jersey.server.ApplicationHandler.createApplication(ApplicationHandler.java:366)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:342)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:392)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:177)
How did this exception happen?
My question is that why Glassfish have to provide jersey2 (JSR implementation) itself for application. Why not just let application to choose the JSR implementation it is using?
Because Glassfish is a Java EE compliant server, and JAX-RS is part of the EE spec. So it needs an implementation of JAX-RS to run a JAX-RS application. It just happens to use Jersey as the implementation , just like JBoss uses RESTEasy. If the server didn't have an implementation, then it wouldn't be EE compliant. An application should be able to run a complete EE application only compiling the application against the single EE jar. It shouldn't have to know anything about implementations.
What if I want to use another version of jersey2?
You can just try to replace all the Jersey implementation jars with new ones. See Updating Jersey 2 in GlassFish 4.
I am using richfaces a4j:push in my Spring-JSF integrated application. I am able to push messages to the browser using websocket in my non cluster environment on wildfly 8.0.0.
When I deploy the application on wildfly8.0.0 on redhat enterprise 7.0 with httpd clustering the push messages are not working.
I get the following error on cluster environment:
17:15:22,862 ERROR [io.undertow.request] (default task-3) UT005023: Exception handling request to /star/__richfaces_push: java.lang.IllegalStateException: UT000077: The underlying transport does not support HTTP upgrade.
My cluster is configured with mod_cluster, referring the document
When I look for details on error UT000077, it says ‘Apache httpd doesn't support HTTP upgrade out of box’ I understand HTTP upgrade is required for websocket communication. It is suggested to use mod_proxy_wstunnel. However the details are not available for this configuration.
Any pointers/suggestions are much appreciated.
At the time of this answer AJP [which is the default one] does not support HTTP upgrade and hence not websocket.
If you switch to HTTP websocket will work.
Following changes you need to do to switch to AJP
Change
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
#LoadModule proxy_http_module modules/mod_proxy_http.so
To
#LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
[comment out proxy_ajp_module and added proxy_http_module]
In modcluster sub-system
Change
<subsystem xmlns="urn:jboss:domain:modcluster:1.2">
<mod-cluster-config advertise-socket="modcluster" connector="ajp">
<dynamic-load-provider>
<load-metric type="cpu"/>
</dynamic-load-provider>
</mod-cluster-config>
</subsystem>
To
<subsystem xmlns="urn:jboss:domain:modcluster:1.2">
<mod-cluster-config advertise-socket="modcluster" connector="default">
<dynamic-load-provider>
<load-metric type="cpu"/>
</dynamic-load-provider>
</mod-cluster-config>
</subsystem>
[“default” is the name of the http listener]
Also you need to load mod_proxy_wstunnel in your httpd
MODCLUSTER-438 WebSocket support for mod_cluster
Let me give my two cents in this question to people there are using Apache 2.2.x If are you using Apache 2.2.x you need to compile the mod_proxy_wstunnel from Apache 2.4 for Apache 2.2.x This link have a how to do it. Following, to achieve WebSockets with mod_cluster you need also compile mod_cluster 1.3.3+ as described in this link and add EnableWsTunnel in your mod_cluster.conf outside your virtual host
I hope helps.