JOGL with OSGi

classic Classic list List threaded Threaded
31 messages Options
12
Jar
Reply | Threaded
Open this post in threaded view
|

JOGL with OSGi

Jar
Hi, I'm trying to repackage JOGL as an OSGi bundle.

Currently, I repack all the gluegen and JOGL code jars into a single jar. Then, I deploy that jar as an OSGi bundle after wrapping it with the bnd tool to add the Export-Package metadata.

However, I'm not sure where the jars containing the native libraries should go. I could create a jar containing all the .dll, .so, and .jnilib files and make it an OSGi fragment and add Bundle-NativeCode metadata. But that didn't seem to work.

What are some working ways that you have used to turn JOGL into OSGi bundles?

Thanks,
Programmer
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

gouessej
Administrator
Hi

I make a separate bundle for GlueGen and JOGL Java classes and I put native libraries into separate bundles (JOGLLib.linux64, JOGLLib.win32, JOGLLib.win64, etc...). Maybe Wade can help you. I don't have any working copy of my bundles at home :s
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

Wade Walker
Administrator
In reply to this post by Jar
In my tutorial at http://wadeawalker.wordpress.com/2010/10/09/tutorial-a-cross-platform-workbench-program-using-java-opengl-and-eclipse/, I show how to put JOGL into a form that can be deployed as an Eclipse RCP project, which I assume is similar to how it would work in a raw OSGi project. The trick I use is creating a project/bundle for JOGL that contains the gluegen and JOGL JARs, then creating fragment projects/bundles for each of the native platforms. At runtime, OSGi loads the correct fragment for the platform.

I believe that new development builds of JOGL have all the native libraries for all platforms available in one big JAR -- if so, you could just make one single JOGL bundle with all the JARs in it, without using native fragments. But I haven't tried it this way yet.


Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

Oscar Vargas Torres
I am using jogl with Apache Karaf. However, I cannot make Karaf to recognize libgluegen-rt.jnilib. I've spent last two days trying several approaches without success.

One of the approaches I tried was to deploy jogl-all-main, gluegen-rt-main and all of their dependants in the hot deploy directory. The errors are here: http://pastie.org/pastes/7814616

I was suggested to make a gigantic bundle with all the native jars and java-only jars. I tried that too, but then karaf complains doesn't start the bundle and when I try to start it, I get an error message that it cannot find native libraries.

I tried to bundle the jars with native libraries (on Mac OS X, they are distributed as jnilib files):

$ cat propNative.bnd
-classpath: gluegen-rt-2.0-rc11-natives-macosx-universal.jar, jogl-all-2.0-rc11-natives-macosx-universal.jar
Bundle-SymbolicName: jogl-gluegen-macosx
ver: 2.0-rc11
-output: ${bsn}-${ver}.jar
Bundle-Version: ${ver}
Export-Package: *;version=${ver}
Bundle-NativeCode: libgluegen-rt.jnilib ; libnativewindow_macosx.jnilib ; libjogl_desktop.jnilib ; libjogl_mobile.jnilib ; libnativewindow_awt.jnilib ; libnewt.jnilib ;
        osname=MacOS ; processor=x86-64 , *
# Uncomment next line to customise imports. The last entry MUST be "*"
# Import-Package: *


### By the way, mybnd is just an alias for java -jar /path/to/bnd.jar; bndlib.jar is in my classpath
oscars-imac:macosxBundle oscarvarto$ mybnd propNative.bnd
-----------------
Warnings
000: propNative.bnd: The JAR is empty: The instructions for the JAR named jogl-gluegen-macosx did not cause any content to be included, this is likely wrong

So maybe my problem is that I don't know how to embed jnilibs in an osgi bundle???

I see your comment:
The trick I use is creating a project/bundle for JOGL that contains the gluegen and JOGL JARs, then creating fragment projects/bundles for each of the native platforms. At runtime, OSGi loads the correct fragment for the platform.

but I guess I don't know how to what you suggest (little experience with osgi).

Please I need help! I've been trying for a lot of time without success.
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

gouessej
Administrator
Hi

JOGL 2 tries to extract the native libraries somewhere but it seems not to be allowed in your case, then you get a IOException.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

Wade Walker
Administrator
In reply to this post by Oscar Vargas Torres
Recently, I successfully used JOGL's native library JARs in an Eclipse RCP project, with the help of a new fix to JarUtil. I'm not sure if it will work in Karaf the same way, but it might.

First, you add the JOGL native library JAR files (e.g. gluegen-rt-natives-linux-amd64.jar and jogl-all-natives-linux-amd64.jar if you're in 64-bit Linux) into an OSGi bundle somehow. In an Eclipse project, this means adding them to a plugin, but in Karaf it may work differently. You can add the JARs for all 5 platforms if you want, or just for the platform you're running on.

Then you add this code to your project so it runs before JOGL is invoked:

JarUtil.setResolver( new JarUtil.Resolver() {  
    public URL resolve( URL url ) {  
        try {
            System.out.print( "before resolution: " + url.toString() );
            return( FileLocator.resolve( url ) );   
        } catch( IOException ioexception ) {  
            return( url );  
        }
    }  
} ); 

FileLocator is an Eclipse class from org.eclipse.core.runtime, there may be something similar in Karaf. It converts OSGi "bundleresource:" URLs into "file:" URLs that JOGL can use internally to unpack its .so/.dll/.jnilib files (more details at https://jogamp.org/bugzilla/show_bug.cgi?id=687). To debug this, you can just return the unresolved URL above and look at what's printed -- if they are bundleresource: or some other type of URL than file:, they need to be resolved somehow or JOGL can't find them.
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

gouessej
Administrator
Thank you Wade, this is the typical kind of tip that should be added into our Wiki or into the user's guide.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

Oscar Vargas Torres
In reply to this post by Wade Walker
I have been trying to follow your advice but need additional help.

you add the JOGL native library JAR files (e.g. gluegen-rt-natives-linux-amd64.jar and jogl-all-natives-linux-amd64.jar if you're in 64-bit Linux) into an OSGi bundle ***somehow***

I have been trying to do that with bnd and the terminal, using a properties.bnd file. Then bnd warns that an empty output file is generated (maybe because there are no classes there, only jnilib files). I added a Include-Resource header to force bnd to include the jnilib files.

I  tried to do that with Eclipse bndtools and Eclipse RCP but I keep getting the same old error: no gluegen-rt library in java.library.path.

I tried to add the java code you posted but I cannot get this to compile:

new JarUtil.Resolver()

I am using the files here http://search.maven.org/#artifactdetails|org.jogamp.gluegen|gluegen-rt|2.0-rc11|jar
Maybe I am supposed to use a newer version of jogamp-all-platforms.7z ...

Could you please, give me more detailed help? I have been trying another day and this is driving me nutts!

Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

Oscar Vargas Torres
In reply to this post by Wade Walker
I found your own Tutorial at http://wadeawalker.wordpress.com/2010/10/09/tutorial-a-cross-platform-workbench-program-using-java-opengl-and-eclipse/

I could successfully follow your instructions there (with eclipse 3.8). I am reeeeeaaaaaaallllly thankful for that tutorial. I am developing my application mostly in Scala, so maybe I'll come back again...
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

Wade Walker
Administrator
Glad you found the tutorial helpful! The JarUtil.setResolver() shows up in nightly builds of JOGL, I don't think it's made it into an official release yet, so you'd need to use a version from http://jogamp.org/deployment/autobuilds/master/.

My tutorial does things the "old fashioned" way, with a fragment bundle for each platform. If you use JarUtil.setResolver(), you can put all 5 platforms of native JARs into the com.jogamp.jogl project, and remove all 5 fragment projects. I've got an example in GitHub at https://github.com/WadeWalker/com.jogamp.jogl.

I usually put the JarUtil.setResolver() call in createPartControl() of the editor. If you use it, you also need to make sure you're not calling GLProfile.initSingleton() in a static block anywhere, since it would be run before the resolver is set.
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

Gene Lege
Wade - would you be able to give an example of an implementation of the interface Resolver?

I am not sure how to set the protocol for use with RCP in the URL return value?

Thanks for any help you can give!

Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

Wade Walker
Administrator
The resolver I use in Eclipse RCP apps looks like this:

JarUtil.setResolver( new JarUtil.Resolver() {
    public URL resolve( URL url ) {
        try {
            return( FileLocator.resolve( url ) ); 
        }
        catch( IOException ioexception ) {
            return( url );
        }
    }
} );

where org.eclipse.core.runtime.FileLocator is a part of Eclipse's framework code. FileLocator.resolve(url) converts the URL from an Eclipse/OSGi "bundleresource:" URL protocol (which is how Eclipse locates JARs/libraries that have been packaged into OSGi bundles) to a normal "file:" URL protocol that JOGL and other non-Eclipse code can use.

The purpose of the Resolver interface is to allow dependency injection, so JOGL can indirectly call this Eclipse/OSGi FileLocator.resolve() method without directly depending on an outside framework's code. In any given situation where your framework uses non-standard URL protocols, just wrap a Resolver around your framework's URL resolver and JOGL's auto-JAR-unpack feature should work correctly.
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

Gene Lege

Thanks, Wade!, this got me farther down the path, but now I am getting a runtime exception on starting my Editor because of:

Caused by: java.lang.ClassNotFoundException: com.jogamp.common.util.JarUtil$Resolver
        at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:501)
        at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
        at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)
        at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
        ... 112 more

I have the gluegen-rt.jar and the jogl-all.jar in my com.jogamp.jogl bundle, along with the appropriate native code jars, I have all the packages in these two jars in the export list, and my application *builds* successfully against it.

Anything else I should look at?  Thanks for the response and anything else you can think of...
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

Wade Walker
Administrator
Hmm, that is strange that it's a runtime exception and not found at compilation time. There are a couple of things to check:

- Make sure your com.jogamp.jogl bundle is in your plugin.xml dependencies
- Make sure your com.jogamp.jogl bundle is also in your <project>.product dependencies (if your plugin.xml was correct, it should have been put there automatically when you created the <project>.product file)
- Double-check that you're using a version of JOGL that actually contains JarUtil$Resolver (it's pretty recent, so it might still only be in a nightly build, though it shouldn't compile if that wasn't right)

The first two are the most likely -- Eclipse may check dependencies differently for compilation than OSGi does at runtime.

Also, just as a reference: I'm setting up the resolver in my editor's createPartControl(), before any JOGL code is called, and I'm not using a static code block anywhere to call GLProfile.initSingleton().
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

Gene Lege

Thanks again, Wade - yes, it was the first one.

I think everything is working right now on the jogl plugin and its native code.

Unfortunately, I am now seeing:


!ENTRY org.eclipse.e4.ui.workbench 4 0 2013-05-29 16:33:05.518
!MESSAGE Unable to create class 'org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor' from bundle '428'
!STACK 0
org.eclipse.e4.core.di.InjectionException: java.lang.NoSuchMethodError: javax.media.opengl.GLContext.setSynchronized(Z)V
        at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:63)
        at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:861)
        at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:841)
...

which I believe I have tracked down to an incompatibility in the version of jogl I am using to utilize the JarUtils.setResolver() and native code mechanism and the version of jogl I apparently need to use with the third party code that is part of my application.

It is actually the third party code that actually utilizes jogl, and they ship a specific version - the jars are dated 12/19/2012, which is their release date, and I suspect that the jogl code that is included is from the 11/2012 release that seems to still be the current official release on the website.

I found the javax.media.opengl.GLContext.setSynchronized() in their jogl jar and not in the one I have been using from 3/2013.

I will keep looking into it - it may be that there is a simple interface change I can make an adapter for, but I suspect that I am going to have to go back to the fragment method.  (which I haven't gotten working yet either, but I should be able to with your tutorial :-))


Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

Gene Lege
I got the fragment bundle method working.

One thing that I did want to point out is that,  because of https://jogamp.org/bugzilla/show_bug.cgi?id=537 , I had to set jogamp.gluegen.UseTempJarCache to false to get this to work - otherwise jogl does not handle falling back from attempting the "new" method correctly
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

gouessej
Administrator
Thank you for the feedback and you should not use several versions of JOGL 2 at the same time. I already wasted several days because of that. For example, if some constants are modified between 2 versions (which occurred several times in NEWT), you'll have some troubles. Maybe we should reopen the bug report 537.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

Gene Lege
"Maybe we should reopen the bug report 537."

Actually, I believe this is fixed, just in a later version than the one I need to use with the third party libraries.
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

Wade Walker
Administrator
In reply to this post by Gene Lege
Gene Lege wrote
...I had to set jogamp.gluegen.UseTempJarCache to false to get this to work...
I had mentioned this in a reply to a comment on my tutorial, but I've moved that up into the main text now to make it more visible. Thanks for reminding me! This is supposed to be fixed, but I may need to revisit bug 537.
Reply | Threaded
Open this post in threaded view
|

Re: JOGL with OSGi

gouessej
Administrator
In reply to this post by Gene Lege
Gene Lege wrote
Actually, I believe this is fixed, just in a later version than the one I need to use with the third party libraries.
Ok but I encourage you to use a single version of JOGL 2 at a time, maybe you can recompile these libraries or ask their maintainers to use a more recent version. Using several versions of JOGL 2 at the same time in a program only leads to troubles and you don't benefit of the latest fixes.
Julien Gouesse | Personal blog | Website
12