September 2, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Access COM Via Java -- A Tutorial

  • May 21, 2001
  • By Yashodhar Desai
  • Send Email »
  • More Articles »

The fact is that Java has been accepted more quickly than any other programming language for Internet applications running on multiple platforms. But many a COM object has been developed by using C++ technology, which are still very useful and very fast as compared with Java.

Hence, I'm inspired to use these COM objects that already exist using Sun's Java. The COM object can be called by a client with Microsoft's JVM or J++, but not with Sun's Java directly. I'll try to show you the way to do this using Java.

In this tutorial, I intend to build an application that can access a COM object created using VC++ 6.0 ATL and then call this COM-server object via a pure Java client.

I believe you should first know how to employ simple COM using ATL with VC++.

I will divide the tutorial into three parts:

1. Write a COM server.

2. Write a Java client.

3. Write an interface between 1 and 2 to work.

Part I

Step 1: Building ATL COM

Choose the "ATL COM AppWizard". Give the project the name "Java_COM_ATL". Set the location where you want this project to be saved in Select "Server Type" as "Dynamic Link Library". Press the finish button to have the Wizard generate the appropriate files for you. A "New Project Information" window will appear to tell you what files are going to be created. Press the OK button to accept this.

Step 2: Creating a New ATL

Make sure you can see the "Workspace View" inside the VC++ IDE. Choose New ATL Object from the Inset Menu. You will see a window like the following:



The default choice, Simple Object, is what we want. Click the Next Button, and you will be in the "ATL Object Wizard Properties" window. In the "Short Name" textbox, enter "Jcom". Notice how the Wizard automatically fills in the rest of the textboxes for you. Click on the "Attributes" tab at the top. Here, you have several choices to make. For the first choice, Threading Model, we will stick with the default Apartment Model. For the "Interface", click on "Custom", instead of "Dual". Finally, as we are not going to be concerned with "Aggregation", click on the "No" radio button. We don't need to worry about any of the three checkboxes at the bottom. Click on the OK Button and let the Wizard create our new ATL Jcom Object.



Step 3: Adding a Method

If you click on the "ClassView" tab now in your workspace, you will notice that the Wizard added a bunch of things. The first thing we want to do is add a method. We can do this easily by right clicking on "IJcom" and choosing "Add Method".

Once you have clicked on "Add Method", you will see the "Add Method to Interface" window. Under the Return Type, you can see that by default the method will return "HRESULT". The next textbox allows us to type in the MethodName. Let's type in "AddNumbers". The last textbox asks us the Parameters we wish to use. As we want to add two numbers together and get a result back, we will use three parameters. The last parameter will be a pointer for a return textbox:



[in] long num1, [in] long num2, [out] long *ReturnVal

We are declaring two parameters as long, the values are going in [in], and a final value to return [out] the answer. Click on the OK Button. Click on the "ClassView" tab and expand all the "+" symbols so the tree is fully open to view. Under the top interface ("IJcom"), you will see our "AddNumbers" method and the parameters we gave it. Double-click on this, and it will place you into the code. Add the following code: This is a must for any job.



STDMETHODIMP CJcom::AddNumbers(long num1, long num2, long *ReturnVal)
{
	// TODO: Add your implementation code here
	//This is the actual fuction doing our job.
	*ReturnVal = num1 + num2;

	return S_OK;
}

Step 4: Compiling the DLL

On compiling, the Com Server will be built. As usual, the compiler will register your new DLL in the registry so that other programs can make use of it. Let's try it with Java. Up to this point, it's all very normal; but to write Java code to access this COM server, we need the help of Java Native API. Before that, though, we have to create the Java client. Stop or minimize VC++ now for the moment; you will need it again in Part III.

Part II

Step 1: Java Code

To write Java code, you may choose any IDE you wish, but I have done it with Notepad to make things simpler at the latter stage. Prepare the file name as HelloCom.java as follows and compile to generate the HelloCom.class file as directed below.



class HelloCom {
    public native void HelloCom_function();

    static {
        System.loadLibrary("ComClient");
    }
    
    public static void main(String[] args) {
        new HelloCom().HelloCom_function();
    }
}

Here, you can see that to call the native method, the system has to load a DLL file which we will create in Part III, but we will now call "ComClient" (remember the name with case). There should not be any problem in the compilation of the file, but it will throw an UnSatisfiedLinkError exception if you try to run it without ComClient.dll created or not in the classpath. Before going further, we need to do some more work.

Go to the command prompt and compile the file with following command:



javac HelloCom.java

And then give the following command:



javah HelloCom

This will generate the HelloCom.class and HelloCom.h files. You will need these two files in the next part.

Part III

Here is the unusual part of the tutorial. Normally, to access a COM object created as in Part I, you would use C++ code. Subsequently, it would generate an .exe file for running the COM object. In our case, however, we will not generate an .exe file, but we will generate another .dll file to access the COM object. In the end, this DLL (ComClient.dll) will be a pure client for the COM object to serve, with Java code, our Java client (HelloCOM.class). This can be done as follows.

Step 1: Creating ComClient.dll

Start up VC++ again and Select New|Project|Win32 Dynamic Link Library and use the name ComClient. (Be careful, here you must give the same name that was given for loading the lib. in Part II, and it is case-sensitive, too.)

Step 2: Include Header File

Now copy the HelloCom.h file of Part II to the working dir of the project (in my case, it is "C:\Program Files\Microsoft Visual Studio\MyProjects\ComClient"), and include it as the header file.

Step 3:Write C++ File in the Project

Again, create one C++ file (named MyComClient.cpp) using the editor, and save and include it in the same dir. The source code of the C++ file is given below, with comments whenever it's required.



//Include JNI.H file which is available with JDK1.3 to tell complier
//Open Tools|Option|directories and include the proper dir. so that
//complier can open it for reading otherwise fatal error will be 
//reported.
#include 
//Allready in the working dir.
#include "HelloCom.h"
#include 
//Normal for the Com Client
#include "..\Java_COM_ATL\Java_COM_ATL.h"
#include 

//Refere JNI API or get the following native method signature from
//HelloCo.H file This is the method called by JavaClient.

JNIEXPORT void JNICALL Java_HelloCom_HelloCom_1function
  (JNIEnv *, jobject)
{
	 

// Copy the following from the Java_COM_ATL_i.c file
// from the Java_COM_ATL project directory
//This number may be diff. as it generated by VC++ using uuidgen.exe.

	const IID IID_IJcom = {0x665A282D,0x3ECD,0x11D5,{0xAC,0x5C,0xDF,0xF9,0xE8,0x6D,0xD6,0x2D}};
	const CLSID CLSID_Jcom = {0x665A282E,0x3ECD,0x11D5,{0xAC,0x5C,0xDF,0xF9,0xE8,0x6D,0xD6,0x2D}};

// Declare and HRESULT and a pointer to the Java_COM_ATL interface
	HRESULT			hr;
// Interface creadted in Part I
	IJcom		*IJComAtl;

	// Now we will intilize COM
	hr = CoInitialize(0);
	if(SUCCEEDED(hr))
	{
		hr = CoCreateInstance( CLSID_Jcom, NULL, CLSCTX_INPROC_SERVER,
						IID_IJcom, (void**) &IJComAtl);
		
		// If we succeeded then call the AddNumbers method, if it failed
		// then display an appropriate message to the user.
		if(SUCCEEDED(hr))
		{
			long ReturnValue;

			hr = IJComAtl->AddNumbers(5, 7, &ReturnValue);
			cout << "The answer for 5 + 7 is: " << ReturnValue << endl;
			hr = IJComAtl->Release();  
		}
		else
		{
			printf("CoCreateInstance Failed.");
		}
	}
	// Uninitialize COM
	CoUninitialize();

    printf("Hello Com is ok and over!\n");
    return;
}

Step 4: Compile

Compile the code to create "ComClient.dll" and put this file in the working dir. Stop VC++, we do not need it now. It's all over.

Step 5: Follow This Step to Run the Java Client.

Step A. Copy your java class file (HelloCom.class) created in Part II to this working dir.

Step B.Go to the DOS prompt and change the dir to that of working Dir.

Step C.Execute the Java class as follows.



		java HelloCom

You must see the output as:



The answer for 5 + 7 is: 12
Hello Com is ok and over!
		

Note: Here, only the simple function HelloCom_function is used, without any return type, and any argument is passed; but in the real world, this can be modified very easily. The ComClient is pure C++ and can even access both the Java object and COM objects.

Downloads

Download demo project = 186K

Download source = 30K

This article was contributed by Yashodhar Desai.






Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel