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 |
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. |
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 |
This post was updated on .
EDIT: Reformatted using quote tags to clarify who said what.
Phil, I think the answer is "no", a rebuild should not be necessary. But I may be wrong. 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? 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 I think the answer to my question is that future Javas from Oracle will not support the current extension mechanism. Larry |
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 |
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 |
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
|
This post was updated on .
Julien,
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. 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. I won't. Thanks, Larry |
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 |
Administrator
|
Hi Larry
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. 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 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
|
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
|
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
|
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
|
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 |
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
|
Free forum by Nabble | Edit this page |