Как сделать файл JAR, который включает файлы DLL? - PullRequest
64 голосов
/ 23 октября 2009

Я купил стороннюю библиотеку Java, которая включает в себя файл JAR и два файла DLL. Я написал свою собственную программу Java, которая вызывает сторонний файл JAR. Теперь мой вопрос как мне упаковать весь мой код в один файл JAR, который включает весь мой код и сторонние JAR и DLL?

Я знаю, SWT такой случай. swt.jar включает файлы dll, но я не знаю, как это сделать и как заставить его работать должным образом.

Ответы [ 2 ]

76 голосов
/ 23 октября 2009

Просто упакуйте его где угодно в банку. Однако следует помнить одну вещь: перед тем, как вы сможете использовать библиотеки DLL, вам нужно извлечь их из JAR-файла и выгрузить их куда-нибудь на жесткий диск, иначе вы не сможете загрузить эти

Так что в основном - я сделал проект JNI для клиента, где я буду использовать такой кувшин, упакованный во время войны. Однако - перед запуском любых собственных методов я бы взял DLL в качестве ресурса и записал ее на диск во временную директорию. Затем я запускаю обычный код инициализации, в котором моя DLL установлена ​​в то же место, в котором я только что написал DLL для

О, и на всякий случай: нет ничего особенного в упаковке dll или любого другого файла в jar. Это как упаковка вещей в zip

Вот код, который я только что выкопал

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
}
6 голосов
/ 09 марта 2010

Используйте http://www.jdotsoft.com/JarClassLoader.php, который может загружать DLL и JAR из другого JAR с неограниченным вложением. Например, DLL может быть в JAR, который находится в другом корневом JAR. Все библиотеки DLL и файлы JAR загружаются так, как они находятся в пути к классам или по пути к библиотеке.

...