I am trying to use a method from a DLL in a OSGI-bundle. The DLL gets loaded correctly in OSGI, but I still get an java unsatisfied link error, the native method is not found!
When deployed standalone in Java only (no OSGI), the DLL gets loaded and run perfectly.
Here's what I did:
I generated a JNI bridge to my C++ compiled DLL through SWIG.
I specified the package name when calling swig.
I declared the dll inclusion in my Maven pom.xml xml element, which generates a correct Manifest file.
Loading of the DLL libraries is done without any errors / warnings
What truly puzzles me is that the symbols in the dll seem to not be found:
java.lang.UnsatisfiedLinkError: com.bmw.corona.components.sample.impl.generated.AdasDeconstructorJNI.swig_module_init()V
The problem is when coupling it with OSGI, I'm guessing somewhere in OSGI's ClassLoader.
The method in the dll seems to have a the correct signature :
_Java_com_bmw_corona_components_sample_impl_generated_AdasDeconstructorJNI_swig_1module_1init#8
with the following prototype in the generated SWIG file:
SWIGEXPORT void JNICALL Java_AdasDeconstructorJNI_swig_1module_1init(JNIEnv *jenv, jclass jcls)
I was triple-sure to check that the Manifest includes the Bundle Native instruction.
What am I doing wrong?
You may want to consult this wiki article: http://wiki.osgi.org/wiki/Dependencies_In_Native_Code
It is hard to tell from your description, but it sound like you have 2 native libs. One with the JNI entry points and the other with the real native function. The above wiki article discusses the dependencies from the JNI native lib to other native libs.
The problem was twofold. First, the methods weren't found do to Visual Studio 2010's method name mangling. I added a linker directive :
#pragma comment(linker, "/EXPORT:__Java_com_bmw_corona_components_sample_impl_AdasDeconstructorJNI_swig_module_init=_Java_com_bmw_corona_components_sample_impl_AdasDeconstructorJNI_swig_1module_1init#8")
It does take a bit of time for all the bundles (more than 100) to get up and running, and I do get a java.lang.NullPointerException: null the first couple of seconds after launch. Afterwards, everything seems to be working fine. And the nullPointerException is gone..
Related
I've dynamically linked libhunspell.dll (HunSpell) to my application. It works, but there is a dumb problem which I don't know why it happens.
Even before I use LoadLibrary("path\\to\\libhunspell.dll"); to load it and use it, on the start of the application it attempts to load the library by itself. If I place the libhunspell.dll into the path where my main executable resides, it can load it, otherwise it reports an error, immediately after starting the application - This application has failed to start because LIBHUNSPELL.DLL was not found. Re-installing the application may fix this problem. and the application doesn't start.
I would understand if the LoadLibrary would use invalid path but this happens as soon as the executable runs, even before the first statement in WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) executes (I've tried to place a breakpoint and it doesn't even reach it, so this happens before).
So, as a result, I must place libhunspell.dll in the same folder as my application executable, and not in the path I want.
This is probably easy to fix although I don't what to look for.
So the question is - how do I avoid it loading it immediately and have it wait until I use LoadLibrary call?
Here is how I linked if it can help:
1) compiled libhunspell.dll in Visual Studio 2015 (I used /MT option to link it statically so it doesn't have VC++ Redistributable as a dependency).
2) created import library (libhunspell.lib) using implib.exe -a -c -f libhunspell.lib libhunspell.dll
3) linked that to the source .cpp unit which is using it using #pragma comment(lib, "libhunspell.lib") (it is RAD Studio 2010 so the .lib is required unlike newer versions).
4) later in the same .cpp used LoadLibrary to load this library and used it.
By linking in the import stubs (libhunspell.lib) the OS will load the DLL for you as it is now a static dependency.
One approach would be specify the library as a delayload dependency: /DELAYLOAD:libhunspell.lib via the linker options. You can then call LoadLibrary on the DLL.
The only other option is to stop including the .lib in the linker step, making it truly a dynamic dependency.
I assume you did Add to project a *.lib file for your DLL. That is a kind of "static" linkage done in the App initialization (prior to your forms are created). So it has two disadvantages.
You DLL must be in the same path as the Apps EXE file
Sometimes DLL file name is locked (can not be changed)
The advantage is that you do not need to do any coding for the DLL loading as the VCL do it for you ... so your app should not contain the LoadLibrary,GetProcAddress calls you just include the *.h file with propper import declarations ...
For dynamic linkage you need to remove the *.lib from your project and use WinAPI LoadLibrary + GetProcAddress for loading your DLL as josh poley suggested. Here an example:
Builder C++ calling VC++ class
Beware there was/(is?) a bug in the GetProcAddress preventing from loading all the functions from your DLL in some cases. Especially if the DLL has old legacy mangling of names the count of functions is high and the DLL was created on compiler incompatible with the mangling in question.
While trying to use ProGuard (5.3.2) to obfuscate a Automation framework getting lot of warnings i've resolved most of the warnings by adding respective library's but could not able to resolve below warnings. i have tried by adding com.hibernate-core jar but still getting same.
Warning: com.test.utils.DBOperations: can't find referenced method 'org.hibernate.Session openSession()' in library class org.hibernate.SessionFactory
Warning: com.test.utils.DBOperations: can't find referenced method 'void close()' in library class org.hibernate.Session
I have tried searching for a solution but the answer would always be for an android application.
I have find there is an option that I can select inside the Proguard GUI. Please check the picture:
This method is good for obfuscation the class name or method name inside the .jar file.
If you want to ignore the warning when creating from android studio or eclipse... just put some "-dontwarn" or "-ignorewarning" command inside the proguard-rule.pro file.
I am trying to write a JNI applications that uses a dll which is dependent on another dll. I have placed both the dlls in the same folder. But still when I run the Java program I get the error
Caused by: java.lang.UnsatisfiedLinkError: \eclipse_workspaces\Learning\Lesson93_Beyond_Test3\bin\QuestionSDK-1.0.dll: Can't find dependent libraries
If I remove the calls to the dependent library my library loads fine so I know the path is correct. What am I missing. Please help.
please note that for a dependent library of a jni library rather than being defined on 'java.library.path' its location has to be defined on the PATH environment variable.
hope this helps you out.
cheers,
I have a solution in VS 2008 that creates a DLL. I then use that DLL in another application. If I go in to the DLL projects property pages and change the following configuration for a DEBUG build then the built dll no long provides the desired functionality. If I change it back and rebuild the DLL, then the DLL does provide the correct functionality:
Property Pages => Configuration Properties => C/C++ => Code Generation => Runtime Library
If set to "Multi-threaded Debug DLL (/MDd)"
then everything works as it should. I get the correct functionality from the DLL
If set to "Multi-threaded DLL (/MD)" then the DLL does not function properly...no runtime errors or anything, it just doesn't work (The DLL is supposed to plot some lines on a map but does not in this mode).
So the question is, why does using the /MDd flag result in correction functionality of the underlying code, while /MD results in incorrect functionality?
A little background...somebody else developed the DLL in C++ and I am using this DLL in a VB.net application.
All DLL's/debug code generation must match across everything that uses them. There may be another referenced library or object or dll or some code in there that is built using the wrong options; or specific options for an individual element that override the global project options.
The only way of figuring it out is to meticulously check all of the options for each file, checking the included and referenced libraries (.lib and .dll) and object files. Check the linker options too.
The reason why it doesn't work is probably because the debug version adds extra guard blocks around memory to allow detection of errors.
I had similar problems. My application which "used" a 3rd party DLL crashed when its runtime library was set to "Multi-threaded DLL (/MD)", but worked when its runtime library was set to "Multi-threaded Debug DLL (/MDd)".
It has something to do with passing std::strings and std::lists across the DLL interface.
Our guess was the low level definition of these types was somehow different in the two runtime libraries.
We solved our related problems using this rule...
The DLL and the DLL user must be build using the exact same runtime library.
The main difference between the two options is in the libraries that your code will be linked at later. for the debug version for example this will include LIBCMTD.LIB and a few others. if your library is going to be built as debug the you should always link with MDd. failing to do so will result in lots of unresolved external linker errors at best. and sometimes the code compiles normally but crashes at runtime. if this happens in vb.net then a catch can easily hide the error. I guess you should make sure you build setting is correct. for more detailed information check this.
I have a project which uses C++/CLI to implement a GUI and some background processing to talk to a sensor. I've got that all working and a lot of the comms stuff which we use to communicate the the sensor sits in a .dll. The problem is that I'd like to combine the library into the main executable to avoid having to worry about distributing .dlls.
I've got a demo project which works fine using a .lib but when I try and switch the mani code body to produce a .lib instead of .dll I get the following error:
1>------ Build started: Project: MyTool, Configuration: Debug Win32 ------
1>Compiling...
1>stdafx.cpp
1>.\stdafx.cpp : fatal error C1113: #using failed on 'c:\projects\MyTool\debug\MyLib.lib'
A bit of googling suggests this happens when you've not got the MSIL switch applied, but it's definitely in there in the library project.
I have a mixture of managed and unmanaged code in both my demo project and the real thing so I'm really struggling to see what the problem is here.
Any suggestions would be very gratefully received!
I am guessing a bit, but I suspect the "MyTool" project has the "MyLib" project as one of its "references" ("Project" menu >> Properties >> Common Properties >> References).
When you change the type of the MyLib project to a LIB instead of a DLL, you need to remove "MyLib" from the project references. You then update the project dependencies of the solution ("Project" menu >> "Project Dependencies...") so that MyTool depends on MyLib.
If you are linking to a mixed mode (managed/native) DLL you may get this error. Which you shouldn't if the project uses CLR even if one of the source files doesn't. But anyway, if that is the case, then try removing the reference from Project|Properties|Common Properties|References and then re-adding it.
I also ran into this. The reason it was failing was because I was compiling my native/managed C++ DLL to target .NET 4.0. And the DLL I was #using was a .NET 2.0 DLL. As such it was failing, even though the paths and file names lined up perfectly. In this case the error message was absolutely of no help at all.
I solve it by updating the independent DLL to .NET 4.0. So that both assemblies were using the same .NET framework.