Overview
Here we are going to try and set things up so that the OpenJMS and code
running inside Dynamo can talk to each other.
As we begin to work with OpenJMS we'll refer to the OpenJMS User's Guide
which is posted here.
The Appendix on Integration with Jakarta Tomcat is very handy.
Creating a Module for Our Example
To facilitate our example I'll create a new
module for all of the configuration changes. The module name is OpenJMS
The MANIFEST.MF file in the META-INF directory is as follows: ATG-Product: OpenJMS
Manifest-Version: 1.0
ATG-Class-Path: classes/
ATG-Config-Path: config/
ATG-Required: DAS and for convenience I've added a CONFIG.properties file to the config foldername=OpenJMS
defaultForUpdates=true
Now when we can start Dynamo with C:\ATG\Dynamo5.6.1\home>bin\startDynamo -m OpenJMS
The OpenJMS Client Libraries
In order for an application to communicate with the OpenJMS it requires the
client library which is packaged as openjms-client-0.7.2.jar in the
openjms-0.7.2\lib directory. The User's Guide also lists openjms-rmi-0.7.2.jar,
exolabcore-0.3.3.jar and jms_1.0.2a.jar as required client side
libraries.
I'm going to add openjms-client-0.7.2.jar, openjms-rmi-0.7.2.jar and exolabcore-0.3.3.jar
to the ATG-Class-Path term in
the OpenJMS module's MANIFEST.MF file which we just created. I'm going to leave
the other jar out for now to see how we go, I have a feeling the classes are
included in Dynamo's CLASSPATH already. I've created a new folder under the
module folder called lib and copied the new jar files to that folder:
ATG-Product: OpenJMS
Manifest-Version: 1.0
ATG-Class-Path: classes/ lib/openjms-client-0.7.2.jar lib/exolabcore-0.3.3.jar \
lib/openjms-rmi-0.7.2.jar
ATG-Config-Path: config/
ATG-Required: DAS
Registering OpenJMS as a JMS Provider in ATG Dynamo
Now it should be relatively easy to hook up to OpenJMS directly with JMS code
as the Tomcat example does in the OpenJMS User's Guide. There's no need to copy
that here, I'd like to hook in via the MessagingManager component, perhaps that
way we can integrate with ATG's advanced features like scenario server.
This approach means that we've got some Dynamo configuration to do...
Note: The section Patch Bay: Configuring the Dynamo Message System in
Chapter 12 of the ATG 5.6.1 Application Server Programmers Guide
covers much of this configuration.
JMS providers are registered with ATG in the patchbay. The patchbay is
a series of combined XML files in the CONFIGPATH. The patchbay XML filename is
/atg/dynamo/messaging/dynamoMessagingSystem.xml. Whenever a module wishes to
modify the DMS (Dynamo's implementation of JMS) configuration, the module
includes a version of this file.
So I've got to create a new dynamoMessagingSystem.xml file in the OpenJMS
module's config layer, for me that is: C:\ATG\Dynamo5.6.1\OpenJMS\config\atg\dynamo\messaging\dynamoMessagingSystem.xml.
Now one thing to watch out for is that the JNDI resolution on the OpenJMS
side cannot handle Composite JDNI names so all the names are simple strings with
no slashes or prefixes
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE dynamo-message-system
SYSTEM
"http://www.atg.com/dtds/patchbay/patchbay_1.0.dtd">
<dynamo-message-system>
<patchbay>
<!-- local JMS provider -->
<provider>
<provider-name>
openjms
</provider-name>
<topic-connection-factory-name>
JmsTopicConnectionFactory
</topic-connection-factory-name>
<queue-connection-factory-name>
JmsQueueConnectionFactory
</queue-connection-factory-name>
<supports-transactions>
true
</supports-transactions>
<supports-xa-transactions>
false
</supports-xa-transactions>
<initial-context-factory>
/OpenJMS/InitialContextFactory
</initial-context-factory>
</provider>
</patchbay>
</dynamo-message-system>
Writing an JMSInitialContextFactory for the OpenJMS Connection
The patchbay configuration specifies an initial-context-factory, this is a
nucleus component which returns the initial context. It seems fairly easy to
write once you have the values for the properties. I gleaned these from the
sample code in the OpenJMS User's Guide:
package imagescript.atg.openjms;
import javax.naming.*;
import java.util.Properties;
import atg.dms.patchbay.*;
import atg.nucleus.*;
public class OpenJMSInitialContextFactory extends GenericService
implements JMSInitialContextFactory
{
String mINITIAL_CONTEXT_FACTORY
= "org.exolab.jms.jndi.rmi.RmiJndiInitialContextFactory";
public void setINITIAL_CONTEXT_FACTORY(String s)
{ mINITIAL_CONTEXT_FACTORY = s; }
public String getINITIAL_CONTEXT_FACTORY()
{ return mINITIAL_CONTEXT_FACTORY; }
String mPROVIDER_URL
= "rmi://localhost:1099/JndiServer";
public void setPROVIDER_URL(String s)
{ mPROVIDER_URL = s; }
public String getPROVIDER_URL()
{ return mPROVIDER_URL; }
public Context createInitialContext (String pProviderName,
String pUsername,
String pPassword,
String pClientId)
throws NamingException
{
logDebug("createInitialContext()");
logDebug("pProviderName = " + pProviderName);
Properties h = new Properties ();
h.put (Context.INITIAL_CONTEXT_FACTORY,
mINITIAL_CONTEXT_FACTORY);
h.put (Context.PROVIDER_URL,
mPROVIDER_URL);
return new InitialContext (h);
}
}
I saved this Java code in the src folder of the module and the compiled it to
place it in the classes C:\ATG\Dynamo5.6.1\OpenJMS>set DYNAMO_HOME=c:\atg\Dynamo5.6.1\home
C:\ATG\Dynamo5.6.1\OpenJMS>%DYNAMO_HOME%\bin\dynamoEnv
C:\ATG\Dynamo5.6.1\OpenJMS>cd src
C:\ATG\Dynamo5.6.1\OpenJMS\src>javac -d ..\classes atg\demo\openjms\*.java Now
I need to create the global Nucleus component /OpenJMS/InitialContextFactory based on
my new class. I'll do this in the ACC making sure that the new properties file
get's put in the module's config layer and not localconfig.# /OpenJMS/InitialContextFactory
#Fri May 31 15:26:10 PDT 2002
$class=imagescript.atg.openjms.OpenJMSInitialContextFactory
$scope=global
loggingDebug=true
Updating the OpenJMS Configuration
Now we need to make sure that OpenJMS is configured in a matching way. It
needs to have an internal rmi server with the destination connection factories
listed. We'll update the rmi_jms.xml, you will of course make a backup first,
unlike I just didn't :). We need are to check the names of the
Connection Factories match those we specified in the patchbay file. We'll
leave the database configuration alone for now, although I feel we'll be coming
back here to change it to solid or whatever DB the site is using. <?xml version="1.0"?>
<!-- OpenJMS configuration:
. RMI connectors
. JDBM persistency
. embedded JNDI provider
. embedded RMI registry, running on port 1099
. single host
. preconfigured destinations
NOTES: this configuration shows all configuration elements relevant
when using an RMI connector.
-->
<Configuration>
<!-- Required when using an RMI connector -->
<Connectors>
<Connector scheme="rmi">
<ConnectionFactories>
<QueueConnectionFactory name="JmsQueueConnectionFactory" />
<TopicConnectionFactory name="JmsTopicConnectionFactory" />
</ConnectionFactories>
</Connector>
</Connectors>
<!-- Required -->
<DatabaseConfiguration>
<JdbmDatabaseConfiguration name="openjms.db" />
</DatabaseConfiguration>
<!-- Required -->
<AdminConfiguration
script="${openjms.home}\bin\startjms.bat"
config="${openjms.home}\config\rmi_jms.xml" />
</Configuration>
The OpenJMS Admin Tool
To restart the OpenJMS safely the Admin Tool can be used, I've added a new
batch file to my configuration startOpenJMSAdmin.bat to do this: set JAVA_HOME=c:\jdk1.3.1
set OPENJMS_HOME=C:\java\openjms-0.7.2
@echo off
echo Starting openJMS Admin
cd %OPENJMS_HOME%\bin
admin -config ../config/rmi_jms.xml Using the Admin Tool, shutdown and
restart the OpenJMS server. If you delete the example topics and queues from the
configuration they may still show up in the Admin Tool. This is because these
topics and queues exist in the database file. To remove them completely shut
down the JMS server and delete the JDBM file openjms.db, then restart.
Checking the New Configuration in Dynamo
First the changes we've made to the Dynamo configuration will require a
restart.
We don't have much in place yet so as a basic check do 2 things:
- Make sure our new InitialContextFactory component was automatically
started
- That the definitionFile property of the MessagingManager contains our XML
changes
How about testing it? click here
|