This is a showcase review for our sponsors at CodeProject. These reviews are intended to provide you with information on products and services that we consider useful and of value to developers.
Messaging made easy with Visual MainWin for J2EE and OpenJMS
One common API that is used in Java� applications is the JMS API, which allows you to implement managed messaging and message queues. When using Visual MainWin for J2EE (a.k.a. Grasshopper) from Mainsoft, you can consume and use Java resources from JAR files or EJBs. In this article, you will learn how to use C# or VB.NET in your Grasshopper applications to interface directly with Java code from the OpenJMS implementation of this API. You can then use this to write and debug JMS applications using the Visual Studio .NET� development environment.
Overview
The Grasshopper 2.0 Technology Preview from Mainsoft introduces support for Microsoft�s� Visual Studio� 2005 IDE and the .NET Framework 2.0. With it, you can test cross-platform development using the latest version of Visual Studio software, C# 2.0 features, and ASP.NET 2.0 controls, and rehost applications that use them on Java-enabled platforms with the Tomcat application server.
Microsoft released .NET 2.0 at the end of 2005, introducing numerous higher level features on top of the technical underpinnings that made .NET 1.x a success. Improved language features such as generics and nullable types and a broader ASP.NET Framework enable you to rapidly develop multi-tier Web sites. ASP.NET 2.0 introduces numerous new Web controls to reduce the amount of code you need to write to build a Web site, an improved security model, improved and expanded data support, and features such as master pages that make it easier to build and maintain Web sites.
Getting Started
To get started, you will need Grasshopper 1.7, which can be downloaded from the Mainsoft website. You will also need Tomcat 5.5, and this will be installed for you as part of the Grasshopper installation. Should you want to use IBM WebSphere�, BEA WebLogic�, or JBoss�, you can also do this, but you�ll need the Enterprise edition of Visual MainWin� for J2EE� which may be downloaded from the same place.
Finally, you�ll need a messaging server, and the one that I would recommend, and am using in the article is the OpenJMS server, which is the standard message queue MOM (Messaging Oriented Middleware) for Tomcat. It can be downloaded from SourceForge.
Installing OpenJMS is a snap. Simply download the binaries, and unzip them to your hard drive. Then, set the environment variable OPENJMS_HOME
to where you unzipped them. In my case, I put them in the directory C:\jms\openjms-0.7.7-alpha-3, and as such set the system environment variable to this value. To do this in Windows, right click �My Computer� on your desktop, and select �Properties�.
Then, on the �Advanced� tab (Figure 1), select �Environment Variables�.
Figure 1. Environment Variables Setup.
The dialog will show user variables and System variables (Figure 2).
Figure 2. Environment Variables Dialog
In the System variables area, click New, and enter the values for the variable name and value as shown in Figure 3. Note that the Variable value may be different on your system. You should set it to the name of the directory where you unzipped OpenJMS.
Figure 3. Setting the Environment Variable
If you do not have a JRE or JDK on your system, you should download and install one, and make sure that your JAVA_HOME
system variable is set to its install directory. The default value for a standard JRE installation is C:\Program Files\Java\jre1.5.0_06.
Once all these are set up, from a DOS command, change to the �bin� directory under where you installed OpenJMS, and issue the �openjms run� command. You should get an output like that in Figure 4.
Figure 4. Running OpenJMS in a Command Console
Build the Messaging Namespace
The next step is to build the messaging namespace. This will contain the classes that you will use to wrap the underlying JMS APIs so they can be used simply within your applications. From Visual Studio .NET, do a File->New->Project request, and select �Class Library� from the �Visual MainWin C# for J2EE Projects� folder. (See Figure 5.)
Figure 5. Creating a New System.Messaging Namespace
This will create a new class library with a single class called �Class1.cs�. Remove all the code in this library, and replace it with the code for System.Messaging
that is in the download for this article.
Next, you will need to add references to the JAR files for OpenJMS. You can do this by right clicking the �References� node in Solution Explorer, and selecting �Add Java Reference�. This will open a common dialog. Use it to browse to the �lib� directory underneath where you installed OpenJMS. So, for example, browse to C:\jms\openjms-0.7.7-alpha-3\lib if you unzipped the OpenJMS files to the C:\jms directory.
Pick these JARs to add references to them � it may take a few minutes to complete the import:
- commons-codec-1.3.jar
- commons-logging-1.0.4.jar
- concurrent-1.3.4.jar
- jms-1.1.jar
- jndi-1.2.1.jar
- openjms-0.7.7-alpha-1.jar
- openjms-common-0.7.7-alpha-1.jar
- openjms-net-0.7.7-alpha-1.jar
- spice-jndikit-1.1.jar
You should now be able to compile your class library. If you encounter any compilation errors, check that you imported all the JAR files mentioned above correctly. Failing that, the full Visual Studio solution for this library is available in the download.
Build the Message Sender
Next, you�ll build a simple console application that sends messages into the Messaging Queue. This is made very simple, thanks to the class library that you built above.
To get started, select File->New->Project in Visual Studio .NET. Select �Console Application� from the �Visual MainWin C# for J2EE� folder, and give it the name �Message Sender�.
Once the solution has been created, add a JAR reference to System.Messaging.jar � the class library you built earlier. You�ll find it in its project folder unless you have already deployed it elsewhere.
Then, add the same JAR Java references that you did earlier when creating the library.
At the top of Class1.cs, add the following �using
� directives:
using System;
using System.Messaging;
using javax.naming;
using javax.jms;
Finally, in the Main
method, you�ll add the code that implements the messaging queue. You�ll start with code that sets up the messaging environment, by setting properties on its Context
object:
static void Main(string[] args)
{
java.util.Hashtable properties = new java.util.Hashtable();
properties.put(Context__Finals.PROVIDER_URL, "tcp://localhost:3035");
properties.put(Context__Finals.INITIAL_CONTEXT_FACTORY,
"org.exolab.jms.jndi.InitialContextFactory");
properties.put(Context__Finals.SECURITY_PRINCIPAL, "admin");
properties.put(Context__Finals.SECURITY_CREDENTIALS, "openjms");
To learn and understand more about these properties and what they do, check out the OpenJMS documentation.
In the rest of your Main
method, you�ll send ten messages with the current time on them into the message queue. It�s safe to run this without the listener being active. OpenJMS will handle queuing for you until you�re ready to pop them off.
string queueServer = "localhost";
string queueName = "queue1";
int N = 10;
if (args != null && args.Length > 0)
{
N = Convert.ToInt32(args[0]);
}
for (int i = 0; i < N; i++)
{
System.Messaging.Message theMessage = new System.Messaging.Message();
theMessage.Body = "test value " + i
+ " " + System.DateTime.Now.ToShortTimeString();
MessageQueue mq = new MessageQueue("FormatName:DIRECT=OS:" +
queueServer + "\\" + queueName);
mq.Send(theMessage);
Console.WriteLine("Sent Message: {0}", theMessage.Body);
}
Console.ReadLine();
java.lang.System.exit(0);
}
Running this application will then send the number of messages specified in the argument to the queue, or if there is no argument, it will send 10 as shown in Figure 6. The meat of this application is in the for
loop. It simply sets up a System.Messaging.Message
object (found in the class library you created earlier), and initializes its body with the string �test value� and the current date and time. It then instantiates a message queue object, and sets it up with the local server and the queue called queue1
, which is a predefined queue in OpenJMS. Then, the Send
method on this queue is invoked, with the message passed to it as a parameter. Very simple!
Figure 6. Running the Message Sender
At this point, the messages have now been dispatched by your message sender, and are sitting in a queue managed by OpenJMS waiting to be picked up. Let�s not keep them waiting for too long, and write a simple reader that will pull them off the queue!
Build the Message Reader
Follow the same steps that you used to create the MessageSender project above, and create a console application called �MessageGetter� that will get the messages. Be sure to add the same references that you did for that project, namely the eight references to OpenJMS jars, and the reference to the System.Messaging
class library that you created earlier.
Then, add the same �using
� directives to the top of Class1.cs that you did earlier.
Finally, here is the Main
method for your class:
static void Main(string[] args)
{
java.util.Hashtable properties = new java.util.Hashtable();
properties.put(Context__Finals.PROVIDER_URL, "tcp://localhost:3035");
properties.put(Context__Finals.INITIAL_CONTEXT_FACTORY,
"org.exolab.jms.jndi.InitialContextFactory");
properties.put(Context__Finals.SECURITY_PRINCIPAL, "admin");
properties.put(Context__Finals.SECURITY_CREDENTIALS, "openjms");
string queueServer = "localhost";
string queueName = "queue1";
int N = 10;
if (args != null && args.Length > 0)
{
N = Convert.ToInt32(args[0]);
}
for (int i = 0; i < N; i++)
{
MessageQueue mq = new MessageQueue("FormatNameIRECT=OS:" +
queueServer + "\\" + queueName);
System.Messaging.Message theMessage = mq.Receive();
Console.WriteLine("Received message: {0}", theMessage.Body);
}
}
Running this application will then give you the output from Figure 7. You will see that it receives each of the messages that were pumped out by the sender. The code is very simple to the sender. You set up a MessageQueue
object, and then listen in on it with the Receive()
method. This returns a message object that you can query for its contents with the �Body
� property.
Figure 7. Running the Message Receiver Application
Conclusion
Grasshopper isn�t limited to the .NET namespaces that it directly supports. As Java references can be plugged directly into your application, and Java source code can run inline with your C# or VB.NET code, you can easily use external Java APIS.
In this article, you learned how to use JMS messaging on the OpenJMS server from Visual Studio .NET, and saw how easy it is to send messages into a queue and get them out. The System.Messaging
class library that you implemented can easily be reused in your applications, so you can go ahead and interoperate your .NET applications with JMS through Grasshopper!
Thanks to Laurence Moroney for polishing the article.