Using Java via COM interoperability
Why COM interop?
JuggerNET is a great tool to make your Java code accessible from .NET, but what if your problem is slightly different? We have many customers who need to use Java from legacy applications written in VB6 or from custom COM applications. Eventually, they want to move forward to VB.NET, but they still need to support the old applications.
JuggerNET offers a great solution for this problem. You can optionally turn on COM support when you're generating your .NET proxy classes and the code generator will add a number of options to the generated code. These options (.NET attributes) allow the registration of your assembly as a COM type library. Once this is achieved, all your COM clients (such as VB6 applications or Excel) can access the original Java types in an easy manner.
What do I need to do to support this use case?
There are several things you have to do:
- Read up on strongly named assemblies.
You will have to generate and deploy strongly named assemblies for the COM interoperability to work well. We have an FAQ on this topic, but you might also want to search for some additional information. If you don't already have a key file you will need to generate one.
- Read up on type library registration.
Once you have created strongly named assemblies, you will need to register them with the COM infrastructure. This involves using the regasm tool from Microsoft's .NET framework.
- Find out whether you have .NET runtime version requirements.
Older versions of Excel might only support .NET 1.1 and if .NET 2.0 or later is installed, the integrated solution might not work unless you take some configuration steps.
- Consider generating different assemblies for the .NET use case and the COM/VB6 use case.
The code generator has several options that make your life much easier on the COM side, but using these options does not necessarily yield optimal results for the .NET use case.
- Analyze your problem to see whether you might wish to provide some utility Java types to make usage of the underlying Java types easier when taking COM's requirements into account.
Once you've completed your investigations, here's what you need to do:
- Open the code generator's Properties dialog and make the following selections:
- COM Interoperability
Check Convert static members to instance members
Check Generate AutoDual attribute
Check Generate Guids (generate a GUID Seed once the button is enabled)
- .NET Assembly
Check Generate "AssemblyInfo.cs"
Check CLS Compliant
Enter a valid version number (important for strong names)
Enter a valid key file (copy it into the output directory and use the filename here)
Check Use strongly named runtime
Choose the proper.NET framework to use.
- COM Interoperability
- Generate the code and build the assembly, using the desired version of .NET.
- Copy the built assembly and the strongly named runtime (netrtsn.dll) to your test/deployment directory.
- Register them using the proper version of the regasm tool, for example:
regasm c:\myapp\bin\myunit.dll /v /u
regasm c:\myapp\bin\netrtsn.dll /v /u
regasm c:\myapp\bin\netrtsn.dll /v /t:netrtsn.tlb /codebase
regasm c:\myapp\bin\myunit.dll /v /t:myunit.tlb /codebase
You will now have two type libraries (.tlb files) that you can use from COM clients like VB6, Excel, etc.
- Taking Excel 2003 as an example, browse for the two type libraries and import them into your spread sheet via the "References" menuitem.
- Create a macro that uses types from the two libraries, for example:
Sub Load() On Error GoTo Handler Dim loader As JvmLoader Dim factory As JvmLoaderFactory Set factory = New JvmLoaderFactory Set loader = factory.GetJvmLoaderWithTracing(TraceFacility_TraceAll, TraceLevel_TraceVerbose) loader.TraceFile = "c:\\temp\\excel.log" loader.COMExceptionMessages = True loader.JvmPath = "C:\\Java\\j2sdk1.4.2_08\\jre\\bin\\client\\jvm.dll" loader.Load_2 (True) Dim tbl As test.Hashtable Set tbl = New test.Hashtable tbl.Get ("test") Call tbl.Put("test", "Value") Dim str As String str = tbl.ToString Exit Sub Handler: Dim msg As String Dim tp As String Dim ceh As COMErrorHelper Set ceh = New COMErrorHelper msg = ceh.Message tp = ceh.Type End Sub
While the above snippet might not represent the most meaningful application, it demonstrates several coding guidelines for VB6 client applications:
- Use the COMExceptionMessages option to maintain Java exception information in the COMErrorHelper utility class.
- Use trace files and more verbose logging during debugging.
- Handle errors, don't let them fall through and create an Automation Error.