【问题标题】:SIGAR API not working after packaging to jar/exe打包到 jar/exe 后 SIGAR API 不起作用
【发布时间】:2014-10-31 21:47:38
【问题描述】:

我正在尝试使用 SIGAR API 收集系统信息。在我的库中包含 sigar.jar 后,Netbeans 给出了找不到 sigar-amd64-winnt.dll 的错误。将该文件添加到库后,它运行良好。

现在我需要创建一个可执行的 jar,所以我使用 NetBeans 来构建我的项目。 Netbeans 自动删除了 .dll 文件,在我手动将其复制回 dist 文件夹后,我的程序就可以工作了。我现在正在尝试使用 Launch4j 创建一个 exe 文件。当我运行它时,抛出一个java异常,可能是因为Launch4j删除了.dll文件。

如何确保 Launch4j 将其包含在 exe 文件中?

我浏览了许多关于 SO 的答案,但无法解决我的问题。下面提到了一些-

sigar-amd64-winnt.dll ... can't reference it or bundle it with .jar

How to include SIGAR API in Java Project

任何帮助将不胜感激..

编辑

当我测试运行 exe 包装器时,Launch4j 在其日志中给出以下异常-

Exception in thread "main" java.lang.NoClassDefFoundError: org/hyperic/sigar/SigarException
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.getMethod0(Unknown Source)
at java.lang.Class.getMethod(Unknown Source)
at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.hyperic.sigar.SigarException
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 6 more

【问题讨论】:

    标签: java jar exe launch4j sigar


    【解决方案1】:

    如果是 Windows,则指定 .dll 路径,如果是 Ubuntu,则指定 .so。 例如:

    java -Djava.library.path=".:/home/ubuntu/AssetManager/libsigar-amd64-linux.so" -jar aa.jar
    

    这里.:/home/ubuntu/AssetManager/libsigar-amd64-linux.so是Sigar API .so文件的路径

    aa.jar 是 Eclipse 创建的实际可运行 jar

    【讨论】:

      【解决方案2】:

      好的,所以为了保证程序能正常运行,我们需要把打包好的exe中的本地.dll库复制到电脑上(把需要的dll库放到src文件夹中),然后作为库加载.

      这就是最终对我有用的方法-

      int arch = Integer.parseInt(System.getProperty("sun.arch.data.model"));
          InputStream is = null;
          if(arch==32)
              is = Logger.class.getClass().getResourceAsStream("/sigar-x86-winnt.dll");
          else if(arch==64)
              is = Logger.class.getClass().getResourceAsStream("/sigar-amd64-winnt.dll");
      
          Path sigar = Files.createTempFile("sigar_lib", ".dll");
      
          try (FileOutputStream out = new FileOutputStream(sigar.toFile())) 
                  {
                      byte[] buffer = new byte[1024];
                      int len;
                      while ((len = is.read(buffer)) != -1) {
                          out.write(buffer, 0, len);
                      }
                  } 
                  catch (Exception e) {
      
              }
          System.load(sigar.toString());
      

      【讨论】:

      • 但是有个问题就是每次都会在temp文件夹里新建一个文件,如果你多次运行程序,C盘就会一天比一天满。 3 次运行 1Mb
      • sigar.deleteOnExit(); 将确保在 JVM 终止时删除该文件。
      猜你喜欢
      • 1970-01-01
      • 2018-03-05
      • 1970-01-01
      • 1970-01-01
      • 2014-09-10
      • 2015-02-21
      • 2015-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多