Archived Forum Post

Index of archived forum posts

Question:

Using Chilkat in a Windows Service in a Java PlayFramework Application

Jul 09 '15 at 08:30

I’m the developer in charge for the integration in one of our web projects and i’m facing problems when loading the DLL: i’m getting a “java.lang.UnsatisfiedLinkError has been caught, com.chilkatsoft.chilkatJNI.new_CkUnixCompress()” exception.

Please note that i can succesfully use the CkUnixCompress in a normal java class when i run a main method from the command line, the problem seems to be when i try to use the class from inside the PlayFramework. I can’t find a way to make the framework load/find the DLL.

I tried to pass a –Djava.library.path directive, i tried to directly load the dll from inside the application, and so on, but no success…

Did you have any previous experience with the PlayFramework (v1.3.0) before?

I can provide you an example project to reproduce the issue if you want.

Here are some tech details:


Answer

We finally found a solution that works for us:

as mentioned before, we use an external jar that statically load the dll files listed in a property file.

The jar contains just one class named JniBootstrap with a static block like this:

static
{
       Properties prop = getProps(); // read a property file with getResourceAsStream
       for (int i = 0; i < 1000; i++)
       {
           String dll = prop.getProperty("jni." + i);
           if (dll != null && !(dll.trim().length() == 0))
             load(dll); // load the dll with System.load(dll)
       }
}

In our webapp we just do

Class.forName(“mypackage.JniBootstrap”);

The problem was that when run as a windows service, the webapp uses a different ClassLoader, making it impossible to find the property file.

So the fix was change the getProps() method and make it try different classloaders, something like this:

InputStream in;

in = ClassLoader.getSystemClassLoader().getResourceAsStream(CONFIG_FILENAME); // works when developing in Eclipse

if (in == null)
{
    in = JniBootstrap.class.getResourceAsStream(CONFIG_FILENAME);
}

if (in == null)
{
    in = Thread.currentThread().getContextClassLoader().getResourceAsStream(CONFIG_FILENAME); // works when webapp is deployed as a windows service
}

I doubt there are others using this combination of old PlayFramework + Chilkat lib + windows service, anyway this works in our environment and maybe could be useful in the future.