Running opengl jogamp from jar - java

I've written a program that uses opengl that I have been running without issue form within eclipse, and I now want to package it up into a jar for deployment.
I'm using maven to manage all the dependencies and the build process. I've done a clean and package to build a jar with all the necessary dependencies, but I'm having trouble getting it to actually run.
It seem to be looking for files outside of the jar file, for example gluegen-rt.dll, which I can see is in the jar at the top level. It also seems like it's trying to reference a version of my jar with '-natives-windows-amd64' appended to the name.
When I try and run it I get the following error:
D:\My Documents\workspace\Cube\target>java -jar cube-0.0.1-SNAPSHOT-jar-with-dependencies.jar 10 OPENGL
Catched FileNotFoundException: D:\My Documents\workspace\Cube\target\cube-0.0.1-SNAPSHOT-jar-with-dependencies-natives-windows-amd64.jar (The system cannot find the file specified), while addNativeJarLibsImpl(classFromJavaJar class com.jogamp.common.os.Platform, classJarURI jar:file:/D:/My%20Documents/workspace/Cube/target/cube-0.0.1-SNAPSHOT-jar-with-dependencies.jar!/com/jogamp/common/os/Platform.class, nativeJarBaseName
cube-0.0.1-SNAPSHOT-jar-with-dependencies-natives-windows-amd64.jar): [ file:/D:/My%20Documents/workspace/Cube/target/cube-0.0.1-SNAPSHOT-jar-with-dependencies.jar -> file:/D:/My%20Documents/workspace/Cube/target/ ] + cube-0.0.1-SNAPSHOT-jar-with-dependencies-natives-windows-amd64.jar -> slim: jar:file:/D:/My%2520Documents/workspace/Cube/target/cube-0.0.1-SNAPSHOT-jar-with-dependencies-natives-windows-amd64.jar!/
Exception in thread "main" java.lang.UnsatisfiedLinkError: Can't load library: D:\My Documents\workspace\Cube\target\gluegen-rt.dll
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.load0(Unknown Source)
at java.lang.System.load(Unknown Source)
at com.jogamp.common.jvm.JNILibLoaderBase.loadLibraryInternal(JNILibLoaderBase.java:551)
at com.jogamp.common.jvm.JNILibLoaderBase.access$000(JNILibLoaderBase.java:64)
at com.jogamp.common.jvm.JNILibLoaderBase$DefaultAction.loadLibrary(JNILibLoaderBase.java:96)
at com.jogamp.common.jvm.JNILibLoaderBase.loadLibrary(JNILibLoaderBase.java:414)
at com.jogamp.common.os.DynamicLibraryBundle$GlueJNILibLoader.loadLibrary(DynamicLibraryBundle.java:388)
at com.jogamp.common.os.Platform$1.run(Platform.java:209)
at java.security.AccessController.doPrivileged(Native Method)
at com.jogamp.common.os.Platform.<clinit>(Platform.java:179)
at javax.media.opengl.GLProfile.<clinit>(GLProfile.java:83)
at ui.jogl.JOGLCube.init(JOGLCube.java:52)
at ui.jogl.JOGLCube.<init>(JOGLCube.java:44)
at ui.jogl.JOGLCubeController.<init>(JOGLCubeController.java:19)
at core.Cube.getVirtualCube(Cube.java:37)
at core.Cube.<init>(Cube.java:27)
at core.Cube.main(Cube.java:56)
I have no prior experience working with OpenGL so any help would be greatly appreciated.
Thanks for reading

You won't be able to get your application in a single jar. JOGL is a pretty sophisticated library of several jars (and optionally DLLs, too) that must be installed correctly in the same folder as your application jar.
I don't know exactly how to set this up in Eclipse (my experience is Netbeans, which IMO is a much more robust build environment) but the issue is that the DLLs for the native part of JOGL are not being found. JOGL uses a slightly crazy method: the DLLs are packaged in jar files, and the library dynamically expands them in place at run time, then attaches them. The name of this file for your architecture is jogl-all-natives-windows-amd64.jar. In general, you should have all these jars with names of the form jogl-all-natives-*.jar in the same directory as your app's jar file.
The problem with the above is that the user of your app must have write permission in a place from which DLLs can be loaded. This can conflict with many enterprise security policies (enforced e.g. by Active Directory push). If you have a wide user population, this will not work for enough users to cause serious pain. The app I've been working on must run in schools internationally. There is no way the all-in-one JAR mechanism can be used for this.
The other way forward is to use the separate native DLLs in the lib folder of the jogamp distribution, placing them in a lib directory that's on the java.library.path of the application.
In all cases, you will need an installer to place the multiple jars, DLLs, and perhaps other files of your system in the right places. I use NSIS for this. It's not as polished as a commercial installer builder, but it's good enough to do multi-jar Java app installers. If you want to check out the way my JOGL app handles installation for Windows and Mac, see Bridge Designer and Contest.
A final note is that if you don't have perfect control over the machines where your app will deploy strongly consider packaging a Java Runtime in your installer. Dealing with the gajillipon ways users can dork up java installation is not much find. A built-in JRE makes the download package much bigger, but in my experience, this causes much less pain than the alternative of dealing with what's on the user machine.
This information (albeit in a not so readable format) is documented on the JOGL deployment Wiki.

I do it for my game (Truly Unusual Experience of Revolution®). It's currently supported. Please look at this page of the wiki:
http://jogamp.org/wiki/index.php/JogAmp_JAR_File_Handling
You have to follow a certain layout to allow GlueGen to find your native libraries for JOGL, JOAL and JOCL:
http://forum.jogamp.org/Packaging-JOGL-projects-to-be-cross-platform-tp4031261p4031286.html
If your project is under GPL, feel free to look at my Ant target "create-jars" in my Ant build script:
http://svn.code.sf.net/p/tuer/code/pre_beta/build.xml
You don't need to set the Java library path, you don't need to use the DLLs, just use the JARs containing the Java libraries and those containing the native libraries.
Keep in mind that the defaut archiver (Ark, WinRAR, ...) might open your JAR when double-clicking on it instead of running your application. I advise you to wrap your JAR into a native application bundle. You can use Packr, Launch4j or NSIS to do so. My script above uses my Ant target "create-app" (inspired by Packr, still using its native launcher) for Mac OS X to create a .app zipped file. Good luck.
P.S: If you're "bothered" by my use of the GPL, you can look at my tutorial for JogAmp's Ardor3D Continuation that deals with this aspect.

Related

“no sigar-winnt.dll in java.library.path” error when using SIGAR

I'm very new to java. I'm developing a tool that checks if your PC meets some set of specifications. This included writing and executing a separate batch file and including an API (SIGAR) for the model of the CPU.
My problem is that when I tried exporting it to Runnable JAR in eclipse, and I ran the resulting JAR from command line, it gave me lots of 'DLL not included in build path' Exceptions. After including the folder that contains the API DLL in the build path, I got similar exceptions. The thing that fixed it was adding the folder containing the DLL to environment variables (PATH) in Advanced System Settings.
Questions:
The JAR now works fine on my computer, but what about the users who download the JAR? Will they also need to add the DLL to environment variables? If so is there a way the JAR can do that for them?
My JAR won't run with a double-click, but will run from command line. Is there any way around this that will carry over to users who download the JAR too?
If the user downloads the tool and can't run it because they don't have the right version of the JRE, will the tool notify them? If not, is there a way around the user having to update JRE or will wrapping as an EXE suffice?
Thanks in advance, much appreciated. Lots of questions.
Q1: The JAR now works fine on my computer, but what about the users
who download the JAR? Will they also need to add the DLL to
environment variables? If so is there a way the JAR can do that for
them?
You can put a DLL inside a JAR file:
How to make a JAR file that includes DLL files? (Hint: read both answers ... completely.)
However, when you distribute a JAR containing a DLL, you then have the problem that different platforms require different DLLs (or whatever). Even with Windows you have the problem of 32 bit versus 64 bit DLLs.
Q2: My JAR won't run with a double-click, but will run from command
line. Is there any way around this that will carry over to users who
download the JAR too?
You cannot address that problem in a JAR file. The "double-click to run" functionality is implemented by the OS. The best way to provide this kind of functionality is using (platform specific) wrapper scripts that are double-clickable.
Q3: If the user downloads the tool and can't run it because they don't
have the right version of the JRE, will the tool notify them? If not,
is there a way around the user having to update JRE or will wrapping
as an EXE suffice?
Unless you have a JRE installed, the JAR file is just a passive blob of data. (A ZIP file, actually).
If the user has a JRE that is too old, then either the JRE will be unable to load any classes in the JAR (because the classfile version number is wrong), or you will get errors because of missing (system) classes.
The only hope would to do something like providing a wrapper script to launch your application that checked the JRE version before attempting to launch the JAR.
As a general rule, if you want to do fancy stuff like this you need to distribute your program in an installer, not as a bare JAR file.

Creating an installer for Java desktop application

I know this question has been asked many a times and all the time there is an answer which says about using an executable jar or making an .exe using launch4j or similar app.
I may sound like a novice, which I actually am.
I have been trying a few things with a Java project. I have successfully made an executable jar and also an .exe file from it. All thanks to your previous answers in SO :)
But, I want to create a installer for Windows. Like, pressing Next for 2 - 3 times(which shows all the terms and conditions etc), then a user specify a location(like C:\Program Files\New Folder\My App), then my .exe, lib folder, img folder, other important folders get pasted in the destination folder along with the .exe file and then a shortcut is created on a desktop.
Any pointers to how can I achieve this ?
I have been using InnoSetup for a long time. It has always worked very well. It can do everything you need (unpack files, put shortcuts on desktop, start menu etc) and generates installers that we are used to.
If you want free and open source, you could take a look IzPack. We use this at work for its command line support in our builder.
You could also take a look install4j which is a commercial product we've trialed on and off before (but when it comes to spending money, you tend to want to know you're getting what you want ;))
If you are on JDK 13 or above, you can package any Java program along with its runtime by using the default packaging tool in the JDK called jpackage.
jpackage can create installers for Linux, Mac and Windows operating system.
You can create a specific runtime by using jlink.
jpackage needs some 3rd party free software for creating Windows bundles:
* To create .exe bundle, it uses Wix
* To create .msi bundle, it uses Inno
Wix is now the only dependency to create both exe and msi bundles.
All the details about jpackage can be found at JEP 343: Packaging Tool.
Edit: I'll leave this here for reference, but note: The Java plug-in needed to launch JWS and applets was removed by browser manufacturers, and both were deprecated in Java 9 and removed from the API.
Use Java Web Start.
Like, pressing Next for 2 - 3 times (which shows all the terms and conditions etc)
The ExtensionInstallerService of the JNLP API provides this. Here is a demo. of the installer service.
..then a user specify a location(like C:\Program Files\New Folder\My App), ..
The ExtensionInstallerService provides a method getInstallPath() which..
Returns the directory where the installer is recommended to install the extension in. It is not required that the installer install in this directory, this is merely a suggested path.
That is not quite the same as what you are asking, but then I think it is generally a bad idea to allow the user that level of control.
then my .exe, lib folder, img folder, other important folders get pasted in the destination folder along with the .exe file ..
JWS installs the resources mentioned in the JNLP automatically, as and when they are needed. Further, it updates the resources if the archives on the server change.
and then a shortcut is created on a desktop.
JWS can supply desktop shortcuts and menu items on supported systems.
E.G.
From How to run Java programs by clicking on their icon on Windows?
This answer, which shows a JWS app. installed in 'Programs and Features', with the desktop icon to the left of it.
I was in the same situation a few months ago. After trying out a lot. I suggest NSIS. There is a nice plug-in for Eclipse EclipseNSIS with some templates. It helps a lot to get a basic installer with just some easy clicks. If the resulting code is not sufficient you can do the rest work by coding, but most of the code is generated by EclipseNSIS.
You can also use Advanced Installer. Since you already have an EXE to launch your JAR, you don't need to use the Java Launcher support from Advanced Installer, you can create a Simple project, which is available in the free edition, so you don't need to purchase a license.
It will take you maximum 10 minutes to install it and create the setup package, as you will see it is very easy to learn using it.
use Launch4j to create exe file. you must give the relative path to jre folder.
next use Inno Setup to make setup. You can bundle jre inside the installer.
I've use it and it works like a magic. I can show details.
I wanted to share another project. This project have two part:updating your desktop app and ready installers for mac os, linux, windows. If you want only installer so you can adopt for your needs documentation in this way you should replace starter-core-1.0.jar with your jar

When I attempt to run my .jar, I get a no library in java.library.path exception

I've looked through a number of posts, and tried what I've found to little success. Here's the setup:
I wrote a program in Java, worked alright, but we needed to switch cameras. This camera is Twain compatible (yuck). I rewrote the program (pretty simple), using JTwain, and it runs just fine in netbeans. I built it, and it runs just fine on my computer. However, when I try and transfer the .jar (and companion library etc.), it runs fine until it needs to take an image, then I get the error:
java.lang.UnsatisfiedLinkError: no aspireJTwain in Java.library.path.
I've tried bringing the base twain package over, adding the system environmental variables, checking the java distribution. I can run the JTwain test file (to make sure you have JTwain and everything is hunky dory).
If someone could please lend a hand, I'd be much obliged.
Can you check to make sure that you have followed the directions from the The Java Developer's Guide to JTwain v9.
6.3 Software Packaging and Distribution
There are two files about JTwain you need to distribute along with
your own binary code. One is JTwain.jar, which is like any other java
library, you can just copy it and put it in the class path. The other
one is AspriseJTwain.dll, the native library. There are many ways to
'install' this dll file, you can: Add the folder containing the
native library to the system path, or Copy the native library to
jre/bin directory – 'install' the library to the JVM, or Copy the
native library to a specific location, e.g. C:\AspriseJTwain.dll,
before calling SourceManage.instance(), call:
SourceManage.setLibraryPath(“ C:\AspriseJTwain.dll ”);

using cygwin compile java file to windows native code

I have written a small java application for one of my homework. the problem is the teacher may not have JRE installed. what i want to id to compile the java file to window exe file so the teacher can run it without the JRE installed.
i use the gcj tool in the cygwin , but the output application seem to need the cygwin1.dll to run. how can i avoid this, IE package all the things the application need to a single file, so the teacher don't have to install anything.
Use MinGW instead of Cygwin.
And get ready for a 10-MiB executable.
Why don't you just ask your teacher to install a JRE, or if they have one? If you are allowed to use Java, then I'm certain the teacher will be required to have the tools for properly evaluating your homework.
If you weren't allowed to use Java, well then, what were were you thinking?
The application seem to need the cygwin1.dll to run.
Shipping an .exe with an cluster of .dll files is the norm on Windows.
If you use Microsoft Visual Studio, your program will also need be shipped with some libraries from the Visual Studio Redistributable Run-Time. (Unless you link it statically.) Most major applications on Windows have installation directories chock full of dll files, and won't run without them.
In the middle of 2016, the Cygwin project changed the licensing from GPL to LGPL. This means you can link programs with to cygwin1.dll and redistribute them, even if those programs have a license that is not compatible with the regular GPL, such as closed-source, non-freely-redistributable, proprietary programs. (If you otherwise comply with the LGPL in regard to how you are redistributing cygwin1.dll itself, of course).
IE package all the things the application need to a single file, so the teacher don't have to install anything.
The only way not to install anything is not to have a file at all. If there is a single file it has to be put somewhere, and that meets the definition of installation. On Windows, if you have a .exe file that depends on a .dll, all you have to ensure is that they are put into the same directory. This requirement can be met as easily as by putting them into a .zip file, if the program is too unimportant to warrant developing a full blown installer.
Your teacher unzips your .zip file on their Desktop, or in their Downloads directory. A folder should appear, and in that folder is your program and the dll. The program can be invoked and loads the dll; no brainer.

JNI-wrapped library seeks out wrong working directory -- how to circumvent?

I am using JNI to wrap a few native functions in a closed-source PDF library. It has an dependent fonts directory which must be in a subfolder of the calling application's directory. In my experience, it is standard to seek based on the current working directory. Thus, the problem.
When loading the JNI code into a Java application, the current working directory is correct. However, the calling application's directory is java.exe's bin directory. I have verified that putting the dependent fonts folder in C:\Program Files (x86)\Java\jre6\bin folder works as expected.
The library seems to be using a C++ GetCommandLine() call, or something similar to determine where the fonts directory should be. Obviously, this is an unacceptable solution.
I'd like to avoid calling an external EXE. But the only workarounds that I've come up with are:
Compile an EXE, place in Java project directory, and use Java's Runtime.exec() to execute. (this does work)
Make JNI code launch a separate process which does the same as above (gains nothing but more complexity)
Any ideas on how I can circumvent this problem? When Java applications are compiled as a runnable JAR, is the resultant command line still the JRE's C:\Program Files\...java.exe?
A Java executable maker can create an executable *.exe from your Java application without any native coding or compiling. You can put that executable, the jar files, the fonts and other application dependencies into a single install directory.
Exe4j is one of the executable makers that will support this, for Windows. It does not require any assumptions about the current working directory. This is important in the frequent case where you have no control over what the working directory is when the application is launched.

Categories

Resources