Accessing JMS from VB |
This example demonstrates how to access a JMS topic from VB. J-Integra® for COM is a Java interoperability component that bridges Java and JMS. It provides bi-directional access of Java objects and COM components. It includes:
A VB COM object implementing the "javax.jms.MessageListener" interface
The Client application passing this object as a parameter to JMS "setMessageListener" method
The JMS Provider can be running on any platform, such as Solaris, UNIX, Linux, etc.
This example assumes the reader has working knowledge of Java, JMS, VB and
hands-on experience with J-Integra®
(specifically accessing Java objects from COM).
This is not an introductory example. If you have not used J-Integra® before,
please take a look at the basic step-by-step
COM accessing Java examples first.
This example uses Suns' J2EESDK1.3, and is based on Sun's Java Message Service tutorial. (Section 4.3 - Simple Publish/Subscribe). Make sure Sun's example runs successfully before attempting to use a VB client. It is very difficult to troubleshoot the system when the JMS part is not working properly in the first place.
To access JMS in DCOM mode, we need a bridging class that registers a
JVM with J-Integra® runtime,
and handles Java object instantiation.
Since we need to implement a Java interface, we must use Early Binding and generate the Java proxies and the Type Library.
Compile and register the COM Type Library (.tlb) for those JMS classes.
Create a Visual Basic Client application, and the Message Listener COM object.
Optionally, run the Java Bridging Class on a non-Windows machine.
Create a folder and name it JMStoVB.
In the JMStoVB folder, create a Java class named COMtoJMSEarly.
Cut and paste the code below (note the JVM name: "JMSEarly"):
import
com.linar.jintegra.*; |
From the command line, open the JMStoVB/Javax directory and run the java2com tool.
Click "Add...", locate j2ee.jar and click Ok.
From the j2ee.jar folder, select the following classes:
javax.naming.InitialContext
javax.jms.TopicConnectionFactory
javax.jms.Topic
javax.jms.TopicConnection
javax.jms.TopicSession
javax.jms.TopicSubscriber
javax.jms.Message
javax.jms.MessageListener
Select Save Settings from the File menu
From the command line, type:
midl Javax.idl
regtlb Javax.tlb JMSEarly
Note that we specify JSMEarly as the JVM name.
Run the regjvm tool.
Click New JVM and specify JMSEarly as the JVM name. Set the Port to 4010 (can be any available port).
Click Save JVM.
In the JMStoVB/VBClient folder, create an ActiveX EXE project—a standard EXE will not work in this case, as we need to export a COM object.
Click Project/References, and select the Javax type library.
The project should have a Class Module, a Form, and a Module:
Create the TextMessageHandler Class, and make it implement Javax.JavaxJmsMessageListener interface:
The code for the TextMessageHandler:
Option Explicit Option Base 0 Implements Javax.JavaxJmsMessageListener Private Sub Class_Initialize() MsgBox "JMS Text Message Listener Initialized." End Sub Private Sub JavaxJmsMessageListener_onMessage(ByVal p1 As Javax.JavaxJmsMessage) Dim message As Javax.JavaxJmsTextMessage Set message = p1 MsgBox message.GetText End Sub |
Create the Form1 Form:
The code for the Form:
(Note that the code follows the equivalent Java JMS subscriber code very
closely)
Option Explicit Dim InitialContext As Javax.JavaxNamingInitialContext Dim TopicConnectionFactory As Javax.JavaxJmsTopicConnectionFactory Dim Topic As Javax.JavaxJmsTopic Dim TopicConnection As Javax.JavaxJmsTopicConnection Dim TopicSession As Javax.JavaxJmsTopicSession Dim TopicSubscriber As Javax.JavaxJmsTopicSubscriber Dim TopicListener As TextMessageHandler Private Sub Command1_Click() Set InitialContext = New Javax.JavaxNamingInitialContext ' Create Java Naming Context ' Look up the connection factory Set TopicConnectionFactory = InitialContext.lookup("TopicConnectionFactory") Set Topic = InitialContext.lookup("MyTopic") ' Look up the Topic "MyTopic" 'Create topic connection Set TopicConnection = TopicConnectionFactory.createTopicConnection2 Set TopicSession = TopicConnection.createTopicSession(False, 0) 'Create topic session Set TopicSubscriber = TopicSession.createSubscriber2(Topic) ' Create topic subscriber Set TopicListener = New TextMessageHandler ' Create the Message Handler Call TopicSubscriber.setMessageListener(TopicListener) ' Set the message Handler TopicConnection.start ' Connect to the topic. End Sub Private Sub Form_Unload(Cancel As Integer) TopicConnection.Close ' Close the connection, and release the resources. Set TopicListener = Nothing End Sub |
Create the Main Module:
The code:
Sub Main() Dim frm As New Form1 Load frm frm.Show End Sub |
Click Project/Properties, and select Sub Main as the Startup Object.
Build the project.
Prepare a startup script (runJVM.bat) for the Bridging Class, and
start the Bridging Class.
If you are running from a non-Windows machine, use the equivalent shell
script.
set JAVA_HOME=c:\jdk1.3.1_01 set J2EE_HOME=C:\j2sdkee1.3 set classpath=.;%classpath% set classpath=c:\JMStoVB\Javax;%classpath% set classpath=%J2EE_HOME%\lib\j2ee.jar;%classpath% set classpath=%J2EE_HOME%\lib\locale;%classpath% set classpath=c:\jintegra\lib\jintegra.jar;c:\jintegra\lib;%classpath% set path= set path=%J2EE_HOME%\bin set path=%JAVA_HOME%\bin;%path% java -Djms.properties=%J2EE_HOME%\config\jms_client.properties -DJINTEGRA_DCOM_PORT=4010 COMtoJMSEarly pause |
We put the following on the classpath (the directory names on your machine may be different):
The directories JMStoVB, and "JMStoVB/Javax
The jintegra.jar
The J-Integra® license directory (jintegra/lib)
The J2EE classes: j2ee.jar, and \lib\locale
Run the Bridging Class with the JINTEGRA_DCOM_PORT set to 4010, the JVM port number.
Make sure that the Topic (MyTopic), has been created. (This is done in Sun's JMS tutorial.)
Start the J2EE server: From the command line, type
j2ee -verbose
Start the VB Client, and click Start Listening to subscribe to the Topic and start listening for messages.
Start the Topic Publisher, as specified in the JMS tutorial and observe the callbacks.
The output of the Bridging Class in shown in the following screen shot.
Specify the machines' propert network name to the regvjm tool instead of localhost
Uncomment the com..linar.jintegra.AuthInfo.setDefault("NT
DOMAIN", "NT USER NAME", "NT PASSWORD");
line in the bridging class, and recompile it.
(The Credentials in "setDefault" are the valid credentials for
a machine running the VB client).
Make sure that the TextMessageHandler object is configured to allow DCOM access (see Configuring DCOM for Remote Access).
2. VB Client raises an error similar to the one below:
Make sure that the proxies (IID... files) have been compiled and
placed on the Classpath.
3. The VB Client can add the Message Listener object successfully, but no
callbacks are coming. The VB client does not raise any errors.
There may be a problem with authentication. Check the Java console and the
J-Integra® log (callbacks.log) for occurrences of the AutomationException:
0x80070005 - General access denied error and the AutomationException:
0x5 - Access is denied error. Make sure that the CallbackObject
has been configured to allow DCOM access, and the credentials supplied in AuthInfo.setDefault(..)
are valid. Make sure that the CallbackObject's Authentication level
is set to Connect in DCOMCNFG. Consult the Configuring DCOM for
Remote Access section of the documentation on resolving this error.
4. The VB Client raises and error: Can't find SerialContextProvider
Make sure that the J2EE server is running.
Check the Bridging Class console for errors.