ActiveX client programming best practices
In general, the best way to access Java components is to use the Java language. It is recommended that you do as much programming as possible in the Java language and use a small simple interface between your COM Automation container (for example, Visual Basic) and the Java code. This interface avoids any overhead and performance problems that can occur when moving across the interface.
- Visual Basic guidelines
- Active Server Pages guidelines
- J2EE guidelines
Visual Basic guidelines
The following guidelines are intended to help optimize your use of the ActiveX to EJB bridge with Visual Basic...
- Launch the Visual Basic replication through the launchClientXJB.bat file. If you want to run your Visual Basic application through the Visual Basic debugger, run the Visual Basic integrated development environment (IDE) within the ActiveX to EJB bridge environment. After you create your Visual Basic project, you can launch it from a command line; for example, launchClientXJB MyApplication.vbp. You can also launch the Visual Basic application alone in the ActiveX to EJB environment, by changing the Visual Basic shortcut on the Windows Start menu so that the launchClientXJB.bat file precedes the call to the VB6.EXE file.
- Exit the Visual Basic IDE before debugging programs.
Because the Java virtual machine (JVM) code attaches to the running process, exit the Visual Basic editor before debugging your program. If you run the process, then exit your program within the Visual Basic IDE, the JVM code continues to run and you reattach the same JVM code when XJBInit() is called by the debugger. This causes problems if you try to update XJBInit() arguments (for example, classpath) because the changes are not be applied until you restart the Visual Basic program.
- Store the XJB.JClassFactory object globally.
Because you cannot unload or reinitialize the JVM code, cache the resulting XJB.JClassFactory object as a global variable. The overhead of treating this object as a global variable or passing a single reference around is much less than recreating a new XJB.JClassFactory object and calling the XJBInit() argument more than once.
CScript and Windows Scripting Host
The following guidelines intend to help optimize your use of the ActiveX to EJB bridge with CScript and Windows Scripting Host (WSH)...
- Launch in ActiveX to EJB environment.
Launch the VBScript files in the ActiveX to EJB bridge environment, to run VBScript files in .vbs files. Two common ways exist to launch your script...
Active Server Pages guidelines
The following guidelines intend to help optimize your use of the ActiveX to EJB bridge with Active Server Pages software...
- Use the ActiveX to EJB Helper functions from the Active Server Pages Application.
Because ASP code typically use VBScript, you can use the included helper functions in any VBScript environment with minor changes. For more information about these helper functions, see Helper functions for data type conversion. To run outside of the ASP environment, remove or change all references to the Server, Request, Response, Application and Session objects; for example, change Server.CreateObject to CreateObject.
- Set JRE path globally in system.
The XJB.JClassFactory object must be able to find the Java run time dynamic link library (DLL) when initializing. In Internet Information Server, you cannot specify a path for its processes independently; set the process paths in the system PATH variable. You can only have a single JVM version available on a machine using the ASP application. Also, remember that after you change the system PATH variable reboot the Internet Information Server machine so that the Internet Information Server can see the change.
- Set the system TEMP environment variable.
If the system TEMP environment variable is not set, Internet Information Server stores all temporary files in the WINNT directory, which is usually not desired.
- Use high isolation or an isolated process.
When using the ActiveX to Java bridge with Active Server Pages software, creating your web application (.war) in its own process is recommended. You can only load one JVM instruction in a single process and if you want to have more than one application running with different JVM environment options (for example, different classpaths), then you need to have separate processes.
- Use the Application Unload option.
When debugging your application, use Unload when viewing your ASP application properties in the Internet Information Server administration console to unload the process from memory and thereby unload the JVM code.
- Run one process per application.
Use only one ASP application per J2EE application or JVM environment, in your ASP environment. If you need separate class paths or JVM settings, you need separate ASP applications (virtual directories with high isolation or an isolated process).
- Store the XJB.JClassFactory object in application scope.
Because of the one-to-one relationship required between a JVM instruction and a process, and because the JVM code can never detach or shut down from a process independently, cache the XJB.JClassFactory object at application scope and call the XJBInit() method only once.
Because the ActiveX to EJB bridge employs a free-threaded marshaler, take advantage of the multi-threaded nature of Internet Information Server and the ASP environment. If you choose to reinitialize the XJB.JClassFactory object at Page scope (local variables), then the XJBInit() method can only initialize your local XJB.JClassFactory variable. It is more efficient to use the XJBInit() method once.
- Use VBScript conversion functions.
Because VBScript code only supports variant data types, use the CStr(), CByte(), CBool(), CCur(), CInt(), Clng(), CSng() and CDbl() functions to tell the activeX to EJB bridge which data type you are using; for example oMyObject.Foo(CDbl(1.234)).
The following guidelines are intended to help optimize your use of the ActiveX to EJB bridge with the J2EE environment;
- Store client container objects globally.
Because you can only have one JVM instruction per process, and a single J2EE client container (com.ibm.websphere.client.applicationclient.launchClient) per JVM instruction, initialize your J2EE client container only once and reuse it. For ASP applications, store the J2EE client container in an application level variable and initialize it only once (either on the Application_OnStart() event in the global.asa file or by checking to see if it IsEmpty()).
A side effect to storing the client container object globally is that you cannot change the client container parameters without destroying the object and creating a new one. These parameters include the EAR file, BootstrapHost, class path, and so on. If you run a Visual Basic application and want to change the client container parameters, end the application and restart it. If you run an Active Server Pages application, first unload the application from Internet Information Server (see "Use the Application Unload Button" under Active Server Pages guidelines). Then load the Active Server Pages application with the different client container parameters. The parameters set the first time the Active Server Pages application loads. Since the client container is stored on the Internet Information Server, all the browser clients share the parameters using the Active Server Pages application. This behavior is normal for Active Server Pages code, but can be confusing when you try to run to different WASs using the same Active Server Pages application, which is not supported.
- Reuse custom temporary directory for EAR file extraction.
By default, the client container launches and extracts the application .ear file to your temp directory and then sets up the thread class loader to use the extracted EAR file directory and the JAR files included in the client JAR manifest. This process is time consuming and because of some limitations with JVM shutdown through JNI and file locking, these files are never cleaned up.
Specifically, each time the client container launch() method is called, it extracts the EAR file to a random directory name in your temporary directory on your hard drive. The current Java thread class loader is then changed to point to this extracted directory which in turn locks the files within. In a normal J2EE Java client, these files automatically clean up after the application exits. This cleanup occurs when the client container shutdown hook is called (which never happens in the ActiveX to EJB bridge), which leaves the temporary directory there.
To avoid these problems, you can specify a directory to extract the EAR file by setting the com.ibm.websphere.client.applicationclient.archivedir Java system property before calling the client container launch() method. If the directory does not exist or is empty, you extract the EAR file normaly. If the EAR file was previously extracted, the directory is reused. This feature is particularly important for server processes (for example, ASP), which can stop and restart, potentially calling the launchClient() method several times.
If you need to update your EAR file, delete the temporary directory first. The next time you create the client container object, it extracts the new EAR file to the temporary directory. If you do not delete the temporary directory or change the system property value to point to a different temporary directory, the client container reuses the currently extracted EAR file, and does not use your changed EAR file.
When specifying the com.ibm.websphere.client.applicationclient.archivedir property, ensure that the directory you specify is unique for each EAR file you use. For example, do not point MyEar1.ear and MyEar2.ear files to the same directory.
If you choose not to use this system property, go regularly to your Windows temp directory and delete the WSTMP* subdirectories. Over a relatively short period of time, these subdirectories can waste a significant amount of space on the hard drive.