Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IOException when loading a native library inside an OSGI bundle using jna.library.path #2

Open
ochafik opened this issue Mar 9, 2015 · 5 comments
Assignees

Comments

@ochafik
Copy link
Member

ochafik commented Mar 9, 2015

From @ochafik on September 1, 2011 18:47

What steps will reproduce the problem?

  1. Create an OSGi bundle that uses a jnaerated CustomLibrary.INSTANCE
  2. Run OSGi container with path to native library (-Djna.library.path=lib)
  3. Deploy and start the custom bundle

What is the expected output? What do you see instead?
The JNAerated code should run without problem as according to the documentation jna.library.path is where libraries are looked for at run-time. Instead an IOException is thrown by the call LibraryExtractor.getLibraryPath()

What version of the product are you using? On what operating system?
maven-jnaerator-plugin 0.9.5 on Windows 7

Is the problem still present in the latest SVN version ?
Yes

Workaround:
Instead of defining jna.library.path, set library.custom
-Dlibrary.custom=lib\custom.dll
This tricks LibraryExtractor.getLibraryPath()

Stack trace of the Exception:
ERROR: Failed to extract library mOcrApi
java.io.IOException: Cannot list contents of bundle://5.0:1/libraries/win32
at com.ochafik.net.URLUtils.listFiles(URLUtils.java:58)
at com.ochafik.lang.jnaerator.runtime.LibraryExtractor.getLibraryPath(Li
braryExtractor.java:96)
at xx.CustomLibrary.(CustomLibrary.jav
a:18)
at xx.CustomDriver.(CustomDriver.java
:16)
at xx.CustomBundleActivator.start(CustomBundleActivator
eActivator.java:12)
at org.apache.felix.framework.util.SecureAction.startActivator(SecureAct
ion.java:633)
at org.apache.felix.framework.Felix.activateBundle(Felix.java:1822)
at org.apache.felix.framework.Felix.startBundle(Felix.java:1739)
at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1143)

    at org.apache.felix.framework.StartLevelImpl.run(StartLevelImpl.java:264

)
at java.lang.Thread.run(Unknown Source)

Google Code Info:
Issue #: 76
Author: [email protected]
Created On: 2010-11-30T15:21:38.000Z
Closed On:

Copied from original issue: nativelibs4java/nativelibs4java#153

@ochafik
Copy link
Member Author

ochafik commented Mar 9, 2015

Hello Aleksandar,

Thank you for your report (and for the workaround !).
(EDIT: deleted a silly comment of mine, didn't realize that library.custom is JNAerator's own library location override mechanism... this tells you how often I use this hack ;-))

Would you have any pointer to an OSGI bundle-howto, so that I can reproduce the issue and play a bit ?

Cheers

Olivier

Google Code Info:
Author: olivier.chafik
Created On: 2010-11-30T16:08:20.000Z

@ochafik ochafik self-assigned this Mar 9, 2015
@ochafik
Copy link
Member Author

ochafik commented Mar 9, 2015

Salut Olivier,

As seen in my case, I use Apache Felix. To use it as an OSGi container you can get starting information from this page:
http://felix.apache.org/site/apache-felix-framework-usage-documentation.html

Here is a 5-step quick guide:

  1. Download Felix Framework Distribution 3.0.6:
    http://felix.apache.org/site/downloads.html
  2. If you're using Maven, create a test project and do the following to your POM:

Add a dependency to OSGi:

org.apache.felix
org.osgi.core
1.4.0

Set packaging to bundle:
bundle

Create and configure a bundle activator:

org.apache.felix
maven-bundle-plugin
true


xx.CustomBundleActivator


  1. Inside the start() method of your CustomBundleActivator (implementation of org.osgi.framework.BundleActivator), use the Custom.INSTANCE field to include the JNAerator magic in the mix.
  2. Put your bundle in Felix' bundle/ directory
  3. Run Felix:
    java -jar bin/felix.jar

Hope that helps,
Alex

Google Code Info:
Author: [email protected]
Created On: 2010-12-01T07:10:57.000Z

@ochafik
Copy link
Member Author

ochafik commented Mar 9, 2015

btw Here is the code by JNAerator:
public static final java.lang.String JNA_LIBRARY_NAME = LibraryExtractor.getLibraryPath("Custom", true, xx.CustomLibrary.class);
public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(xx.CustomLibrary.JNA_LIBRARY_NAME, com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper.DEFAULT_OPTIONS);
public static final CustomLibrary INSTANCE = (CustomLibrary)Native.loadLibrary(xx.CustomLibrary.JNA_LIBRARY_NAME, xx.CustomLibrary.class, com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper.DEFAULT_OPTIONS);

I didn't understand why it's different from your example:
http://code.google.com/p/jnaerator/wiki/SimpleMeaningfulExample

public TestLibrary INSTANCE = (TestLibrary)com.sun.jna.Native.loadLibrary("test", TestLibrary.class);

I tried different command line options but I couldn't remove the call to LibraryExtractor.getLibraryPath(). Maybe only -skipLibraryInstance, but I don't like it as a solution because then I'll have to write stuff in my code.

Google Code Info:
Author: [email protected]
Created On: 2010-12-01T07:34:16.000Z

@ochafik
Copy link
Member Author

ochafik commented Mar 9, 2015

Hi,

The workaround mentioned in the initial report does not work for me. I don't even use jna.library.path at all: because my native libraries have other dependencies, I set the LD_LIBRARY_PATH environment variable instead. It doesn't seem to make any difference if I set jna.library.path or library.custom at all.

I now use -skipLibraryInstance while generating the code, and lose the getLibraryPath call in my own code. Maybe not so clean, but it works for me.

By the way, I use JNAerator for some Eclipse plug-ins which need to access native libraries. Eclipse is also OSGi based, which is why this issue shows up for me.

Google Code Info:
Author: [email protected]
Created On: 2011-06-07T09:10:53.000Z

@ochafik
Copy link
Member Author

ochafik commented Mar 9, 2015

From @gamerson on December 30, 2014 5:56

I've been trying to use the jnaerator-runtime in an OSGi runtime and I'm getting this exception. But it seems to be innocuous. I was able to avoid the problem by simply redefining the URIUtils.listFiles() method and simply deleting the line that throws the IOException. Everything else seems to work as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant