Writing Openwings components that use Native code
There are a couple of things to keep in mind if you want to
write Openwings components that use native code.
Where to put your library. When building up an installable
image, you should put your native libraries in the "lib" directory
of your component image, along with your Jar files containing
Java code.
How to load the native libraries in your code. There are
two slightly different ways to load native code in Java programs.
The first is through the method java.lang.System.loadLibrary(java.lang.String)
which is equivalent to java.lang.Runtime.getRuntime().loadLibrary(java.lang.String).
To quote from the javadoc, this method "loads the system library
specified by the libname argument. The manner in which a library
name is mapped to the actual system library is system dependent."
Practically speaking, it works like this: on Unix platforms,
the library must be named "lib<name>.so" where <name>
is the String passed to loadLibrary. This library must be found
in a directory specified in the LD_LIBRARY_PATH environment variable.
On Windows platforms, the library must be named "<name>.dll"
where <name> is the String passed to loadLibrary. This library
must be found in a directory specified in the PATH environment
variable.
So, if you want to call loadLibrary in your program, you would
have to make sure that the appropriate environment variable includes
a reference to the directory where your native library resides.
This does not mesh well with the Openwings installation model,
which tries to avoid having to set or modify environment variables.
Note: there may be some legacy programs that call loadLibrary
that cannot be changed. In this case, the Container Services reference
implementation does provide some help. Basically, processes that
are designated as standalone processes are started with a current
working directory equal to the "lib" directory under their installation.
For example, let's say the component "MyComponent" is installed
under "C:\openwings\MyComponent-1.0\", it's
"sharedContainerHint" flag in its
InstallableComponentDescriptor is set to "false", and there
is a file called "MyLibrary.dll" stored at "C:\openwings\MyComponent-1.0\lib".
When an instance of MyComponent is started, its CWD will be "C:\openwings\MyComponent-1.0\lib".
If the PATH environment variable includes ".", as it usually will,
"MyLibrary" may be loaded by the following line of code:
System.loadLibrary("MyLibrary");
This workaround only applies to standalone processes started
by the Container Manager, not the "owrun" tool.
The second approach to loading libraries is simpler and is the
preferred method. Use the method java.lang.System.load(java.lang.String)
(which is equivalent to java.lang.Runtime.getRuntime().load(java.lang.String)).
To quote from the javadoc, this method "loads a code file with
the specified filename from the local file system as a dynamic
library. The filename argument must be a complete pathname."
So, how do we determine the absolute filename to the library
of an installed component? The Install Service writes a series
of properties into the
InstallableComponentDescriptor for each installed component.
One of these
properties is called
"net.openwings.install.libDir", and this property refers to
the location on the computer where your component's "lib" directory
is located. Therefore, you could build the absolute filename for
your native library by concatenating the value of the "net.openwings.install.libDir"
property with the name of the library file.
This approach should work for all
processes started by the Container Manager and the
"owrun" tool.
An example of a component that uses native code is provided
under the demos folder where you have installed openwings. The
component is NativeDemo.jar. It was written with the second method
- where the load library was loaded with
java.lang.System.load("NativeDemo");
To execute this program use the Container Manager and see the
results in the log file.
You can find out how the Native Demo was created by perusing
the
JNI tutorial. Sun provides detailed
step-by-step instructions on how to integrate native code
with Java.