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

时间:2021-09-04 22:20:59

I bought a third-party Java library which includes a JAR file and two DLL files. I wrote my own Java program which invoke the third-party JAR file. Now my question is how can I package all my code into a single JAR file which include all my code and the third-party JAR and DLLs?

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

I know SWT is such a case. The swt.jar includes dll files, but I don't know how to do this and how to make it work properly.

我知道SWT就是这样。swt。jar包含dll文件,但是我不知道如何做到这一点以及如何使它正常工作。

2 个解决方案

#1


71  

Just package it anywhere in the jar. One thing you have to keep in mind though - before you can use the DLLs you need to actually extract these from the JAR and dump these on the hard disk somewhere otherwise you won't be able to load these

只要把它装在罐子里的任何地方。但有一件事你必须记住——在你使用dll之前,你需要从JAR中提取这些并将它们转储到硬盘上,否则你将无法加载它们

So basically - I did JNI project for the client where I will use such jar packaged within the war. However - before running any native methods I would get the DLL as a resource and write it to the disc into temp directory. Then I would run regular initialization code where my DLL is set to the same location I just wrote DLL to

基本上,我为客户做了JNI项目,在那里我将使用在战争中打包的jar。然而,在运行任何本机方法之前,我将把DLL作为资源并将其写入到磁盘到临时目录中。然后我将运行常规的初始化代码,其中我的DLL被设置为我刚刚写入DLL的相同位置

Oh, and just in case: there's nothing special about packaging dll or any other file into jar. It's just like packaging stuff into zip

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

Here's some code I just digged out

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

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
}

#2


6  

Use http://www.jdotsoft.com/JarClassLoader.php which could load DLLs and JARs from another JAR with unlimited nesting. For example, DLL could be in JAR which is in another root JAR. All DLLs and JARs are loaded like they are in a classpath or library path.

使用http://www.jdotsoft.com/JarClassLoader.php,它可以从另一个JAR中加载dll和JAR,并具有无限制的嵌套。例如,DLL可以在JAR中,JAR在另一个根JAR中。所有dll和jar都被加载到类路径或库路径中。

#1


71  

Just package it anywhere in the jar. One thing you have to keep in mind though - before you can use the DLLs you need to actually extract these from the JAR and dump these on the hard disk somewhere otherwise you won't be able to load these

只要把它装在罐子里的任何地方。但有一件事你必须记住——在你使用dll之前,你需要从JAR中提取这些并将它们转储到硬盘上,否则你将无法加载它们

So basically - I did JNI project for the client where I will use such jar packaged within the war. However - before running any native methods I would get the DLL as a resource and write it to the disc into temp directory. Then I would run regular initialization code where my DLL is set to the same location I just wrote DLL to

基本上,我为客户做了JNI项目,在那里我将使用在战争中打包的jar。然而,在运行任何本机方法之前,我将把DLL作为资源并将其写入到磁盘到临时目录中。然后我将运行常规的初始化代码,其中我的DLL被设置为我刚刚写入DLL的相同位置

Oh, and just in case: there's nothing special about packaging dll or any other file into jar. It's just like packaging stuff into zip

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

Here's some code I just digged out

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

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
}

#2


6  

Use http://www.jdotsoft.com/JarClassLoader.php which could load DLLs and JARs from another JAR with unlimited nesting. For example, DLL could be in JAR which is in another root JAR. All DLLs and JARs are loaded like they are in a classpath or library path.

使用http://www.jdotsoft.com/JarClassLoader.php,它可以从另一个JAR中加载dll和JAR,并具有无限制的嵌套。例如,DLL可以在JAR中,JAR在另一个根JAR中。所有dll和jar都被加载到类路径或库路径中。