<dependency>
<groupId>org.apache.tomee.bom</groupId>
<artifactId>tomee-plus-api</artifactId>
<version>11.0.0-M2-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- here what is needed to use client lookup with jms resources -->
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>openejb-client</artifactId>
<version>11.0.0-M2-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>openejb-ejbd</artifactId>
<version>11.0.0-M2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
<version>6.2.6</version>
<scope>runtime</scope>
</dependency>
Client Resource Lookup (Preview)
This example shows how a standalone client using the remote OpenEJB client
(org.apache.openejb.client.RemoteInitialContextFactory) can look up JMS
resources, here an ActiveMQ ConnectionFactory and Queue, through JNDI.
The resources are not fetched from a server: the client builds them from
system properties. In effect you declare a small JNDI tree on the client side.
The example is only a test, SenderTest. There is no application code.
Dependencies
The client needs the OpenEJB client, which provides the InitialContext
factory, and the ActiveMQ classes it will instantiate:
Declaring the client resources
The resources are declared as system properties. The key is the JNDI name
used for the lookup. The value follows the pattern
<kind>:<implementation class>:<constructor argument>:
@BeforeClass
public static void configureClientResources() {
// can be set this way or with the key Resource/<type>
// in fact we create on client side a mini jndi tree
// the key is the jndi name (the one used for the lookup)
System.setProperty("aConnectionFactory", "connectionfactory:org.apache.activemq.ActiveMQConnectionFactory:tcp://localhost:11616");
System.setProperty("aQueue", "queue:org.apache.activemq.command.ActiveMQQueue:LISTENER");
}
When the client resolves a name, it first checks for a system property
with that name, after dropping a java: prefix and any comp/env/.
If one exists, the value is parsed and the object is created on the
client:
-
connectionfactory:,queue:andtopic:load the given class through the thread context class loader and call itsStringconstructor with the rest of the value. Sonew ActiveMQConnectionFactory("tcp://localhost:11616")andnew ActiveMQQueue("LISTENER")are created here. -
The client also knows
datasource:,javamail:andlink:(the last one points to another system property).
As the comment in the test says, you can also key the value by resource
type as Resource/<type>. The client uses that property when the server
answers a lookup with a resource of that type.
Creating the ActiveMQConnectionFactory does not open a connection, so
nothing has to listen on tcp://localhost:11616 for this test.
The test
SenderTest creates an InitialContext with the remote client factory and
looks up both resources with the java: prefix:
@Test
public void send() throws Exception {
final Properties properties = new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
final Context context = new InitialContext(properties);
final Queue destination = (Queue) context.lookup("java:aQueue");
assertNotNull(destination);
assertEquals("LISTENER", destination.getQueueName());
final ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("java:aConnectionFactory");
assertNotNull(connectionFactory);
}
It checks that the queue is found and is named LISTENER, and that the
connection factory is found. Both are answered from the system properties,
so no TomEE server has to be running.
Running
mvn clean test