Login  Register

Re: Running a JOGL app from a single JAR file

Posted by sasq on Jan 14, 2015; 4:14pm
URL: https://forum.jogamp.org/Running-a-JOGL-app-from-a-single-JAR-file-tp4033846p4033850.html

gouessej wrote
It's discouraged mainly because it mixes up everything (your code + third party libraries) together, making it hard to indicate that what was in a JAR came from a specific organization.

Couldn't I just make separate directories in the JAR file, one for my package, and one for the libraries?

gouessej wrote
It's possible but is it worth the effort? It depends on the size of your application.

For the production version, I guess it might be worth the effort (smaller downloads, less traffic for the server etc.). Expecially if generating of these files could be automated through some makefiles.

gouessej wrote
I advise you to make it work first with the JARs mentioned in the second post.
That's why I'm trying to do by now.
gouessej wrote
You don't need an IDE to make a fat JAR. There are some softwares for that but they are a lot less flexible than the build tools like Ant.
OK, so I decided to go with ant, since I already have it on my system. (Thanks for the tutorial! It was very helpful). Here's my first attempt at writing the build file:
<project name="TextureQuads" basedir="." default="main">
	
	<property name="src.dir"     value="src"/>
	<property name="lib.dir"     value="lib"/>
	<property name="assets.dir"  value="assets"/>
	
	<property name="build.dir"   value="build"/>
	<property name="classes.dir" value="${build.dir}/classes"/>
	<property name="jar.dir"     value="${build.dir}/jar"/>
	
	<property name="main-class"  value="texQuads.Main"/>
	
	<path id="classpath">
		<fileset dir="/usr/share/gluegen-2/lib" includes="gluegen-rt.jar"/>
		<fileset dir="/usr/share/jogl-2/lib"    includes="jogl.all.jar jogl.test.jar"/>
		<fileset dir="${lib.dir}" includes="**/*.jar"/>
	</path>
	
	<presetdef name="javac">
		<javac includeantruntime="false"/>
	</presetdef>
	
	
	<target name="clean">
		<delete dir="${build.dir}"/>
	</target>
	
	<target name="compile">
		<mkdir dir="${classes.dir}"/>
		<javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
	</target>
	
	<target name="jar" depends="compile">
		<mkdir dir="${jar.dir}"/>
		<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
			<manifest>
				<attribute name="Main-Class" value="${main-class}"/>
				<attribute name="Class-Path" value="/usr/share/gluegen-2/lib /usr/share/jogl-2/lib"/>
			</manifest>
		</jar>
	</target>
	
	<target name="run" depends="compile">
		<java classname="${main-class}" classpath="${classes.dir}" classpathref="classpath" fork="true"/>
	</target>
	
	<target name="run-jar" depends="jar">
		<java jar="${jar.dir}/${ant.project.name}.jar" fork="true"/>
	</target>
	
	<target name="clean-build" depends="clean,jar"/>
	
	<target name="main" depends="clean,jar"/>
	
</project>

Note that I deliberately set the Class-Path field in the manifest file to point to my system libs, because I wanted to test if it will run from the JAR at all before trying to package them into the JAR file itself.

Compilation goes without any errors. I can run the final app from the command line by using java -cp {path to the JOGL libs} texQuads/main and it runs fine. So it seems to work. But...

When I try to run the JAR file, it throws up:

run-jar:
     [java] Exception in thread "main" java.lang.NoClassDefFoundError: javax/media/opengl/GLEventListener
     [java]     at java.lang.ClassLoader.defineClass1(Native Method)
     [java]     at java.lang.ClassLoader.defineClass(ClassLoader.java:643)
     [java]     at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
     [java]     at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
     [java]     at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
     [java]     at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
     [java]     at java.security.AccessController.doPrivileged(Native Method)
     [java]     at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
     [java]     at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
     [java]     at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
     [java]     at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
     [java] Caused by: java.lang.ClassNotFoundException: javax.media.opengl.GLEventListener
     [java]     at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
     [java]     at java.security.AccessController.doPrivileged(Native Method)
     [java]     at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
     [java]     at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
     [java]     at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
     [java]     at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
     [java]     ... 11 more
     [java] Could not find the main class: texQuads.Main. Program will exit.
     [java] Java Result: 1

So it seems that I cannot even run it with the class path set to my system libs :-/ What did I do wrong?