Aww shoot, I thought I could edit my posts, but I guess it’s only the replies? Anyhoo, sorry about the lame formatting, but, onward. One more point of introduction is that Normen once mentioned “OSGi bundles will also be provided by us when jME3 is stable”, and I’m hoping that the following discussion is helpful to that effort.
1) Classpath issues
A) Current versions of LWJGL apparently require runtime access to sun.misc.Unsafe. We have marked this dependency as an explicit package import in the pom.xml for ext.bundle.opengl.jmonkey. This import works under Felix, as long as we supply permission for sun.misc to be exposed by the framework, using org.osgi.framework.system.packages.extra=sun.misc as shown at line 210 of this OSGi application pom.xml. However, this technique is not yet working for us under Netigso/Netbeans-Platform. I mention this last point 1) in case it is useful to others, and 2) because we actually had JMonkey+LWJGL (August 2011 vintage) working under Netigso (before some refactoring of our own, yes), and so I’m hoping that either someone can confirm yes/no “the LWJGL dependence on sun.misc.Unsafe is/is-not new since August” and/or point out some other useful configuration point we may have missed (or forgotten and refactored over ;0).
B) JME3 likes to load assets from the classpath, and it’s a beautiful thing! Some assets (e.g. the “Common” tree) are packaged with the JMonkey core libraries, and hence it is natural to export them from our ext.bundle.opengl.jmonkey bundle. We also have our own separate bundle of assets (called org.cogchar.bundle.render.resources). Under OSGi, each bundle gets assigned its own classloader, which basically has authority to load classes+resources only from that bundle. The tricky thing is that JME3 (in its default configuration) in several places uses the current thread’s ContextClassLoader (henceforth TCCL) to pull in assets, so we must make sure that “the right classloader” is set on our thread when we enter JMonkey code that might load assets. We have made a lot of these scenarios work by trial and error, but as we’re now trying to become more formal and tidy our own projects (not duplicating resources, not mixing code and resources without a good reason), we’re needing to understand better exactly what JME3 is doing, which decisions are more settled vs. more volatile, and how we might perhaps better use the configurable AssetManager features. Here is a recap of what I currently see in practice when creating a SimpleApplication to run in a Swing/AWT canvas under OSGi (on Windows 7, x64, JDK6). Note that “iii” below is where we currently are having trouble and would like help.
i) SimpleApplication.initialize() loads resources from the JME3 core library, using the TCCL. We facilitate this by overriding initialize() and setting the TCCL to point to ext.bundle.opengl.jmonkey before calling super.initialize().
ii) SimpleApplication.update() also loads resources from the JME3 core library, using the TCCL. Presumably this only happens on the first call to update(), or some other time that “resources are needed”. Currently we are overriding update() and switching the TCCL before every call to super.update(), which doesn’t feel real good, but it is working.
(Side note about i & ii: Strangely the TCCL during these callbacks does not seem to be the same as what is
on the parent thread when we call startCanvas(), although…I thought it used to be as of September).
iii) We override simpleInitApp(), and read in our own assets from org.cogchar.bundle.render.resources. We set the TCCL to point to the classloader for that bundle, and read in an Ogre mesh model (currently using a copy of Sinbad from 20110917 as well as our own models). Here is the trouble: The model itself is located and loaded, and is rendered OK. But its subordinate models and materials are not found. We see:
INFO [LWJGL Renderer Thread] (JmonkeyAssetLoader.java:55) - Setting thread class loader to local loader: 154.0
Dec 23, 2011 12:02:03 AM com.jme3.scene.plugins.ogre.MeshLoader load
WARNING: Cannot locate jme3dat/models_20110917/sinbad/Sinbad.material for model jme3dat/models_20110917/sinbad/Sinbad.mesh.xml
Dec 23, 2011 12:02:03 AM com.jme3.scene.plugins.ogre.MeshLoader applyMaterial WARNING: Cannot locate Sinbad/Eyes for model jme3dat/models_20110917/sinbad/Sinbad.mesh.xml
Dec 23, 2011 12:02:03 AM com.jme3.scene.plugins.ogre.MeshLoader applyMaterialWARNING: Cannot locate Sinbad/Body for model jme3dat/models_20110917/sinbad/Sinbad.mesh.xml
…
Dec 23, 2011 12:02:04 AM com.jme3.scene.plugins.ogre.MeshLoader applyMaterial WARNING: Cannot locate Sinbad/Clothes for model jme3dat/models_20110917/sinbad/Sinbad.mesh.xml
INFO [LWJGL Renderer Thread] (JmonkeyAssetLoader.java:74) - ********** Finished loading model, restored classLoader to: 129.0
Again, Sinbad.mesh.xml itself is loaded OK, and even displays on the canvas as a red outline, but his siblings/children are dead to him (though those files are in the same package). The same jar of assets (treating the same bundle as just a jar), and same Java code works fine outside OSGi, or if we just lump all JME3+app code and assets into one mega-bundle. But for some reason, the sub-asset-load under OSGi is not working, perhaps because something about the state of the single DesktopAssetManager is not compatible with the TCCL-switching skullduggery? What would be the right approach? Do we need to create a separate AssetManager for each classloader, or register some separate AssetLocator / AssetLoader instances?