sigar-amd64-winnt.dll … can't reference it or

2020-07-21 00:33发布

问题:

(It might be an obvious mistake I'm making, but I couldn't get it to work after 6 hours now.)

I'm trying to get CPU information using the sigar.jar in my eclipse project (just testing the sigar API for now).

It runs in eclipse without problems:

  • what made it work in eclipse was to put the dll in the same folder as the sigar.jar
  • I tested that adding a path to the dll as the "native code property" in the build path config dialog has no effect.
  • Adding vm arguments in the run configuration also has no effect.
  • I tested putting 2 fake paths in those 2 places and as long as I have the dll in the same folder as the sigar.jar... it runs well in eclipse.

The problem is when I try to export a runnable .jar file for my project. I tried 2 things:

  • I modified the MANIFEST.MF file with Bundle-NativeCode: libs/sigar-amd64-winnt.dll (I'm assuming here the path is relative to the project folder) --> no success:
 main starting!! no sigar-amd64-winnt.dll in java.library.path
 org.hyperic.sigar.SigarException: no sigar-amd64-winnt.dll in
 java.library.path
         at org.hyperic.sigar.Sigar.loadLibrary(Sigar.java:172)
         at org.hyperic.sigar.Sigar.<clinit>(Sigar.java:100)
         at CpuData.main(CpuData.java:59) 
 cpudata(sigar s) starting!!! cpuInfo() starting!!! 
 Exception in thread
 "main" java.lang.UnsatisfiedLinkError:
 org.hyperic.sigar.Sigar.getCpuInfoList()[Lorg/hyperic/sigar/C puInfo;
         at org.hyperic.sigar.Sigar.getCpuInfoList(Native Method)
         at CpuData.cpuInfo(CpuData.java:103)
         at CpuData.<init>(CpuData.java:29)
         at CpuData.main(CpuData.java:59)
  • Then I decided to put the .dll in the same folder as my project.jar, and used in the command line: java -Djava.library.path=./native/ -jar C:\cpu_usage_log\cpu3.jar (I'm assuming here the path is relative to the folder that contains the project.jar) ...but again no success:

Error: impossible to find or load the main class .library.path=..native

(I suspected that I should give a main class name as a second argument after the -Djava.library.path=./path/ but I can't find that supposed "main class" name, or any examples on the web that do specify such a class ...is it a main class from within the .dll?)

I don't really know what else to try at this point. I read those 2 solutions worked for others, and it makes it even more frustrating because I imagine it could something obvious that I missed or didn't understand when reading other posts and that I just can't find (it's the first time I deal with native dlls in a java project).

回答1:

For me it was always the best to modify the way how Java loads the library.

Usually you call System.loadLibrary("mylib"); which searches the library on the library path.

IMHO it is much better loading the library using it's absolute path. This allows you to implement a custom search logic in your program:

// Extends the name to mylib.so or mylib.dll
mylibname = System.mapLibraryName("mylib"); 

// Load the library via its absolute path
System.load(new File(path, mylibname).getAbsolutePath());

Note that each library can only be loaded once, therefore if you load the library as shown above, calls of System.loadLibrary("mylib"); afterwards will be ignored as the library is already loaded.