如何制作包含DLL文件的JAR文件?

Jus*_*ner 66 java dll swt packaging jar

我买了第三方Java库,其中包含一个JAR文件和两个DLL文件.我编写了自己的Java程序来调用第三方JAR文件.现在我的问题是如何将我的所有代码打包成一个包含我所有代码和第三方JAR和DLL的JAR文件?

我知道SWT就是这种情况.在swt.jar包括DLL文件,但我不知道如何做到这一点,以及如何使其正常工作.

Bos*_*one 78

只需将它打包在罐子里的任何地方.有一件事你必须记住 - 在你可以使用DLL之前,你需要从JAR中实际提取这些并将它们转储到某个地方的硬盘上,否则你将无法加载这些

所以基本上 - 我为客户做了JNI项目,我将在战争中使用这样的jar包装.但是 - 在运行任何本机方法之前,我会将DLL作为资源并将其写入光盘到temp目录.然后我会运行常规初始化代码,其中我的DLL设置为我刚刚写入DLL的相同位置

哦,以防万一:将dll或任何其他文件打包到jar中没有什么特别之处.就像把东西包装成拉链一样

这是我刚刚挖掘出来的一些代码

public class Foo {
private static final String LIB_BIN = "/lib-bin/";
private final static Log logger = LogFactory.getLog(ACWrapper.class);
private final static String ACWRAPPER = "acwrapper";
private final static String AAMAPI = "aamapi51";
private final static String LIBEAU = "libeay32";

static {
    logger.info("Loading DLL");
    try {
        System.loadLibrary(ACWRAPPER);
        logger.info("DLL is loaded from memory");
    } catch (UnsatisfiedLinkError e) {
        loadFromJar();
    }
}

/**
 * When packaged into JAR extracts DLLs, places these into
 */
private static void loadFromJar() {
    // we need to put both DLLs to temp dir
    String path = "AC_" + new Date().getTime();
    loadLib(path, ACWRAPPER);
    loadLib(path, AAMAPI);
    loadLib(path, LIBEAU);
}

/**
 * Puts library to temp dir and loads to memory
 */
private static void loadLib(String path, String name) {
    name = name + ".dll";
    try {
        // have to use a stream
        InputStream in = ACWrapper.class.getResourceAsStream(LIB_BIN + name);
        // always write to different location
        File fileOut = new File(System.getProperty("java.io.tmpdir") + "/" + path + LIB_BIN + name);
        logger.info("Writing dll to: " + fileOut.getAbsolutePath());
        OutputStream out = FileUtils.openOutputStream(fileOut);
        IOUtils.copy(in, out);
        in.close();
        out.close();
        System.load(fileOut.toString());
    } catch (Exception e) {
        throw new ACCoreException("Failed to load required DLL", e);
    }
}
    // blah-blah - more stuff
}
Run Code Online (Sandbox Code Playgroud)

  • 关于这种方法的注意事项 - 确保清理临时文件.如果每次重复使用相同的路径,请考虑如果多个应用程序使用您的JAR会发生什么(如果另一个应用程序已经锁定了临时文件,则会失败).请注意 - 有时单独部署JAR和DLL会更容易. (7认同)
  • 要记住一件事:我使用的是依赖于其他DLL的JNI DLL.我在jar中包含了所有DLL,并使用上面的代码解压缩.但我得到了java.lang.UnsatisfiedLinkError异常,说"找不到依赖库".问题是您必须按顺序调用DLL上的System.load(),以便首先加载相关的DLL. (7认同)

小智 6

使用http://www.jdotsoft.com/JarClassLoader.php可以从另一个具有无限嵌套的JAR加载DLL和JAR.例如,DLL可能位于另一个根JAR中的JAR中.所有DLL和JAR都像在类路径或库路径中一样加载.

  • 其他人注意:许可证是GPLv3,它大大限制了适用性. (28认同)
  • 另请注意:此类加载器将所有嵌套jar解压缩到一个临时目录中.所以它就像第一个答案一样.仅在需要时才解压缩本机库. (5认同)
  • 提供商业许可证. (2认同)