i want to create a very simple JMS standalone client to a JMS Topic hosted on my Glassfish server.
My project is built using maven.
I know there seems to be some kind of mess concerning JMS dependencies to use, so, which dependencies shouls I use in my pom to
- Connect to my JNDI context
- Be able to read my JMS topic ?
My Java test method is
/** Thanks to WELD CDI, this method is not static */
public void main(@Observes ContainerInitialized event) throws Throwable {
Context context = new InitialContext();
ConnectionFactory factory = (ConnectionFactory) context.lookup(JMSNotifierConstants.CONNECTION_FACTORY_NAME);
Connection connection = factory.createConnection();
Topic topic = (Topic) context.lookup(JMSNotifierConstants.NOTIFICATION_TOPIC);
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
MessageConsumer consumer = session.createConsumer(topic);
connection.start();
while (true) {
Message received = consumer.receive();
System.out.println(received);
}
}
And my pom contains, for now, the following dependencies
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.0-SP1</version>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-se</artifactId>
<version>1.0.1-Final</version>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-logger</artifactId>
<version>1.0.0-CR2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.jms</artifactId>
<version>3.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.glassfish.extras</groupId>
<artifactId>appserv-rt</artifactId>
<version>3.1</version>
</dependency>
OK, this one was rather tricky.
After some searches and tries, I removed weld dependencies (in order to go back to a more classical main).
Then, I replaced my (old-style) appserv-rt.jar
dependency with
<dependency>
<groupId>org.glassfish.appclient</groupId>
<artifactId>gf-client</artifactId>
<version>3.1</version>
<type>pom</type>
<scope>compile</scope>
</dependency>
This is not a little change, as gf-client
pulls all jars for Glassfish, which obviously makes a lot of jars (hopefully there is a method to optimize jar number, although we all know about premature optimization).
So, once it's done, it's perfectly possible to use EJB remote interface, but not JMS (due to incomprehensible reasons). In order to make JMS work with gf-client, one then have to go create maven dependencies for imqjmsra.jar
and imqbroker.jar
, both located in %GLASSFISH3_INSTALL_DIR%/glassfish/lib/install/applications/jmsra
. Furthermore, as imqjmsra.jar
internally uses imqbroker.jar
, I recommend you to create the following poms :
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.glassfish.external.jms</groupId>
<artifactId>imqjmsra</artifactId>
<version>3.1.0</version>
<description>POM was created by Sonatype Nexus</description>
<dependencies>
<dependency>
<groupId>org.glassfish.external.jms</groupId>
<artifactId>imqbroker</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
</project>
associated to imqjmsra.jar
and
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.glassfish.external.jms</groupId>
<artifactId>imqbroker</artifactId>
<version>3.1.0</version>
<description>POM was created by Sonatype Nexus</description>
</project>
associated to imqbroker.jar
.
Obviously, as I use Nexus repository management, it was easier for me to create these dependencies in our company 3rd parties local repository using Nexus "upload artifact page".
Once it's done, My POM dependencies now are
<dependency>
<groupId>org.glassfish.appclient</groupId>
<artifactId>gf-client</artifactId>
<version>3.1</version>
<type>pom</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.glassfish.external.jms</groupId>
<artifactId>imqjmsra</artifactId>
<version>3.1.0</version>
</dependency>
And I can totally poll my JMS queue.
I'm converting from GF 2.1 to 3.1 and I haven't got to the client software yet (it is definitely on my list) but as far as I can tell you need most of the glassfish install with GF 3.1 to get the client to launch. (With GF 2.1 it was 15+ mb include files)
"gf-client.jar refers to many other .jars from the GlassFish installation directory so it is best to refer to it from within the installation directory itself rather than copying it(and all the other .jars) to another location" EJB FAQ
You can either use the auto-generated webstart launch with Application Client Container, or you can package up your client and deploy it manually. Glassfish 3.0 manual, ACC
Well for me what worked was adding gf-client.jar from the glassfish installation folder, but adding gf-client from the maven repositories did not work.
When using maven dependencies, I found that this worked:
https://stackoverflow.com/a/10123034/516188
<dependency>
<groupId>org.glassfish.main.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.1.2</version>
</dependency>
It makes for a 62Mb final JAR file, but it works. Next thing I hit this problem though, used System.exit(0) for that one:
Sending message with JMS hangs on exit
You can get imqbroker by adding this:
<dependency>
<groupId>com.sun.messaging.mq</groupId>
<artifactId>imqbroker</artifactId>
<version>4.5.1-b03</version>
</dependency>