Eclipse RCP + Native Code
1 отговора
0 прегледа
Eclipse RCP + Native Code
Здравейте,
в момента пиша една Eclipse Rich Client Platform апликация и се сблъсках с проблем, на който след доста ровене по документации, блогове и форуми все още не мога да намеря разрешение. Реших да попитам и вас в случай, че някой е имал подобна ситуация.
Положението е следното. Един от плъгиновете, които пиша за апликацията, използва third party библиотека. Тя се състои от един .jar и няколко dll-а. Част от класовете в jar-а ползват въпросните dll чрез JNI, но имам само приблизителна представа какво точно се случва, понеже нямам достъп до кода. Eclipse-проектът на плъгина изглежда горе-долу така:
+ src
+ lib
|- library.jar
- a.dll
- b.dll
- c.lib
library.jar е в Build Path-a, а dll-овете са декларирани в манифеста на плъгина:
Bundle-NativeCode: а.dll ; b.dll ; c.lib ; osname=win32 ; processor=x86
Кодът компилира, но щом се опитам да инстанциирам някой клас от library.jar, винаги получавам ClassNotFoundException. Както изглежда, самите dll-ове са познати на системата, понеже System.loadLibrary("...") работи. Но ClassLoader-а на плъгина не намира класовете от library.jar. Някой знае ли какво пропускам?!
Мерси и приятна работа на всички!
в момента пиша една Eclipse Rich Client Platform апликация и се сблъсках с проблем, на който след доста ровене по документации, блогове и форуми все още не мога да намеря разрешение. Реших да попитам и вас в случай, че някой е имал подобна ситуация.
Положението е следното. Един от плъгиновете, които пиша за апликацията, използва third party библиотека. Тя се състои от един .jar и няколко dll-а. Част от класовете в jar-а ползват въпросните dll чрез JNI, но имам само приблизителна представа какво точно се случва, понеже нямам достъп до кода. Eclipse-проектът на плъгина изглежда горе-долу така:
+ src
+ lib
|- library.jar
- a.dll
- b.dll
- c.lib
library.jar е в Build Path-a, а dll-овете са декларирани в манифеста на плъгина:
Bundle-NativeCode: а.dll ; b.dll ; c.lib ; osname=win32 ; processor=x86
Кодът компилира, но щом се опитам да инстанциирам някой клас от library.jar, винаги получавам ClassNotFoundException. Както изглежда, самите dll-ове са познати на системата, понеже System.loadLibrary("...") работи. Но ClassLoader-а на плъгина не намира класовете от library.jar. Някой знае ли какво пропускам?!
Мерси и приятна работа на всички!
Re: Eclipse RCP + Native Code
Ок, открих решението. В случай, че някой някога запецне на същото място:
Първо, library.jar трябва изрично да се добави в ClassPath-а на плъгина (в MANIFEST.MF):
Bundle-ClassPath: lib/library.jar,
.
Второ, Bundle-NativeCode не е достатъчен сам по-себе си, поне в моя случай.
Тази директива позволява на плъгините да ползват нативни библиотеки без да трябва да се манипулира java.library.path. Всички dll файлове, декларирани в тази директива, стават видими и могат да бъдат заредени с System.loadLibrary(), т.е. директно по име.
Проблемът е, когато има повече от един dll-а, които имат dependencies помежду си. Ако най-напред се опитаме да заредим нативна библиотека, която има dependency, Windows няма да знае къде да намери тази dependency - информацията за това е известна само на виртуалната машина. Така че това веднага ще доведе до грешка. Ако обаче първо сме заредили библиотеката, която удовлетворява необходимата dependency, Windows просто ще установи, че вече е била заредена и няма да се оплаква (нативните библиотеки могат да бъдат заредени само еднократно).
Така че в Активатора на пългина, в метода start(BundleContext context) добавих:
System.loadLibrary("а");
System.loadLibrary("b");
и всичко тръгна по мед и масло.
Тъпа история, но като се налага...
Поздрави.
Първо, library.jar трябва изрично да се добави в ClassPath-а на плъгина (в MANIFEST.MF):
Bundle-ClassPath: lib/library.jar,
.
Второ, Bundle-NativeCode не е достатъчен сам по-себе си, поне в моя случай.
Тази директива позволява на плъгините да ползват нативни библиотеки без да трябва да се манипулира java.library.path. Всички dll файлове, декларирани в тази директива, стават видими и могат да бъдат заредени с System.loadLibrary(), т.е. директно по име.
Проблемът е, когато има повече от един dll-а, които имат dependencies помежду си. Ако най-напред се опитаме да заредим нативна библиотека, която има dependency, Windows няма да знае къде да намери тази dependency - информацията за това е известна само на виртуалната машина. Така че това веднага ще доведе до грешка. Ако обаче първо сме заредили библиотеката, която удовлетворява необходимата dependency, Windows просто ще установи, че вече е била заредена и няма да се оплаква (нативните библиотеки могат да бъдат заредени само еднократно).
Така че в Активатора на пългина, в метода start(BundleContext context) добавих:
System.loadLibrary("а");
System.loadLibrary("b");
и всичко тръгна по мед и масло.
Тъпа история, но като се налага...
Поздрави.