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

OSGi enabled JavaCPP #332

Merged
merged 11 commits into from
Sep 6, 2019
Merged

OSGi enabled JavaCPP #332

merged 11 commits into from
Sep 6, 2019

Conversation

timothyjward
Copy link
Contributor

Following on from discussions in PR #328 this PR does not change the Maven Plugin layout and

  1. Adds OSGi metadata to the JavaCPP library
  2. Adds an OSGi integration test

Note that the integration test passes because the JavaCPP Loader.load() method is not used, if it is used then the test fails. This demonstrates how the native library loading done by JavaCPP fails in OSGi, and hopefully can be used to design a fix.

* Annotations are used to export packages and define versions
* User implementable interfaces are marked `@ConsumerType`
* Baselining is enabled to validate future package version changes

Signed-off-by: Tim Ward <timothyjward@apache.org>
This test currently passes because it does not use the JavaCPP Loader to load its native libraries. Ideally this would be fixed so that users don't need to care about where they are running

Signed-off-by: Tim Ward <timothyjward@apache.org>
pom.xml Show resolved Hide resolved
pom.xml Outdated Show resolved Hide resolved
pom.xml Show resolved Hide resolved
@saudet
Copy link
Member

saudet commented Aug 22, 2019

If I understand correctly OSGi wants to manage native libraries on its own with Bundle-NativeCode? It looks rather limited in functionality. We probably won't be able to use that. We'll need to figure out the right way to call System.load().

@timothyjward
Copy link
Contributor Author

If I understand correctly OSGi wants to manage native libraries on its own with Bundle-NativeCode? It looks rather limited in functionality. We probably won't be able to use that. We'll need to figure out the right way to call System.load()

So what OSGi does with Bundle-NativeCode is to allow you to package multiple native binaries for different platforms and have the correct one selected for you automatically. Furthermore it sets up the bundle's class loader properly so that the native library can be found and loaded by the bundle class loader with a call to System.loadLibrary(libName) without any further file extraction required.

I'm currently investigating the feasibility of generating a small Java Helper class to live alongside the class(es) using JavaCPP. This helper can be called to try to load the native library within the correct Class context. If you have another idea about how this could be achieved then I'd be happy to hear it!

Signed-off-by: Tim Ward <timothyjward@apache.org>
@saudet
Copy link
Member

saudet commented Aug 22, 2019

Let's see, System.load() looks like this:

    public static void load(String filename) {
        Runtime.getRuntime().load0(getCallerClass(), filename);
    }

https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/lang/System.java#L1058-L1060

Still seems to be the same on the tip:
https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/lang/System.java#L1871

Would you be against trying to call Runtime.load0()? Or is this pretty much guaranteed to fail with OSGi anyway?

@timothyjward
Copy link
Contributor Author

Would you be against trying to call Runtime.load0()? Or is this pretty much guaranteed to fail with OSGi anyway?

Obviously there are issues with reflectively calling the internals of the JDK (for example this may not work on Eclipse's J9) but there isn't anything that OSGi will do to stop you and it should work. My biggest concern is that this sort of thing may well not work in future versions of Java as the VM is further locked down. When it comes down to it it's your call. I'll create a PR for the "helper class" approach so that you can take a look.

@saudet
Copy link
Member

saudet commented Aug 23, 2019

OpenJ9 uses OpenJDK, Android uses OpenJDK, there isn't much of anything that doesn't use OpenJDK these days, well maybe except IBM JDK, but they haven't updated since Java SE 8, so that's not a problem IMO. If OpenJDK ever decides to change that API, or even better, make the equivalent public, then we can always update at that point. There is still nothing to replace Unsafe completely, so people are still using, and the world hasn't ended. Just saying. The alternative is going to be much uglier.

timothyjward added a commit to timothyjward/javacpp that referenced this pull request Sep 2, 2019
As discussed in bytedeco#332, this commit uses reflection to load native libraries using the relevant class context

A similar commit is present in bytedeco#337, but this commit is designed to be applied to the master branch as part of bytedeco#332

Signed-off-by: Tim Ward <timothyjward@apache.org>
@saudet
Copy link
Member

saudet commented Sep 3, 2019

Looks good, but as I pointed out, we don't need to use try to use Runtime.load0(), unless the class loader are not the same. Let's add a check for that?

And could you revert the breaking changes to the manifest as well?

As discussed in bytedeco#332, this commit uses reflection to load native libraries using the relevant class context

A similar commit is present in bytedeco#337, but this commit is designed to be applied to the master branch as part of bytedeco#332

Signed-off-by: Tim Ward <timothyjward@apache.org>
Remove the name section so that all packages pick up the metadata in the manifest

Signed-off-by: Tim Ward <timothyjward@apache.org>
@timothyjward
Copy link
Contributor Author

Looks good, but as I pointed out, we don't need to use try to use Runtime.load0(), unless the class loader are not the same. Let's add a check for that?

Done

And could you revert the breaking changes to the manifest as well?

Also done, but not as a revert (which results in a broken OSGi bundle and fails the integration test). Instead I have applied the same fix as is on the osgi branch which removes the manifest section and applies the metadata to all the packages.

@timothyjward
Copy link
Contributor Author

It looks like the Travis build is passing. Are you happy to merge this now?

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

Successfully merging this pull request may close these issues.

2 participants