I am trying to deploy my JavaFX project (which uses Java 11). I found some other tips online that said to create a Launcher class which does not extend Application and call the actual main method from the Launcher class.
Although this allowed me to create a JAR that I could run in the desktop, it required me to provide a path to my JavaFX library folders in the command line.
Since I am deploying this project, I do not want to force users to have to download the entire JavaFX library.
Is there a way to deploy my JavaFX project without requiring users to have the entire JavaFX library folders downloaded? I am especially confused because it seems that the JAR already has the JavaFX library folders in it, as the JAR file size is large.
I would also like to avoid using any third-party libraries or tools.
For reference, I am using IntelliJ IDEA.
Related
I need to create a .exe file for my project. I have a launcher and 5 applications. Applications are launched using the launcher applications. How can I collect the entire project into 1 executing file and run it using it? My project built on Gradle.
What are the ways to solve my problem?
The recommended way to do this for modern JavaFX applications is to use jpackage which comes with JDK 14. Don't try executable jars. They won't work in general.
If you have to, you can use JDK 14+ just for jpackage but bundle your app with any JDK 11+. Just have a look here for a tutorial: https://github.com/dlemmermann/JPackageScriptFX
Try using Launch4J (http://launch4j.sourceforge.net/) or Advanced Installer (https://www.advancedinstaller.com/) to package your .jar files into a single (or multiple) .exe file(s). Note that these are third-party programs which will enable you to package your .jar files and deploy most probably on your client's computer.
For more info read,
https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/self-contained-packaging.html
https://www.genuinecoder.com/convert-java-jar-to-exe/
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.
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
I tried top learn Java because it's the easiest way to make cross platform apps(python too but I've already know it). I tried to write hello world program with JOGL. I've written it and it runs perfectly in my Eclipse and NetBeans but when I'm trying to build jar and run it it says that there isn't JOGl in the java.library.path. I tried to pass library path with -D argument and it works!
The question: Is there is a way to run it without any additional args? With only double click.
Thanks.
You should create a manifest file in your project: META-INF/MANIFEST.MF (probably you already have it in your project tree).
And There you can specify your classpath, for example:
Class-Path: lib/jogl.jar lib/other_lib.jar
Then make sure that this file goes in your jar. For more information http://download.oracle.com/javase/tutorial/deployment/jar/manifestindex.html
When it comes time to deploy to users, deploy the app. using Java Web Start. That makes using natives a 'one click' install for the end-user, and it can also partition the native download between platforms.
Is there is a way to run it without any additional args? With only double click.
JWS also offers desktop integration - desktop shortcuts and menu items with icons, on the supported OS'.
You can do the above very easily using a tool like JarSplice. Just follow the gui, its pretty easy to do. The application will put the natives inside the jar for you, so all you have to do is double click the jar to run your jogl application.
Setting the Java library path is no more required in JOGL 2.0. You just need to set the class path (jogl-all.jar and gluegen-rt.jar must be in the class path) and to put the JARs containing the native libraries into the same directories whatever you use (applications, applets, Java Web Start, etc...). Then, JOGL 2.0 automatically loads the native libraries.
We have a class library, written in Java (Standard Edition or MIDP 2.0, we have both variants), compiled to JAR file. There's nothing special in that library, mainly work with sockets (TCP and UDP) and threading.
Now we need to ensure, that this library will work on Android, and fix linkage problems (such as classes or methods missing on Android).
Is there a way to "validate" generic JAR file for Android without writing a complicated test case and running it on Android? I imagine something that I can pass the JAR to and it will tell me "could not load JAR - method X not found in class Y".
Found the solution. If you have a JAR file which you want to check for basic compatibility with Android's libraries, you need to do the following:
Create an android project
Add a JAR file as an external JAR to the list of project libraries.
Attempt to build the project.
If the JAR references missing classes, you will get an error immediately during building.
Is there a way to "validate" generic JAR file for Android without writing a complicated test case and running it on Android?
I would hope that somebody with your SO karma would not try to ship a JAR for Android without actually "running it on Android".
That being said, there's no good way that I can think of to perform your validation at the JAR level. However, if you pour your source code into an empty Android project, you will get compile errors if you refer to classes or methods that do not exist.