Java - jni4net Bridge - Развертывание Jar с зависимостями dll

Я создаю приложение, использующее jni4net и несколько библиотек DLL, предоставленных нашим поставщиком (то есть я не контролирую библиотеки DLL).

При разработке программы в моей IDE (Eclipse) я просто помещал jni4net jar и связанные dll в папку проекта рабочей области.

[каталог проекта в IDE][1]

Программа отлично работает в среде IDE:

fs() throws IOException {

    Bridge.setVerbose(true);

    Bridge.init();

    Bridge.LoadAndRegisterAssemblyFrom(new java.io.File("Kratos_3.j4n.dll"));

    Bridge.LoadAndRegisterAssemblyFrom(new java.io.File("Kratos_3.dll"));

    fsod = new FactSetOnDemand();
}

выход:

> loading core from C:\Users\therka\workspace - Copy\instHolders\jni4net.n-0.8.3.0.dll
loading jni4net.n-0.8.3.0, Version=0.8.3.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxx from C:\Users\therka\workspace - Copy\instHolders\jni4net.n-0.8.3.0.dll
loaded jni4net.n-0.8.3.0, Version=0.8.3.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxx from C:\Users\therka\workspace - Copy\instHolders\jni4net.n-0.8.3.0.dll
Initialized jni4net core
core loaded from C:\Users\therka\workspace - Copy\instHolders\jni4net.n-0.8.3.0.dll
loading Kratos_3.j4n, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null from C:\Users\therka\workspace - Copy\instHolders\Kratos_3.j4n.dll
loaded Kratos_3.j4n, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null from C:\Users\therka\workspace - Copy\instHolders\Kratos_3.j4n.dll
loading Kratos_3, Version=3.5.0.0, Culture=neutral, PublicKeyToken=null from C:\Users\therka\workspace - Copy\instHolders\Kratos_3.dll
loaded Kratos_3, Version=3.5.0.0, Culture=neutral, PublicKeyToken=null from C:\Users\therka\workspace - Copy\instHolders\Kratos_3.dll

Теперь, когда я экспортирую из IDE в работающий JAR, я выбираю опцию "Копировать обязательные библиотеки в подпапку рядом с сгенерированным JAR". В каталоге, где сейчас находится jar, я размещаю все библиотеки и библиотеки DLL и запускаю его из командной строки.

> C:\instHolder>java -jar instHolder.jar
09-29-17 (03:42:12 PM): 317 clients retreived...
09-29-17 (03:42:12 PM): Confirming JVM version: 64
09-29-17 (03:42:12 PM): Java Version confirmation: 1.8.0_144
09-29-17 (03:42:12 PM): setting verbose
loading core from C:\instHolder\instHolder_lib\jni4net.n-0.8.3.0.dll
loading jni4net.n-0.8.3.0, Version=0.8.3.0, Culture=neutral, PublicKeyToken=xxxxxxxxxx
from C:\instHolder\instHolder_lib\jni4net.n-0.8.3.0.dll
loaded jni4net.n-0.8.3.0, Version=0.8.3.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxfrom C:\instHolder\instHolder_lib\jni4net.n-0.8.3.0.dll
Initialized jni4net core
core loaded from C:\instHolder\instHolder_lib\jni4net.n-0.8.3.0.dll
09-29-17 (03:42:13 PM): setting j4n
loading Kratos_3.j4n, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null from C:\instHolder\Kratos_3.j4n.dll
loaded Kratos_3.j4n, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null from C:\instHolder\Kratos_3.j4n.dll
09-29-17 (03:42:13 PM): setting 3
loading Kratos_3, Version=3.5.0.0, Culture=neutral, PublicKeyToken=null from C:\instHolder\Kratos_3.dll
loaded Kratos_3, Version=3.5.0.0, Culture=neutral, PublicKeyToken=null from C:\instHolder\Kratos_3.dll
09-29-17 (03:42:13 PM): Press Enter key to continue onto FSOD...
Exception in thread "main" java.lang.UnsatisfiedLinkError: kratos_3.runtimeplatform.FactSetOnDemand.__ctorFactSetOnDemand0(Lnet/sf/jni4net/inj/IClrProxy;)V
        at kratos_3.runtimeplatform.FactSetOnDemand.__ctorFactSetOnDemand0(Native Method)
        at kratos_3.runtimeplatform.FactSetOnDemand.<init>(FactSetOnDemand.java:25)
        at instHolders.fs.<init>(fs.java:46)
        at instHolders.init.main(init.java:44)

Сбой программы при создании нового объекта FactSetOnDemand (последняя строка в примере кода выше)

Я также подал библиотеки и библиотеки в аргументы командной строки и получил ту же ошибку

java -jar instHolder.jar -Dfile.encoding=Cp1252 -classpath""C:\instHolders\bin;C:\Users\therka\Desktop\JavaAPIs\SQLServer\jtds-1.3.1.jar;C:\Users\therka\Desktop\JavaAPIs\Apache\Commons\commons-net-3.3.jar;C:\Users\therka\Desktop\JavaAPIs\commons-lang3-3.4-bin\commons-lang3-3.4\commons-lang3-3.4.jar;C:\Users\therka\Desktop\JavaAPIs\Apache\IO\commons-io-2.4.jar;C:\Users\therka\Desktop\JavaAPIs\MySQL\mysql-connector-java-5.1.30.jar;C:\instHolders\jni4net.j-0.8.3.0.jar;C:\instHolders\Kratos_3.j4n.jar;C:\instHolder\Kratos_3.dll;C:\instHolder\Kratos_3.j4n.dll;C:\instHolder\jni4net.n-0.8.3.0.dll"" instHolders.init

В конечном итоге это приводит к тому же неудовлетворенному линкеру.

Может ли кто-нибудь указать мне правильное направление в отношении моей проблемы? Я уверен, что это связано с моими параметрами экспорта и, в конечном счете, с моим макетом каталога

Большое спасибо!

РЕДАКТИРОВАТЬ:

Все еще неспособный заставить это работать после того, как я ударился головой о стену, я добавил монитор процесса в среду IDE и командную строку.jar - из этого я смог получить аргументы командной строки, которые оба используют (см. Ниже).

COMMAND LINE ARGUMENTS-Parent PID: 10988, Command line: java  -jar instHolder.jar -Dfile.encoding=Cp1252 -classpath "C:\instHolders\bin;C:\Users\therka\Desktop\Java APIs\SQL Server\jtds-1.3.1.jar;C:\Users\therka\Desktop\Java APIs\Apache\Commons\commons-net-3.3.jar;C:\Users\therka\Desktop\Java APIs\commons-lang3-3.4-bin\commons-lang3-3.4\commons-lang3-3.4.jar;C:\Users\therka\Desktop\Java APIs\Apache\IO\commons-io-2.4.jar;C:\Users\therka\Desktop\Java APIs\MySQL\mysql-connector-java-5.1.30.jar;C:\instHolders\jni4net.j-0.8.3.0.jar;C:\instHolders\Kratos_3.j4n.jar" instHolders.init, Current directory: C:\instHolder\, Environment: 

=C:=C:\instHolder

=ExitCode=00000001

ALLUSERSPROFILE=C:\ProgramData

APPDATA=C:\Users\therka\AppData\Roaming

asl.log=Destination=file

CommonProgramFiles=C:\Program Files\Common Files

CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files

CommonProgramW6432=C:\Program Files\Common Files

COMPUTERNAME=xxxxxxxxxxx 

ComSpec=C:\Windows\system32\cmd.exe

FP_NO_HOST_CHECK=NO

HOMEDRIVE=P:

HOMEPATH=\

HOMESHARE=\\xxxxx-fp\data\Users\xxxxx

LOCALAPPDATA=C:\Users\therka\AppData\Local

LOGONSERVER=\\xxxxx

NUMBER_OF_PROCESSORS=4

OS=Windows_NT

Path=C:\ProgramData\Oracle\Java\javapath;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\oracle\product\10.2.0\client_1\bin;C:\Program Files (x86)\Sybase\Shared\PowerBuilder\;C:\Program Files (x86)\Sybase\Shared\PowerBuilder\;C:\Program Files\Java\jre7\bin\javaw.exe

PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

PROCESSOR_ARCHITECTURE=AMD64

PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 58 Stepping 9, GenuineIntel

PROCESSOR_LEVEL=6

PROCESSOR_REVISION=3a09

ProgramData=C:\ProgramData

ProgramFiles=C:\Program Files

ProgramFiles(x86)=C:\Program Files (x86)

ProgramW6432=C:\Program Files

PROMPT=$P$G

PSModulePath=C:\Windows\system32\WindowsPowerShell\v1.0\Modules\

PUBLIC=C:\Users\Public

SESSIONNAME=Console

SystemDrive=C:

SystemRoot=C:\Windows

TEMP=C:\Users\xxxxx\AppData\Local\Temp

TMP=C:\Users\xxxxx\AppData\Local\Temp

USERDNSDOMAIN=xxxxxxxxxxx .xxxxxxxxxxx 

USERDOMAIN=xxxxxxxxxxx 

USERNAME=xxxxx

USERPROFILE=C:\Users\xxxxx

windir=C:\Windows

IDE

"IDE ARGUMENTS - Parent PID: 9696, Command line: ""C:\Program Files\Java\jre1.8.0_141\bin\javaw.exe"" -Dfile.encoding=Cp1252 -classpath ""C:\Users\xxxxx\workspace - Copy\instHolders\bin;C:\Users\xxxxx\Desktop\Java APIs\SQL Server\jtds-1.3.1.jar;C:\Users\xxxxx\Desktop\Java APIs\Apache\Commons\commons-net-3.3.jar;C:\Users\xxxxx\Desktop\Java APIs\commons-lang3-3.4-bin\commons-lang3-3.4\commons-lang3-3.4.jar;C:\Users\xxxxx\Desktop\Java APIs\Apache\IO\commons-io-2.4.jar;C:\Users\xxxxx\Desktop\Java APIs\MySQL\mysql-connector-java-5.1.30.jar;C:\Users\xxxxx\workspace - Copy\instHolders\jni4net.j-0.8.3.0.jar;C:\Users\xxxxx\workspace - Copy\instHolders\Kratos_3.j4n.jar"" instHolders.init ""-Djava.library.path=c:\instHolder"", Current directory: C:\Users\xxxxx\workspace - Copy\instHolders\, Environment: 

ALLUSERSPROFILE=C:\ProgramData

APPDATA=C:\Users\xxxxx\AppData\Roaming

asl.log=Destination=file

CommonProgramFiles=C:\Program Files\Common Files

CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files

CommonProgramW6432=C:\Program Files\Common Files

COMPUTERNAME=xxxxxxxxxxx 

ComSpec=C:\Windows\system32\cmd.exe

FP_NO_HOST_CHECK=NO

HOMEDRIVE=P:

HOMEPATH=\

HOMESHARE=\\xxxxx-fp\data\Users\xxxxx

LOCALAPPDATA=C:\Users\xxxxx\AppData\Local

LOGONSERVER=\\xxxxx

NUMBER_OF_PROCESSORS=4

OS=Windows_NT

Path=C:/Program Files/Java/jre1.8.0_144/bin/server;C:/Program Files/Java/jre1.8.0_144/bin;C:/Program Files/Java/jre1.8.0_144/lib/amd64;C:\ProgramData\Oracle\Java\javapath;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\oracle\product\10.2.0\client_1\bin;C:\Program Files (x86)\Sybase\Shared\PowerBuilder\;C:\program files\java\jdk1.8.0_141\bin;C:\Program Files (x86)\Sybase\Shared\PowerBuilder\;C:\Program Files\Java\jre7\bin\javaw.exe;C:\Windows\system32;

PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

PROCESSOR_ARCHITECTURE=AMD64

PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 58 Stepping 9, GenuineIntel

PROCESSOR_LEVEL=6

PROCESSOR_REVISION=3a09

ProgramData=C:\ProgramData

ProgramFiles=C:\Program Files

ProgramFiles(x86)=C:\Program Files (x86)

ProgramW6432=C:\Program Files

PSModulePath=C:\Windows\system32\WindowsPowerShell\v1.0\Modules\

PUBLIC=C:\Users\Public

SESSIONNAME=Console

SystemDrive=C:

SystemRoot=C:\Windows

TEMP=C:\Users\xxxxx\AppData\Local\Temp

TMP=C:\Users\xxxxx\AppData\Local\Temp

USERDNSDOMAIN=xxxxxxxxxxx 

USERDOMAIN=xxxxxxxxxxx 

USERNAME=xxxxx

USERPROFILE=C:\Users\xxxxx

windir=C:\Windows"

Также из монитора процесса я вижу, что основная проблема возникает, когда.jar распаковывает dll в классы и затем использует FactSetOnDemand.class.

Вывод Process Montiro для IDE Вывод монитора процессов Вы можете видеть, что это работает успешно и создает необходимые классы.

Вывод монитора процесса для запускаемой.jar командной строки Вывод монитора процесса Не удается создать классы.

1 ответ

Решение

После недели бездействия я смог решить свою проблему с помощью разработчика вендора (спасибо Адриан!).

В конечном счете моя проблема была комбинацией факторов:

  1. Параметры экспорта, используемые при создании исполняемого файла.jar из моей IDE
  2. Макет папки развернутого запускаемого файла.jar
  3. пути, используемые в моем коде

Сначала я неправильно экспортировал свой код с опцией "Копировать необходимые библиотеки в подпапку рядом с сгенерированным.jar". Правильным вариантом было "упаковать библиотеки в сгенерированный файл.jar" с помощью запускаемого файла.jar.

Во-вторых, я создал папку и экспортировал в нее исполняемый файл.jar. В этой папке я создал подпапку с именем lib (dosnt вещество), которая содержит необходимые DLL-файлы для запуска программы.

В-третьих, я изменил свой код следующим образом:

    Bridge.setVerbose(true);

    Bridge.init(new File("C:\\Users\\therka\\Desktop\\jar\\lib\\jni4net.n.w64.v40-0.8.3.0.dll"));

    Bridge.LoadAndRegisterAssemblyFrom(new java.io.File("C:\\Users\\therka\\Desktop\\jar\\lib\\Kratos_3.j4n.dll"));

    fsod = new FactSetOnDemand();

Пути, указанные в jni4net Bridge.init & Bridge.LoadAndRegisterAssembly, должны указывать на папку / lib /, содержащую DLL-файлы. Ранее я не указывал каталоги, и в результате.dll не были найдены (вызывая unsatisifedLinkerror).

Теперь все, что вам нужно, это открыть командную строку, перейдите в каталог с каталогом.jar и -java -jar - исполняемый файл.

Надеюсь, это спасет кого-то от головной боли, через которую мне пришлось пройти.

Другие вопросы по тегам