Accessing a Visual C++ EXE from Java

Accessing a Visual C++ EXE from Java

Java/J2EE COM Interoperability Products Page

This example demonstrates how to access a Visual C++ MFC EXE from Java. J-Integra® for COM is a Java interoperability component that bridges Java and Visual C++ MFC applications. It provides bi-directional access of Java objects and COM components.

Contents

  1. Introduction
  2. Configure your environment
  3. Create the Visual C++ COM Component
  4. Run the Java Client on Local Windows Machine
    1. Generate Java Proxies
    2. Create the Example
    3. Compile and Run the example
  5. Run the Java Client on Remote Machine, e.g. Windows, UNIX, Linux and etc

1 Introduction

You may read this example simply to get a feel for how easy it is to use J-Integra® to access COM components created from Microsoft Visual C++ 6.0. You can run the Java client on a Windows machine to access its local MFC COM component, or run the Java client on a non-Windows machine (such as Linux) to access MFC COM component installed on a remote Windows machine.

This example will require access to a machine that is running Windows, and has Visual C++ installed on it. This example assumes you are using Microsoft Visual Studio 6.0.

2 Configure your environment

If you do wish to try out this example, you should first download and install the Java Developers Kit. You should also download and install the J-Integra® for COM.

We will be performing this example under D:\pure. Create that directory (if you have not already created it for the Excel example), and a pure2vc directory under it. Set your path environment variable to include the JDK and J-Integra® bin directories, and update your CLASSPATH environment to include the J-Integra® runtime:

Accessing a Visual C++ EXE from Java: Set environment variables

3 Create the Visual C++ COM Component

  1. Start up Visual C++, and create a new project:

    Accessing a Visual C++ EXE from Java: Create new project

  2. Create a project of type MFC AppWizard (exe), set the Location to D:\pure, and then set the Project name to vcproject -- the Location will be automatically updated to include the project name:

    Accessing a Visual C++ EXE from Java: Edit project details

    Click on OK, and on the next two pages Step 1 and 2, simply click on Next

  3. On Step 3, enable Automation Support:

    Accessing a Visual C++ EXE from Java: Enable automation support

    Click on Finish, and then click on OK to create the new project

  4. Start up the Class Wizard using View|Class Wizard:

    Accessing a Visual C++ EXE from Java: Start Class Wizard

  5. Select the Automation pane:

    Accessing a Visual C++ EXE from Java: Select Automation window

  6. Select the project document class CVcprojectDoc:

    Accessing a Visual C++ EXE from Java: Select project document class

  7. Click on the Add Method button to add a new method to the class:

    Accessing a Visual C++ EXE from Java: Add new method

  8. Set the method name to meth1, set the return type to float, and specify two parameters p1 and p2, of types DATE and BSTR* (pointer to a String) respectively:

    Accessing a Visual C++ EXE from Java: Edit method properties

    Click on OK

  9. Click on the Add Method button to add a second method to the class:

    Accessing a Visual C++ EXE from Java: Add a second method

  10. Set the method name to meth2 and the return type to void (this method will be used to demonstrate an exception being thrown, so we don't need parameters or return types):

    Accessing a Visual C++ EXE from Java: Edit method details

    Click on OK

  11. Click on the Add Property button to add a new property to the class:

    Accessing a Visual C++ EXE from Java: Add a new property

  12. Set the new property name to prop1, set the return type to LPDISPATCH (a pointer to a COM Component), and select Get/Set methods for the implementation:

    Accessing a Visual C++ EXE from Java: Edit property details

    Click on OK

  13. You will now create a new COM Component, instances of which will be returned by the prop1 property you just added. Click on the Add Class button, and select New...:

    Accessing a Visual C++ EXE from Java: Add new class

  14. Set the class name to CMyClass, set the Base Class to CCmdTarget and select the Automation radio button. By deriving the class from CCmdTarget it can act as a COM Automation Component:

    Accessing a Visual C++ EXE from Java: Edit class details

    Click on OK

  15. Click on the Add Method button to add a method to the new class:

    Accessing a Visual C++ EXE from Java: Add method to new class

  16. Set the method name to add, set the return type to double, and define two parameters p1 and p2 of types float and double respectively:

    Accessing a Visual C++ EXE from Java: Edit method details

    Click on OK

  17. Click on OK to exit the Class Wizard, and on the left hand side of your screen, double-click on vcProjectClasses-CVcprojectDoc-meth1, to edit the implementation of that method:

    Accessing a Visual C++ EXE from Java: Edit method implementation

  18. Update the implementation of meth1 to return 22/7, and to update the string parameter (p2) with a string representation of the first parameter (a date):

    float CVcprojectDoc::meth1(DATE p1, BSTR FAR* p2)
    {
    COleDateTime theDate = p1;
    CString dateStr = theDate.Format("%d/%m/%Y %H:%M:%S %Z");
    *p2 = dateStr.AllocSysString();
    return 22.0F/7.0F;
    }

  19. Update the implementation of meth2 to throw an exception:

    void CVcprojectDoc::meth2()
    {
    AfxThrowOleDispatchException(0, "I am sorry Dave, I can't do that...");
    }

  20. Update the implementation of GetProp1 to return a new instance of the MyClass class you created using the class wizard:

    LPDISPATCH CVcprojectDoc::GetProp1()
    {
    CMyClass* myClass = new CMyClass();
    return myClass->GetIDispatch(false);
    }

  21. Move to the top of the file, and add #include "MyClass.h", so that we can use CMyClass from this file:

    Accessing a Visual C++ EXE from Java: Include MyClass.h

  22. Double-click on vcProjectClasses-CMyClass-add, to edit the implementation of that method:

    Accessing a Visual C++ EXE from Java: Edit the method implementation

  23. Update the implementation of add to return the sum of the two parameters:

    double CMyClass::add(float p1, double p2)
    {
    return p1 + p2;

    }

  24. Build and execute your server using Build|Execute vcproject.exe. When asked if you wish to build, click on OK. By executing the server, you will register it so that we can configure access to it from DCOM. Once it has started running, you can immediately shut it down:

    Accessing a Visual C++ EXE from Java: Build and run server

4 Run the Java Client on Local Windows Machine

You can try this example on local Windows machine first to get a feel for how easy it is to use J-Integra® to access MFC COM component from Java. Once you make it working on local machine, you can then try to run the Java client on a non-Windows machine to remotely access MFC COM component on another Windows machine.

4.1 Generate the Java proxies

Use com2java to generate Java proxies which can be used to access the COM Component you just created from any standard JVM:

  1. Select D:\pure\vcproject\Debug\vcproject.tlb as the type library to open -- this file was automatically created by Visual C++ when you built your project.
  2. Enter d:\pure into the Output Dir field
  3. Enter pure2vc into the Java Package text field
  4. Click on the Generate Proxies button
  5. Accessing a Visual C++ EXE from Java: Generate proxies

4.2 Create the example

  1. Create the file d:\pure\VcExample.java, by cutting and pasting from your Web Browser.

    Here is the file.

    import java.util.Date;
    public class VcExample {
      public static void main(java.lang.String[] args) {
        try {
          com.linar.jintegra.Log.logImmediately(3, "jintegra.log");
    
          // DCOM authentication: Make sure NT DOMAIN, Nt USER, Nt PASSWORD are valid credentials.
          // Uncomment this line if VcExample.java remotely accesses MFC COM component:
          // com.linar.jintegra.AuthInfo.setDefault("NT DOMAIN", "USER", "PASSWORD");
        
          // Specify host name or IP address of MFC COM component machine as parameter if
          // VcExample.java remotely accesses MFC COM component.
          // pure2vc.Document doc = new pure2vc.Document("123.456.789.0");
          pure2vc.Document doc = new pure2vc.Document();
    
          // See how VC sees the date we pass it
          String[] dateStr = { "" };
          Date now = new Date();
          float result = doc.meth1(now, dateStr);
          System.out.println("VC says that 22/7=" + result);
          System.out.println("VC says that the date and time is " + dateStr[0]);
          System.out.println("Java thinks the date and time is " + now);
          // doc.meth2() returns a new object (you can't tell what type, from the type library)
          // -- we wrap it in the corresponding Java class, since we know what it really is
          pure2vc.MyClass myClass = new pure2vc.MyClass(doc.getProp1());
          double result2 = myClass.add(654.12F, 76.1234);
          System.out.println("The newly returned object says that 654.12 + 76.1234 = " + result2);
          myClass.release();
    
          // Now we will invoke a method which will deliberately throw an exception
          doc.meth2();
        } catch(Exception e) {
          e.printStackTrace();
        }
      }
    }
  2. Compile the example using the javac VcExample.java command:

    Accessing a Visual C++ EXE from Java: Compile example

4.3 Compile and run the example

On the Java client machine, make sure your CLASSPATH and PATH environment variables are set up according to J-Integra® installation instructions. Compile and run the example in  J-Integra®'s native mode (you need to use DCOM mode if remotely accessing MFC COM component):

javac VcExample.java
java -DJINTEGRA_NATIVE_MODE VcExample

5 Run the Java Client on Remote Machine, e.g. Windows, UNIX, Linux and etc

You can also run the Java client on a remote machine, such as Linux, Solaris, UNIX and AIX. For instance, if you run it on a Linux machine, then you must do the following.:

  1. Move the com2java tool to the Windows machine to generate the Java proxies from MFC COM Component, and then move the Java proxies from the Windows machine to the Linux machine.
  2. Install J-Integra® (the jintegra.jar file) on the Linux machine and include the jintegra.jar file and generated Java proxies in CLASSPATH.
  3. Use DCOMCNFG to configure MFC COM Component on the Windows machine.
  4. Pass correct login credentials to com.linar.jintegra.AuthInfo.setDefault("NT DOMAIN", "NT USER", "NT PASSWORD");
    Refer to Configuring DCOM for Remote Access for more information about AuthInfo.setDefault.
  5. Pass the IP address or computer name of the MFC COM Component machine to the constructor of Document object in VcExample.java:
    pure2vc.Document doc = new pure2vc.Document("123.456.789.0");
  6. Move VcExample.java to the Linux machine. Compile and run it in DCOM mode without using DJINTEGRA_NATIVE_MODE property:
    java VcExample