views:

1185

answers:

3

Hi, I need to include native lib (jnotify but I think that it does't matter) to my jar. I wont to do it with NetBeans.

I added Bundle-NativeCode: /lib/jnotify.dll; osname=win32 to my manifest.mf file and added jnotify.dll to projektHome\src\lib\ folder. But unfortunately NetBeans is overidning manifest.mf file.

How can I fixed? Can I do this using only NetBeans? Is it line 'Bundle-NativeCode: /lib/jnotify.dll; osname=win32 correct? I also heard I should put dlls hash in manifest.mf and sign my jar. Is that true?

+2  A: 

I don't think the Java executable supports Bundle-NativeCode. I'm pretty sure that is an OSGi attribute. The list of supported attributes is defined in the JAR File Specification.

Outside frameworks that provide it, there is no built-in support for bundling native libraries inside JAR files. If I recall correctly, it is possible to extract the file to a temporary location and load it manually.

McDowell
Thanks for answer. I think I will try wrap it into exe. I could make simple bat batch file but I prefer having only one file. But I haven't found suitable tool yet. I tried Lunch4j but it doesn't have option for adding native libs.
Maciek Sawicki
+2  A: 

I ran into this problem when trying to hook a Windows shutdown event when the program runs on that OS. The solution I ended up using was essentially McDowell's - adding the DLL to the jar file and extracting it to a temporary location when the program starts. If it fits your program, you can leave the DLL in a more permanent place and then reference it on subsequent program startups. My application was used in an environment where the users might intentionally delete files they shouldn't, so I had to extract the DLL on every run. However, it hasn't resulted in any performance hit of significance.

spork
have You any code snippet for doing this?
Maciek Sawicki
+3  A: 

Sometimes i found the problem is not the Java way of loading native libs, but the 3rd party library that needs that native code.

The problem is that the 3rd party libs will do at some point (normally very early in initialization)

System.loadLibrary("native.dll");

And if native.dll is not at the appropiated place it throws an Error.

If you have access to the java source of the 3rd party library it might be easy to patch that code and you could easily extract your dll from the JAR and run System.load before using the 3rd party lib.

Update I had a look into JNotify sources. It is exactly what i said:

public class JNotify_win32
{
    static
    {
     System.loadLibrary("jnotify"); /* *** */
     int res = nativeInit();
     if (res != 0)
     {
      throw new RuntimeException("Error initialiing native library. (#" + res + ")");
     }
    }

Take line *** out or surround with try-catch, load with System.load() and you are done.

PeterMmm
good point, but I think it's not a problem in my case: "To use JNotify, you need to have the native library (jnotify.dll or jnotify.so) in your java.library.path. to do that, you need to use the -Djava.library.path prameter when you run the java application. for example: java -cp jnotify.jar -Djava.library.path=."
Maciek Sawicki
Thanks a lot. You are 100% right. I was thinking about creating bat and thought that changing dll's location should be a problem. When I read your answer I thought "I checked I can do every thing with my del" but I was checking completely different thing. I must be tired.
Maciek Sawicki