Просто упакуйте его в любом месте в банке. Одна вещь, которую вы должны иметь в виду: прежде чем вы сможете использовать библиотеки DLL, вам нужно извлечь их из JAR и выгрузить их на жесткий диск где-нибудь в другом месте, вы не сможете загрузить их
Так что в основном - Я сделал проект JNI для клиента, где я буду использовать такой банку, упакованную в течение войны. Однако - перед запуском каких-либо собственных методов я бы получил DLL в качестве ресурса и записал его на диск в каталог temp. Тогда я бы запускал обычный код инициализации, где моя DLL установлена в то же место, где я только что написал DLL:
О, и на всякий случай: нет ничего особенного в упаковке dll или любом другом файле в банку. Это так же, как упаковка материала в почтовый
Вот код, я просто вырыта
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
}
Предупреждение об этом подходе - убедитесь, что вы очищаете временные файлы. Если вы повторно используете один и тот же путь каждый раз, подумайте о том, что произойдет, если несколько приложений используют JAR (один будет терпеть неудачу, если у другого уже есть блокировка временного файла). Просто будьте осторожны - иногда проще развернуть JAR и DLL отдельно. –
Код может быть изменен для перезаписывания ранее установленного файла. В моем случае это было веб-приложение, которое не будет часто перерабатываться, но действительно, если вы просто скопируете код «как есть», вы получите новую копию DLL при каждом ее выполнении. – Bostone
Следует иметь в виду: I использует JNI DLL, которые зависят от других DLL. Я включил все библиотеки DLL внутри банки и использовал вышеприведенный код для распаковки. Но я получал исключения java.lang.UnsatisfiedLinkError, говорящие «Не могу найти зависимые библиотеки». Проблема в том, что вы должны вызывать System.load() в DLL, чтобы сначала загружать зависимые DLL. –