Как создать JAR-файл, содержащий DLL-файлы?
Вопрос
Я купил стороннюю библиотеку Java, которая включает в себя JAR-файл и два DLL-файла.Я написал свою собственную Java-программу, которая вызывает сторонний JAR-файл.Теперь мой вопрос заключается в следующем как я могу упаковать весь свой код в один JAR-файл, который включает весь мой код, а также сторонние JAR и библиотеки DLL?
Я знаю СВТ есть такой случай.Тот Самый swt.jar
включает dll-файлы, но я не знаю, как это сделать и как заставить его работать должным образом.
Решение
Просто упакуйте его в любое место в банке.Однако вы должны иметь в виду одну вещь - прежде чем вы сможете использовать библиотеки DLL, вам нужно фактически извлечь их из JAR и поместить куда-нибудь на жесткий диск, иначе вы не сможете их загрузить
Итак, в принципе - я сделал проект JNI для клиента, где я буду использовать такую банку, упакованную в war.Однако, прежде чем запускать какие-либо собственные методы, я бы получил DLL в качестве ресурса и записал ее на диск во временный каталог.Затем я бы запустил обычный код инициализации, где моя библиотека 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
}
Другие советы
Используйте http://www.jdotsoft.com/JarClassLoader.php , который может загружать библиотеки DLL. и JAR из другого JAR с неограниченным вложением. Например, DLL может быть в JAR, который находится в другом корневом JAR. Все библиотеки DLL и файлы JAR загружаются так, как они находятся в пути к классам или в пути к библиотеке.