Bug 550 - JOAL lacks Platform.initSingleton() - Using TempJarCache reveals unresolved initialization dependency leading to NPE in NativeLibrary
Summary: JOAL lacks Platform.initSingleton() - Using TempJarCache reveals unresolved i...
Status: RESOLVED FIXED
Alias: None
Product: Joal
Classification: JogAmp
Component: core (show other bugs)
Version: 1.0
Hardware: All all
: --- normal
Assignee: Sven Gothel
URL:
Depends on:
Blocks:
 
Reported: 2012-01-04 16:06 CET by Julien Gouesse
Modified: 2013-03-07 23:46 CET (History)
0 users

See Also:
Type: ---
SCM Refs:
c18c52b8c20aa03a08940bef81b620d48c4117e2
Workaround: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Julien Gouesse 2012-01-04 16:06:26 CET
When jogamp.gluegen.UseTempJarCache is set to true (by default), GlueGen tries to extract native libraries from JARs. It uses the architecture of the machine to determine which one should be loaded.

If the bitness of the architecture of the machine (indicated by the property "os.arch") is not the same as the bitness of the JVM (indicated by the property "sun.arch.data.model"), GlueGen attempts to load the native libraries matching with the former whereas the JVM used by Java Web Start supports native libraries matching with the latter, i.e a 32 bits JVM fails to load 64 bits native libraries extracted by GlueGen.

The problem can be reproduced by launching the pre-beta version of TUER with a 32 bits JVM on a 64 bits machine as you can see below:
Detected from bootclasspath: C:\\Program Files (x86)\\Java\\jre7\\lib\deploy.jar
Dez 24, 2011 10:56:23 AM engine.integration.DesktopIntegration <init>
Information: operating system: windows 7
Dez 24, 2011 10:56:23 AM engine.integration.DesktopIntegration <init>
Information: operating system family: Windows
Dez 24, 2011 10:56:23 AM engine.integration.DesktopIntegration <init>
Information: tries to create a temporary file to contain the WSH script...
Dez 24, 2011 10:56:23 AM engine.integration.DesktopIntegration <init>
Information: temporary file C:\Users\EGONOL~1\AppData\Local\Temp\getDesktopFolder5195775719385520981.js successfully created
Dez 24, 2011 10:56:23 AM engine.integration.DesktopIntegration <init>
Information: temporary file C:\Users\EGONOL~1\AppData\Local\Temp\getDesktopFolder5195775719385520981.js successfully filled
Dez 24, 2011 10:56:23 AM engine.integration.DesktopIntegration <init>
Information: registry value used as a desktop path: C:\Users\EgonOlsen\Desktop
Dez 24, 2011 10:56:23 AM engine.integration.DesktopIntegration <init>
Information: operating system supported. Desktop path: C:\Users\EgonOlsen\Desktop

Starting up SoundSystem...
Initializing JOAL
    (The JOAL binding of OpenAL.  For more information, see http://joal.dev.java.net/)
java.nio.channels.ClosedByInterruptException
   at java.nio.channels.spi.AbstractInterruptibleChannel.end(Unknown Source)
   at sun.nio.ch.FileChannelImpl.write(Unknown Source)
   at java.nio.channels.Channels.writeFullyImpl(Unknown Source)
   at java.nio.channels.Channels.writeFully(Unknown Source)
   at java.nio.channels.Channels.access$000(Unknown Source)
   at java.nio.channels.Channels$1.write(Unknown Source)
   at java.nio.file.Files.copy(Unknown Source)
   at java.nio.file.Files.copy(Unknown Source)
   at sun.net.www.protocol.jar.URLJarFile$1.run(Unknown Source)
   at sun.net.www.protocol.jar.URLJarFile$1.run(Unknown Source)
   at java.security.AccessController.doPrivileged(Native Method)
   at sun.net.www.protocol.jar.URLJarFile.retrieve(Unknown Source)
   at sun.net.www.protocol.jar.URLJarFile.getJarFile(Unknown Source)
   at sun.net.www.protocol.jar.JarFileFactory.get(Unknown Source)
   at sun.net.www.protocol.jar.JarURLConnection.connect(Unknown Source)
   at com.sun.jnlp.JNLPCachedJarURLConnection.connect(Unknown Source)
   at com.sun.jnlp.JNLPCachedJarURLConnection.getJarFile(Unknown Source)
   at com.jogamp.common.util.JarUtil.getJarFile(JarUtil.java:294)
   at com.jogamp.common.util.cache.TempJarCache.bootstrapNativeLib(TempJarCache.java:346)
   at com.jogamp.common.os.Platform$3.run(Platform.java:312)
   at java.security.AccessController.doPrivileged(Native Method)
   at com.jogamp.common.os.Platform.loadGlueGenRTImpl(Platform.java:303)
   at com.jogamp.common.os.Platform.<clinit>(Platform.java:214)
   at com.jogamp.common.os.NativeLibrary.<clinit>(NativeLibrary.java:76)
   at com.jogamp.common.os.DynamicLibraryBundle.<clinit>(DynamicLibraryBundle.java:56)
   at jogamp.openal.ALImpl$1.run(ALImpl.java:2250)
   at java.security.AccessController.doPrivileged(Native Method)
   at jogamp.openal.ALImpl.<clinit>(ALImpl.java:2247)
   at com.jogamp.openal.ALFactory.initialize(ALFactory.java:58)
   at com.jogamp.openal.ALFactory.getALC(ALFactory.java:92)
   at com.jogamp.openal.util.ALut.alutInit(ALut.java:66)
   at paulscode.sound.libraries.LibraryJOAL.init(LibraryJOAL.java:154)
   at paulscode.sound.SoundSystem.CommandNewLibrary(SoundSystem.java:1576)
   at paulscode.sound.SoundSystem.CommandQueue(SoundSystem.java:2572)
   at paulscode.sound.CommandThread.run(CommandThread.java:121)
Exception in thread "Thread-12" java.lang.ExceptionInInitializerError
   at com.jogamp.common.os.NativeLibrary.<clinit>(NativeLibrary.java:76)
   at com.jogamp.common.os.DynamicLibraryBundle.<clinit>(DynamicLibraryBundle.java:56)
   at jogamp.openal.ALImpl$1.run(ALImpl.java:2250)
   at java.security.AccessController.doPrivileged(Native Method)
   at jogamp.openal.ALImpl.<clinit>(ALImpl.java:2247)
   at com.jogamp.openal.ALFactory.initialize(ALFactory.java:58)
   at com.jogamp.openal.ALFactory.getALC(ALFactory.java:92)
   at com.jogamp.openal.util.ALut.alutInit(ALut.java:66)
   at paulscode.sound.libraries.LibraryJOAL.init(LibraryJOAL.java:154)
   at paulscode.sound.SoundSystem.CommandNewLibrary(SoundSystem.java:1576)
   at paulscode.sound.SoundSystem.CommandQueue(SoundSystem.java:2572)
   at paulscode.sound.CommandThread.run(CommandThread.java:121)
Caused by: java.lang.NullPointerException
   at com.jogamp.common.os.NativeLibrary.isValidNativeLibraryName(NativeLibrary.java:259)
   at com.jogamp.common.util.cache.TempJarCache.findLibrary(TempJarCache.java:288)
   at com.jogamp.common.jvm.JNILibLoaderBase.loadLibraryInternal(JNILibLoaderBase.java:303)
   at com.jogamp.common.jvm.JNILibLoaderBase.access$000(JNILibLoaderBase.java:55)
   at com.jogamp.common.jvm.JNILibLoaderBase$DefaultAction.loadLibrary(JNILibLoaderBase.java:85)
   at com.jogamp.common.jvm.JNILibLoaderBase.loadLibrary(JNILibLoaderBase.java:215)
   at com.jogamp.common.os.DynamicLibraryBundle$GlueJNILibLoader.loadLibrary(DynamicLibraryBundle.java:365)
   at com.jogamp.common.os.Platform$3.run(Platform.java:317)
   at java.security.AccessController.doPrivileged(Native Method)
   at com.jogamp.common.os.Platform.loadGlueGenRTImpl(Platform.java:303)
   at com.jogamp.common.os.Platform.<clinit>(Platform.java:214)
   ... 12 more
The initialization of the sound manager (based on JOAL) failed: paulscode.sound.SoundSystemException: SoundSystem did not load after 30 seconds.

Starting up SoundSystem...
Initializing Java Sound
    (The Java Sound API.  For more information, see http://java.sun.com/products/java-media/sound/)
JavaSound initialized.

java.lang.NoClassDefFoundError: Could not initialize class com.jogamp.common.os.Platform
   at javax.media.opengl.GLProfile.<clinit>(GLProfile.java:81)
   at com.ardor3d.framework.jogl.JoglNewtWindow.<clinit>(JoglNewtWindow.java:37)
   at engine.service.Ardor3DGameServiceProvider.<init>(Ardor3DGameServiceProvider.java:212)
   at engine.service.Ardor3DGameServiceProvider.main(Ardor3DGameServiceProvider.java:159)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at com.sun.javaws.Launcher.executeApplication(Unknown Source)
   at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
   at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
   at com.sun.javaws.Launcher.run(Unknown Source)
   at java.lang.Thread.run(Unknown Source)
#### Java Web Start Error:
#### null 

You can launch it here:
http://tuer.sourceforge.net/very_experimental/tuer.jnlp

In my humble opinion, despite the bugs of some OpenGL drivers used in such a case, GlueGen should extract the native libraries that fit the best with the bitness supported by the JVM by relying on the property "sun.arch.data.model".
Comment 1 Sven Gothel 2012-01-04 19:22:57 CET
IMHO the bug description is wrong, since this setup, 32-on-64 
is working on all our test nodes (-> unit tests) incl. JOAL.
Besides, I have tested 32bit browsers on 64bit OS incl JOAL.

As far as I can read your exception, it's an NPE:

Caused by: java.lang.NullPointerException
   at
com.jogamp.common.os.NativeLibrary.isValidNativeLibraryName(NativeLibrary.java:259)
   at
com.jogamp.common.util.cache.TempJarCache.findLibrary(TempJarCache.java:288)
   at
com.jogamp.common.jvm.JNILibLoaderBase.loadLibraryInternal(JNILibLoaderBase.java:303)
   at
com.jogamp.common.jvm.JNILibLoaderBase.access$000(JNILibLoaderBase.java:55)
   at
com.jogamp.common.jvm.JNILibLoaderBase$DefaultAction.loadLibrary(JNILibLoaderBase.java:85)
   at
com.jogamp.common.jvm.JNILibLoaderBase.loadLibrary(JNILibLoaderBase.java:215)

Please rename the bug description (if bug still valid) and provide a 'trace'
w/ all debug infos on. Thank you Julien.
Comment 2 Sven Gothel 2012-01-04 20:13:16 CET
Additional notes ..

NativeLibrary.java line 259 of latest GlueGen source code
commit aa4cc872d630d7de170bdc4202d072220c053325:

+++
259: for(int i=0; i<prefixes.length; i++) {
+++

implies that 'prefixes' is null, which is set in the static init block
in a switch-case with default case.
How could this date be null at all ? Probably b/c of an unresolved 
initialization sequence / dependency, ie from:
  com.jogamp.openal.ALFactory.initialize(ALFactory.java:58)

where Platform is not initialized before actually attempting to 
call the NativeLibrary loading mechanism.

Pls try to call 'Platform.initSingleton()' upfront you overall demo
and tell me if this solves the issue. In this case, I will fix the lack 
of Platform initialization where it belongs, ie: ALFactory.

The same Platform.initSingleton() is performed in JOGL and JOCL, so it works there.

+++

'sun.arch.data.model' would not be sufficient for os_and_arch derivation.

We use 'os.name' and 'os.arch' in Platform to derive os_and_arch 
in the same manner as we use it at build time in gluegen's gluegen-cpptasks-base.xml.
This way we ensure same set of supported platforms and behavior.
Further more, we validate the findings w/ the runtime MachineDescription,
hence if our assumption is wrong GlueGen will immediatly throw an Exception and stop working.
Comment 3 Sven Gothel 2012-01-04 20:23:39 CET
Ok, fixed bug title and module. I am pretty sure my comment 2 describes the culprit.

JOAL commit c18c52b8c20aa03a08940bef81b620d48c4117e2 should fix this issue.

Please verify. If this commit does not fix the issue, pls
try to call Platform.initSingleton() upfront in you application.
In either case, pls write about the results / confirmation.
Comment 4 Julien Gouesse 2012-01-09 11:15:53 CET
Hi

I will update TUER in order to use GlueGen build 473, JOAL build 267 and JOGL build 618. I will reopen this bug if necessary, otherwise I will confirm this bug fix works.
Comment 5 Julien Gouesse 2012-01-09 22:59:25 CET
My demo now uses Updates JOGL 2.0 (build 620), JOAL 1.1.3 (build 268) and GlueGen (build 474) ,you can launch it here:
http://tuer.sourceforge.net/very_experimental/tuer.jnlp

I'm going to ask someone to test it again.
Comment 6 Julien Gouesse 2012-01-11 00:00:30 CET
I confirm this bug is fixed, EgonOlsen confirmed it works fine now :)
Comment 7 Sven Gothel 2012-01-11 12:39:11 CET
awesome.
Comment 8 Julien Gouesse 2013-03-07 23:41:09 CET
I reopen this bug because the loading of JOAL native libraries still fails when using a 32 bits JVM on a 64 bits OS, I get this on the laptop Packard Bell EasyNote MH36: 
[java] Exception in thread "Thread-9" java.lang.ExceptionInInitializerError
[java] 	at com.jogamp.openal.ALFactory.initialize(ALFactory.java:96)
[java] 	at com.jogamp.openal.ALFactory.getALC(ALFactory.java:140)
[java] 	at com.jogamp.openal.util.ALut.alutInit(ALut.java:66)
[java] 	at paulscode.sound.libraries.LibraryJOAL.init(LibraryJOAL.java:154)
[java] 	at paulscode.sound.SoundSystem.CommandNewLibrary(SoundSystem.java:1576)
[java] 	at paulscode.sound.SoundSystem.CommandQueue(SoundSystem.java:2572)
[java] 	at paulscode.sound.CommandThread.run(CommandThread.java:121)
[java] Caused by: java.lang.RuntimeException: Couln't load native AL library
[java] 	at jogamp.openal.ALImpl.<clinit>(ALImpl.java:1618)
[java] 	... 7 more
Comment 9 Julien Gouesse 2013-03-07 23:45:43 CET
Sorry, I was wrong, using a 64 bits JVM doesn't solve the problem.