J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

Larry Tesler
I maintain a huge Windows 7 standalone application I'll call "BigOldApp". A tested JRE is bundled with the product. I recently upgraded the environment from 32-bit Java 6 to 64-bit Java 7. I migrated a 3D graphics feature from 32-bit to 64-bit Java3D using JogAmp's Java3D pre12 + JOGL 2.3.2 + Gluegen 2.3.2.

I created an Eclipse project named JOGL as suggested in the documentation. I included source code just for debugging purposes. Because an IT security policy regarding temporary files caused Automated Native Library Loading to crash, I gave up on automation and got the application working inside Eclipse by adding:

        -Djogamp.gluegen.UseTempJarCache=false
        -Djava.library.path=C:\Users\myname\workspace\JOGL\jogamp-all-platforms\lib\windows-amd64

to VM args and by setting the native library locations of gluegen-rt and jogl-all to

        JOGL/jogamp-all-platforms/jar/atomic

BigOldApp only calls Java3D if and when the user invokes the 3D feature.

It works like a charm. Inside Eclipse, that is.

Next, I ran MyApp's legacy ANT script to consolidate code from three legacy Eclipse projects plus the bundled Java plus the newly added JOGL:

        BigOldApp
        BigOldLib
        BigOldImporter
        JRE
        JOGL

I will run an existing installer soon using NSIS but first I want to prove that ANT did the right thing.

The legacy Ant scripts built a directory hierarchy at the top level of the Eclipse workspace. Among other things, this directory contains:

        BigOldApp.exe
        BigOldApp.bat
        lib
           BigOldApp.jar

The app launched but the 3D feature crashed with:

Exception in thread "AWT-EventQueue-0" java.lang.
UnsatisfiedLinkError: C:\Users\tesllar\Desktop\BigOldVendor\BigOldApp\Development\Installer Development\NSIS\BigOldApp\jre\bin\J3D.dll: Can't load a 32-bit .dll on a AMD 64-bit platform
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1965)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1890)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1872)
        at java.lang.Runtime.loadLibrary0(Runtime.java:849)
        at java.lang.System.loadLibrary(System.java:1088)
        at javax.media.j3d.MasterControl$22.run(MasterControl.java:889)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.media.j3d.MasterControl.loadLibraries(MasterControl.java:886)
        at javax.media.j3d.VirtualUniverse.<clinit>(VirtualUniverse.java:229)

I added the recommended VM ARGS to the batch file but it made no difference.

I added no code to the legacy Ant scripts or JOGL's barebones Ant scripts. Is that why it grabbed a 32-bit dll instead of the requested 64-bit version? What's the recommended way to integrate Ant processing into a Java3D+JOGL build process?

Thanks,

Larry Tesler
Reply | Threaded
Open this post in threaded view
|

Re: J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

philjord
Larry,
This looks like a fairly common problem (I hope).

The dll you are loading J3D.dll is from the older versions of Java3D before Jogamp took it over.

Also the line in MasterControl
 at javax.media.j3d.MasterControl$22.run(MasterControl.java:889)
Definately doesn't match Java3D 1.6.2 code.

Often this is caused because your installation of Java has the java3D jar files installed into the extension folder (very common on MacOS) and those jar files are loaded before anything on your class path.

So the first step would be to open the jre/ext folder and see what's in there, probably this folder
 C:\Users\tesllar\Desktop\BigOldVendor\BigOldApp\Development\Installer Development\NSIS\BigOldApp\jre\lib\ext\

If there is any Java3D jar files in there then that's the issue.

The easiest thing to do is then delete the java3d jars (including vecmath.jar) from that folder and re-test.

However this is often not a solution if you are deploying to machines with a pre-installed JRE.
If you are unable to change the users ext folder you will need to either:
A/ change to Java3D 1.7 where all package names have been altered to not match the legacy names.
B/ use something like -Djava.ext.dirs=.\none\ in your start up properties. Though this this you can't access any jar in the ext folder and so you'd need to find what you use (if anything) and move it into your project (a good idea anyway).

So take a look and see if this is the issue.

Thanks,
Phil.


Reply | Threaded
Open this post in threaded view
|

Re: J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

Larry Tesler
Phil,

I don't think I would have diagnosed this problem correctly without your help.

> Often this is caused because your installation of Java has the java3D jar files installed into the extension folder (very > common on MacOS) and those jar files are loaded before anything on your class path.
>
> So the first step would be to open the jre/ext folder and see what's in there, probably this folder
>  C:\Users\tesllar\Desktop\BigOldVendor\BigOldApp\Development\Installer Development\NSIS\BigOldApp\jre\lib\ext\
>
> If there is any Java3D jar files in there then that's the issue.

All four j3d jars were there. I had thought it would be enough to remove all explicit references to them but I was wrong.
 
> The easiest thing to do is then delete the java3d jars (including vecmath.jar) from that folder and re-test.

*** QUESTION: Should I remove the four jars from the Eclipse project's jre\lib\ext and rebuild? ***

To test the idea quickly, I did not rebuild. All I did was to remove the jars from the built application's jre\lib\ext. Then I tried run.bat, which does this:

jre\bin\java -Djogamp.gluegen.UseTempJarCache=false -Djava.library.path=C:\Users\tesllar\workspace\JOGL\jogamp-all-platforms\lib\windows-amd64 -Xms256m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -jar .\lib\BigOldApp.jar "%1"

Result:

Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: javax/media/j3d/Canvas3D
...
Caused by: java.lang.ClassNotFoundException: javax.media.j3d.Canvas3D
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        ... 41 more

> However this is often not a solution if you are deploying to machines with a pre-installed JRE.

We bundle a tested JRE in the application. We have control over what's in ext.

> If you are unable to change the users ext folder you will need to either:
> A/ change to Java3D 1.7 where all package names have been altered to not match the legacy names.

"A" sounds appealing. I will look into it.

> B/ use something like -Djava.ext.dirs=.\none\ in your start up properties. Though this this you can't access any jar in > the ext folder and so you'd need to find what you use (if anything) and move it into your project (a good idea anyway).

The app uses several things in ext. Why is it a good idea to move them into the project? One downside: Whenever we release an app update with a different jre bundled, we'll have to repeat the surgery.

Thanks,

Larry
Reply | Threaded
Open this post in threaded view
|

Re: J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

Larry Tesler
This post was updated on .
EDIT: Reformatted using quote tags to clarify who said what.

Phil,
Larry Tesler wrote
philjord wrote
The easiest thing to do is then delete the java3d jars (including vecmath.jar) from that
folder and re-test.
*** QUESTION: Should I remove the four jars from the Eclipse project's jre\lib\ext and rebuild? ***
I think the answer is "no", a rebuild should not be necessary. But I may be wrong.
Larry Tesler wrote
philjord wrote
 A/ change to Java3D 1.7 where all package names have been altered to not match the
legacy names.
"A" sounds appealing. I will look into it.
I haven't found a download site for Java3D 1.7. What I've read about it is several months old.
Is it something that could ship in a product? Is it in GitHub? Where?
philjord wrote
B/ use something like -Djava.ext.dirs=.\none\ in your start up properties. Though
this this you can't access any jar in > the ext folder and so you'd need to find what you
use (if anything) and move it into your project (a good idea anyway).
Into my BigOldApp project? What's involved in moving (for example) SunJCE into BigOldApp? Just
dragging the jar file from jre\lib\ext to BigOldApp\lib (or BigOldApp\lib\anydir)? Revise the
classpath? Rebuild?

ADDED,EDITED,EDITED: I found a book chapter on line (Java Security, 2d Ed., O'Reilly, May 2000). It uses SunJCE as an example of a library that can live in "ext" ("installed") or elsewhere ("unbundled" with edits to java.policy). The files and directories in the example are somewhat obsolete--or evolved--but perhaps the process hasn't changed, or there's better documentation now?
    http://www.onjava.com/excerpt/java_security_ch1
Larry Tesler wrote
The app uses several things in ext. Why is it a good idea to move them into the
project? One downside: Whenever we release an app update with a different jre bundled,
we'll have to repeat the surgery.
I think the answer to my question is that future Javas from Oracle will not support the current
extension mechanism.

Larry
Reply | Threaded
Open this post in threaded view
|

Re: J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

Larry Tesler
I just realized that I have been using Java3D 1.6.0-pre12 + JOGL 2.3.1 (not 2.3.2) + Gluegen 2.3.1 (not 2.3.2).

Does that alter the diagnosis or the advice?

Larry
Reply | Threaded
Open this post in threaded view
|

Re: J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

Larry Tesler
Java3D list members: If you spot anything amiss or questionable about my config, please let me know.

DOWNLOADS INSTALLED

    J3D version 1.6.0.
    JOGL version 2.3.1.
   
    The Ant script "java3d-core-master/build.xml" refers to:
   
        <property name="jogl.lib"          location="../jogl-v2.3.1/jogl-all.jar"/>
        <property name="gluegen.lib"       location="../jogl-v2.3.1/gluegen-rt.jar"/>
        <property name="version_base"      value="1.6.0"/>

    https://jogamp.org/deployment/java3d/1.6.0-pre12/
           
        JOGL sources, jars and dlls; Java3D jars
   
                jogamp-java3d.7z 21-Apr-2015 19:00  1.1M
                j3dcore.jar 20-Apr-2015 05:23  2.7M  
                j3dutils.jar 20-Apr-2015 05:24  1.6M  
               
    Java3D jars
 
                vecmath.jar 20-Apr-2015 05:21  306K  

    Java3D sources
   
        https://github.com/hharrison/java3d-core (Download ZIP)
        https://github.com/hharrison/java3d-utils (Download ZIP)
        https://github.com/hharrison/vecmath (Download ZIP)


JAVA BUILD PATH (Eclipse)

Source tab: blank

Projects tab: blank

Libraries tab:

        (None) for all Javadoc locations and Access rules
       
        gluegen-rt.jar - JOGL/jogamp-all-platforms/jar
                Source attachment: gluegen-java-src.zip - JOGL/jogamp-all-platforms
                Native library location: JOGL/jogamp-all-platforms/jar/atomic
       
        j3dcore.jar - JOGL/jogamp-java3d/jar
                Source attachment: src - JOGL/source-code-of-java3d/java3d-core-master
                Native library location: (None)
       
        j3dutils.jar - JOGL/jogamp-java3d/jar
                Source attachment: src - JOGL/source-code-of-java3d/java3d-utils-master
                Native library location: (None)
       
        jog-all.jar - JOGL/jogamp-all-platforms/jar
                Source attachment: jogl-java-src.zip - JOGL/jogamp-all-platforms
                Native library location: JOGL/jogamp-all-platforms/jar/atomic
       
        vecmath.jar - JOGL/jogamp-java3d/jar
                Source attachment: src - JOGL/source-code-of-java3d/vecmath-master
                Native library location: (None)
               
        JRE System Library [jdk1.7.0_80]
       
Order and Export tab:

        [X] gluegen-rt.jar - JOGL/jogamp-all-platforms/jar
        [X] jog-all.jar - JOGL/jogamp-all-platforms/jar
        [ ] JRE System Library [jdk1.7.0_80]
        [X] j3dcore.jar - JOGL/jogamp-java3d/jar
        [X] j3dutils.jar - JOGL/jogamp-java3d/jar
        [X] vecmath.jar - JOGL/jogamp-java3d/jar

My application bundles a specific JDK version [jdk1.7.0_80] living in C:\Program Files\Java for use by Eclipse, by the app to run within Eclipse, and (as a copied JRE) for use by the built release.

Larry
Reply | Threaded
Open this post in threaded view
|

Re: J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

gouessej
Administrator
This post was updated on .
In reply to this post by Larry Tesler
It's explained in the Java3D user's guide I wrote, you MUST use Java3D 1.6.0-pre12 with JOGL 2.3.2. There is no DLL in Java3D itself since I removed the crappy unmaintained native renderers not based on JOGL.

P.S: Actually, if you really want to build Java3D, you should use my repository but ... it's Java3D 1.7.0, the imports aren't the same...

P.S: Please don't use the extension mechanism, it's only a source of trouble. Ensure that there is no library elsewhere that could cause a conflict, look at your path and your classpath. There is no complicated surgery to do, you can merge all JARs into one but having to handle the native libraries separately because of a corporate policy that blocks the automated native library loading drives things less simple.

Relying on the extension mechanism is a really poor decision, I wrote that it's going to be completely removed from Java. It has been an endless source of version conflicts, it can break applets and applications that require different versions...
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

Larry Tesler
This post was updated on .
Julien,

gouessej wrote
It's explained in the Java3D user's guide I wrote...
At what URL is the most current version of your guide?

EDIT: If it's https://gouessej.wordpress.com/2012/08/01/java-3d-est-de-retour-java-3d-is-back/, I have read it many times. It is dated 2012 but it does seem to link to the late 2015 archive. I'll try to follow it again.
gouessej wrote
P.S: Actually, if you really want to build Java3D, you should use my repository but ... it's Java3D 1.7.0, the imports aren't the same...
Is https://libraries.io/github/scijava/java3d-core the repo you speak of? If not, what is the URL of the repo you meant and what are the major pros and cons?

EDIT: I see that scijava is ctrueden's and yours are at https://github.com/gouessej?tab=repositories.
gouessej wrote
Relying on the extension mechanism is a really poor decision
I won't.

Thanks,

Larry
Reply | Threaded
Open this post in threaded view
|

Re: J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

Larry Tesler
Please keep in mind that my current tool set is Eclipse (4.2.2), CVS (not yet git or svn) and ANT (not yet Maven). Once I have released the next version of BigOldApp, changing to a different tool set for subsequent releases will be very much on the table.

If I could get past these Java3D issues, BigOldApp would be essentially ready to release. I am oh so close...

Larry
Reply | Threaded
Open this post in threaded view
|

Re: J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

gouessej
Administrator
Hi Larry

Larry Tesler wrote
Julien,

gouessej wrote
It's explained in the Java3D user's guide I wrote...
At what URL is the most current version of your guide?

EDIT: If it's https://gouessej.wordpress.com/2012/08/01/java-3d-est-de-retour-java-3d-is-back/, I have read it many times. It is dated 2012 but it does seem to link to the late 2015 archive. I'll try to follow it again.
My tutorial is frequently updated, there is no need to rewrite it from scratch. I update it only when I'm sure of what I'm going to do in order to confuse my readers.

Larry Tesler wrote
gouessej wrote
P.S: Actually, if you really want to build Java3D, you should use my repository but ... it's Java3D 1.7.0, the imports aren't the same...
Is https://libraries.io/github/scijava/java3d-core the repo you speak of? If not, what is the URL of the repo you meant and what are the major pros and cons?

EDIT: I see that scijava is ctrueden's and yours are at https://github.com/gouessej?tab=repositories.
gouessej wrote
Relying on the extension mechanism is a really poor decision
I won't.

Thanks,

Larry
ctrueden's fork isn't maintained by the JogAmp community. ctrueden's contributions have been very valuable :)

I was talking about my repositories:
https://github.com/gouessej/java3d-core
https://github.com/gouessej/vecmath
https://github.com/gouessej/java3d-utils

Larry Tesler wrote
Please keep in mind that my current tool set is Eclipse (4.2.2), CVS (not yet git or svn) and ANT (not yet Maven). Once I have released the next version of BigOldApp, changing to a different tool set for subsequent releases will be very much on the table.

If I could get past these Java3D issues, BigOldApp would be essentially ready to release. I am oh so close...

Larry
Actually, when I look at your very first error message, I assume that you packaged your software with the wrong version of the JRE, there is a problem of bitness. You try to use a 64-bit JRE with 32-bit native libraries.

I've just looked at your very first stack trace and I can confirm that your program doesn't use Java3D 1.6 or 1.7, there is no call to System.loadLibrary() in the MasterControl class since the pre-build in which I removed the native renderers:
https://github.com/gouessej/java3d-core/blob/master/src/main/java/org/jogamp/java3d/MasterControl.java
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

gouessej
Administrator
In reply to this post by Larry Tesler
To sum up, your problem comes from some JARs loaded in priority somewhere on your machine, those JARs come from Java3D 1.5 which is NOT maintained by the JogAmp community. When you remove those crappy obsolete stuff, you'll solve your problem of crash as we don't even call System.loadLibrary() in MasterControl. If JOGL 2.3.2 is in the classpath with the right native libraries in the Java library path, it will work.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

gouessej
Administrator
In reply to this post by Larry Tesler
Hi

In my humble opinion, you should rebuild your software with Java3D 1.6.0-pre12, it doesn't require to rebuild Java3D itself. When you run your test, you must ensure that the JARs of Java3D 1.6.0-pre12 and the JAR(s) of JOGL 2.3.2 & GlueGen containing the Java libraries are in the classpath, you must ensure that no JAR of other versions is somewhere in your classpath or in any directories used by the extension mechanism, you must ensure that the Java library path points to the directory containing the native libraries of JOGL 2.3.2 & GlueGen, you must ensure that no native library of other versions are in a directory in your PATH environment variable or in any other directory used by the JRE to look for the native libraries and you must ensure that your launch script uses the bundled JRE with the right bitness (64-bit JRE -> 64-bit native libraries).

If you get another UnsatisfiedLinkError within Java3D but not in JOGL and/or GlueGen, especially in MasterControl, it will mean that your software still doesn't use Java3D 1.6.0-pre12. If you get an UnsatisfiedLinkError elsewhere in JOGL and/or GlueGen, there will be a problem of bitness (64-bit/32-bit) or you use two different versions of the libraries, the Java libraries don't match with the native libraries, for example you use JOGL 2.3.2 Java libraries with JOGL 2.3.1 native libraries.

If you get a ClassNotFoundException in javax.*, you still use an old version of Java3D that looks for the JOGL classes in their old location. If you get a ClassNotFoundException in com.jogamp.* or jogamp.*, you probably use the right version of Java3D but with an obsolete version of JOGL.

The Ant script to build Java3D 1.6.0-pre12 might be a little bit buggy. I advise you to use our JARs in the meantime, until you can modify your toolset to build Java3D 1.7 yourself with Maven.

The very first problem Philjord pointed out concerning MasterControl was easy to find as I indicated in my tutorial where the source code of Java3D is and Harvey's source code doesn't call System.loadLibrary() in MasterControl. What's the point of using an open source library if you don't look at its source code when something goes wrong? You claimed that you read my user's guide several times but most of the possible problems you mentioned were mentioned in it, in the troubleshooting section, in "Conflict with an obsolete version".

Keep in mind that we do our best to help you but most of those problems could occur with any other Java library. It's not specific to JOGL. Good luck.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

gouessej
Administrator
In reply to this post by Larry Tesler
By the way, I suspect that you put an old version of Java3D directly into your bundled JRE, your very first error message shows an old DLL of Java3D <= 1.5.2 in jre/bin. You removed 4 JARs from C:\Users\tesllar\Desktop\BigOldVendor\BigOldApp\Development\Installer Development\NSIS\BigOldApp\jre\lib\ext but your software must be built with Java3D 1.6.0-pre12 and don't forget this part of the Java manual concerning "java -jar":
"When you use this option, the JAR file is the source of all user
              classes, and other user class path settings are ignored."

Please look at this part of an Oracle tutorial:
https://docs.oracle.com/javase/tutorial/deployment/jar/downman.html
You must set the Class-Path manifest attribute correctly so that your software finds the third party libraries (except if you make a big fat JAR).
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

Larry Tesler
In reply to this post by gouessej
All your messages today will be VERY helpful.

Status:

A legacy ANT script builds my application and bundles a modified jre into it.

I discovered yesterday that the script adds a lot of jars to jre/lib/ext. Not good! And it seems to install two copies of that lib into the built application (one parallel to jre and one inside it), each with a copy of ext. Ugh.

I need to make sure that it doesn't do anything that undermines what you have taught me.

I will let you know when I have succeeded or get stumped.

Thanks,

Larry
Reply | Threaded
Open this post in threaded view
|

Re: J3D+JOGL good within Eclipse but UnsatisfiedLinkError as standalone

gouessej
Administrator
You're welcome.

You can move those JARs from jre/lib/ext into another directory except the useless ones (old versions of JOGL, GlueGen and Java3D). Of course, you can use Ant to make a new JAR manifest with the Class-Path manifest attribute correctly set. If some of them use a service provider, they might need some additional considerations (the provider-configuration file must be in META-INF/services). Good luck.
Julien Gouesse | Personal blog | Website