How to export to a runnable jar with Proccessing (Eclipse) - java

I have tried to export my processing applet to a runnable jar file from eclipse (which I am using to code it) and it exports successfully but when opened just causes a blank (grey) screen. If I run it with command prompt I get this error:
java.lang.NullPointerException: Cannot invoke "String.contains(java.lang.CharSequence)" because "jarPath" is null
When I extracted the jar sample the folders and directories seem to be incorrect too.
before
(the dependencies are in the dependencies folder)
after
(the dependencies are outside of the now missing dependencies folder)
I'm sure its an issue with the file structuring on generation, more specifically the dependencies. when I run it as an application eclipse it runs perfectly fine with no exceptions.
Full message:
java.lang.NullPointerException: Cannot invoke "String.contains(java.lang.CharSequence)" because "jarPath" is null
at processing.core.PApplet.dataFile(PApplet.java:7673)
at processing.core.PApplet.dataPath(PApplet.java:7650)
at processing.core.PApplet.createInputRaw(PApplet.java:6741)
at processing.core.PApplet.createInput(PApplet.java:6659)
at processing.core.PApplet.loadBytes(PApplet.java:6959)
at processing.awt.ShimAWT.loadImage(ShimAWT.java:384)
at processing.core.PSurfaceNone.loadImage(PSurfaceNone.java:61)
at processing.core.PApplet.loadImage(PApplet.java:5311)
at processing.core.PApplet.loadImage(PApplet.java:5296)
at net.turke1034.shootergame.game.ShooterGame.draw(ShooterGame.java:55)
at processing.core.PApplet.handleDraw(PApplet.java:2201)
at processing.awt.PSurfaceAWT$10.callDraw(PSurfaceAWT.java:1422)
at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:354)
java.lang.NullPointerException: Cannot invoke "String.contains(java.lang.CharSequence)" because "jarPath" is null
at processing.core.PApplet.dataFile(PApplet.java:7673)
at processing.core.PApplet.dataPath(PApplet.java:7650)
at processing.core.PApplet.createInputRaw(PApplet.java:6741)
at processing.core.PApplet.createInput(PApplet.java:6659)
at processing.awt.ShimAWT.loadImageIO(ShimAWT.java:454)
at processing.awt.ShimAWT.loadImage(ShimAWT.java:439)
at processing.core.PSurfaceNone.loadImage(PSurfaceNone.java:61)
at processing.core.PApplet.loadImage(PApplet.java:5311)
at processing.core.PApplet.loadImage(PApplet.java:5296)
at net.turke1034.shootergame.game.ShooterGame.draw(ShooterGame.java:55)
at processing.core.PApplet.handleDraw(PApplet.java:2201)
at processing.awt.PSurfaceAWT$10.callDraw(PSurfaceAWT.java:1422)
at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:354)
I have tried the same thing with a test project that requires no dependencies, and it runs as expected (when run in command prompt)

had the same issue, so troubleshooted for a while until i found the following solution. i'm assuming that you are using a data file similar to the data file in Processing projects to contain your dependencies.
in Eclipse, export as a runnable jar and select the option "Extract required libraries into generated JAR". once the jar is created, put this jar into a new folder. put your data folder into this folder as well. this worked for me.
no idea why this works - just threw stuff at the wall until this stuck. one troubleshooting technique i used was making a printwriter before loading any data so i could see where the computer was searching for the dependencies. the snippet below outputs the file to the same place that Processing looks for data.
PrintWriter pw = createWriter(dataPath("test.txt"));
pw.print("over here");
pw.close();
i used this in combination with dataPath("") to find that it was looking for dependencies outside of the jar.

In the past (older answer here) I had success exporting runnable .jar projects from eclipse which use Processing's libraries by using the Copy required libraries into a sub-folder next to the generated jar option in Runnable Jar File Export options:
This made it easier to debug java classpath issues (-cp flag when running from command line) and native library paths(-D.java.library.path command line flag).
If you're using java packages remember to specify them in PApplet.main():
public static void main(String[] args) {
PApplet.main(ShooterGame.class.getCannonicalName());
}
The above is useful only if you can't execute the jar files due to missing libraries (class not found, missing native libraries, etc.)
Regarding loading external assets, as Shivoum B mentions, you can make use of dataPath() but also sketchPath().(See this similar answer).
Without seeing the path to the loadImage() call you're making I can only make assumptions, but you might be able to get away with something like this in ShooterGame.java:
loadImage(sketchPath("data" + File.separator + "yourImageName.png");
(Off-topic, if I read this correctly you're trying to load images in draw() ?
I'd recommend loading all assets in setup() once instead of multiple times in draw(). A special case might be with the loading large assets that take time and using P2D or P3D where the OpenGL context setup might time out (in which you can load in draw() but should use a "debouncing" boolean to ensure assets are loaded only once)

Related

Class.forName(Class) in a specific directory?

While testing a program I am developing that writes to a SQLite database, I noticed that if I moved my sqlite.jar file to a sub-directory, Class.forName("org.sqlite.JDBC") throws the ClassNotFoundException. Is there a way that I can change the directory that Class.forName("org.sqlite.JDBC") is looking in so that I can store the file where I want it?
It looks like the classpath is set to work with that location. If you are using an IDE, add the library to your build path in your project properties and then execute your code. The IDE will do the rest of the things you need to do.
If you are working with classpath setup, you should not move your files from the classpath where the class files are specified and your program will look for its desired class to load.

JAVA, Batch file errors

I have an existing Java project that compiles and runs properly through Eclipse. I have created the following .bat file to run the program sans Eclipse:
java -classpath jflashplayer.jar;bin TestProgram
The file is saved within the project folder, but not within the bin folder (located in same directory as bin). When I try to run the batch, I am met with a large number of runtime errors, the first being
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/apache/commons/io/FileUtils
I'm not sure why I get this error when it compiles and runs properly via Eclipse. I have the commons-io jar files linked to the project within Eclipse as libraries, and the jar files are themselves located in the project file (same directory as the batch file and the bin folder).
Also, I'm not entirely sure what the -classpath jflashplayer.jar bit of the batch file is doing. I am using the jflashlayer.jar library (also linked to the project within Eclipse and in the same location as the other jar files), but I am not sure why it would appear in the batch file. I edited an existing batch file from a similar project that uses the jflashplayer.jar files, and it has worked previously to leave that part in.
When I write code in Java, I rarely require it to compile/run outside of the IDE, so I usually have troubles when it comes to this part. Perhaps there is a more robust and foolproof method to run the program outside of the IDE other than the batch file method.
The batch file method is fine, but you have to specify all the libraries you're using on the classpath, just like the jflashplayer.jar.
In this case, the error you're getting is because the Apache commons-io library is not specified on the classpath. Your command would have to look something like:
java -classpath jflashplayer.jar;commons-io.jar;<other jars ...>;bin TestProgram
Alternatively, you can create a runnable jar from Eclipse as described here. When you select a library handling strategy, choose the option Extract required libraries into generated JAR. This will make it so that all the library classes you're using are packaged into your application's jar file, and you can just execute it by invoking java -jar my_application.jar.

How to create Windows executable from JAR

I have a simple Java program (lets call it MyProgram.java) that does some I/O, re-names some images, deletes a directory, etc. I've been browsing around S/O looking for a simple way to run a Java program's main method from command prompt. I've compiled the source code into a jar, and tried using Jar2EXE Wizard, however I kept getting an unexpected compilation error that I wasn't getting while running my code from the IDE.
Does any one have either a Jar -> EXE converter solution they've had success with or can walk me through how to run my program from a batch file?
[..]or can walk me through how to run my program from a batch file?
The simplest way is to execute:
java -jar YOUR_JAR_FILE.jar
in your batch file. However this requires a manifest file to be present in your jar file which specifies the Main class to use and jar files it depends on. If you do not want to work with a manifest file you can specify these things manually. If you do not depend on external jar files you can execute:
java -cp YOUR_JAR_FILE.jar some.package.Main
This will execute the public static main(String[] args) method in class some.package.Main contained in YOUR_JAR_FILE.jar.
If there are other jar files you depend on (in your case that would be IOUtils/FileUtils), specify those jar files as well:
java -cp YOUR_JAR_FILE.jar:library1.jar:library2.jar some.package.Main
(in your case library1 and library2 are IOUtils and FileUtils respectively).
You can specify any number of jar files and you can also use the wildcard *.jar to include all files in the current (or another) directory. Note however that you cannot write * or x*.jar or the like. Only *.jar (or some/directory/*.jar) is accepted.
In 90% of the times, the order of the jar files does not make any difference. However sometimes it does make a difference: If a resource is loaded from the classpath (could be a class or something as simple as a configuration file), the jar files are searched in the order you specified. If a resource exists in multiple jar files, only the first one found will be used.
You can consider using install4j.
If you want use batch file you can write this:
java -jar sources.jar
If your code have more than 2 static void main(String[] args) you need explicitly hit the method:
java -jar sources.jar classes.package.Main
Directory structure:
-\project\
-\project\run.bat
-\project\sources.jar
Take a look at JSmooth. It wraps your JARs as executables and provides options for detecting, and handling lack of, the JVM. I've used it on a simple app and it was painless.
Bonus: it is available as a portable app with no installation needed.

sigar-amd64-winnt.dll ... can't reference it or bundle it with .jar

(It might be an obvious mistake I'm making, but I couldn't get it to work after 6 hours now.)
I'm trying to get CPU information using the sigar.jar in my eclipse project (just testing the sigar API for now).
It runs in eclipse without problems:
what made it work in eclipse was to put the dll in the same folder as
the sigar.jar
I tested that adding a path to the dll as the "native code property"
in the build path config dialog has no effect.
Adding vm arguments in the run configuration also has no effect.
I tested putting 2 fake paths in those 2 places and as long as I have the
dll in the same folder as the sigar.jar... it runs well in eclipse.
The problem is when I try to export a runnable .jar file for my project. I tried 2 things:
I modified the MANIFEST.MF file with Bundle-NativeCode: libs/sigar-amd64-winnt.dll (I'm assuming here the path is relative to the project folder) --> no success:
main starting!! no sigar-amd64-winnt.dll in java.library.path
org.hyperic.sigar.SigarException: no sigar-amd64-winnt.dll in
java.library.path
at org.hyperic.sigar.Sigar.loadLibrary(Sigar.java:172)
at org.hyperic.sigar.Sigar.<clinit>(Sigar.java:100)
at CpuData.main(CpuData.java:59)
cpudata(sigar s) starting!!! cpuInfo() starting!!!
Exception in thread
"main" java.lang.UnsatisfiedLinkError:
org.hyperic.sigar.Sigar.getCpuInfoList()[Lorg/hyperic/sigar/C puInfo;
at org.hyperic.sigar.Sigar.getCpuInfoList(Native Method)
at CpuData.cpuInfo(CpuData.java:103)
at CpuData.<init>(CpuData.java:29)
at CpuData.main(CpuData.java:59)
Then I decided to put the .dll in the same folder as my project.jar, and used in the command line: java -Djava.library.path=./native/ -jar C:\cpu_usage_log\cpu3.jar (I'm assuming here the path is relative to the folder that contains the project.jar) ...but again no success:
Error: impossible to find or load the main class .library.path=..native
(I suspected that I should give a main class name as a second argument after the -Djava.library.path=./path/ but I can't find that supposed "main class" name, or any examples on the web that do specify such a class ...is it a main class from within the .dll?)
I don't really know what else to try at this point. I read those 2 solutions worked for others, and it makes it even more frustrating because I imagine it could something obvious that I missed or didn't understand when reading other posts and that I just can't find (it's the first time I deal with native dlls in a java project).
For me it was always the best to modify the way how Java loads the library.
Usually you call System.loadLibrary("mylib"); which searches the library on the library path.
IMHO it is much better loading the library using it's absolute path. This allows you to implement a custom search logic in your program:
// Extends the name to mylib.so or mylib.dll
mylibname = System.mapLibraryName("mylib");
// Load the library via its absolute path
System.load(new File(path, mylibname).getAbsolutePath());
Note that each library can only be loaded once, therefore if you load the library as shown above, calls of System.loadLibrary("mylib"); afterwards will be ignored as the library is already loaded.

.Jar file, created by netbeans doesn't open anymore on windows

For some reason, my application stopped working when I used "clean and build" at NetBeans and try to run it from dist folder. Application used to open from the jar file, but now it only blinks, and even doesn't give any error messages. Application runs, if I test run it with F6 using NetBeans. Jar file is created by NetBeans, so I guess the manifest should be okay.
Here's the link for the jar file...
Executing the jar in the terminal gives this exception trace:
Exception in thread "main" java.lang.NullPointerException
at javax.swing.ImageIcon.<init>(ImageIcon.java:155)
at tbs.ImageLoader.loadImage(ImageLoader.java:11)
at tbs.Flag.<init>(Flag.java:21)
at tbs.Model.<init>(Model.java:58)
at tbs.GameView.<init>(GameView.java:33)
at tbs.GUI.<init>(GUI.java:36)
at tbs.Main.main(Main.java:6)
So it looks like you had something like this here:
public Image loadImage(String name) {
return new ImageIcon(getClass().getResource(name));
}
... and the getResource() method returned null, which caused the ImageIcon constructor to throw the Exception.
In line 21 of Flag.java you used "images/flagNeutral.png" as the image string, but your jar file contains images/flagneutral.png (inside the tbs directory). See the difference?
If it worked on your local system outside of the jar, you are using a case-insensitive file system there. (Windows or Mac?)
In the jar, as well as over HTTP and on "real" file systems, the URLs are case sensitive, which means you have to name the resource precisely as the file is named.
And yeah, normally you should have at least tried your program yourself, and posted the stack trace as well as the relevant code lines.
There may be a lib folder in the dist directory. If so, it contains jar files for any libraries you included. Make sure that is the case. You need to distribute the jar as well as the entire lib folder and store both in the same folder just like Netbeans creates them.
I am hoping you have created a Java application project and not a Java Class library project.
You can check if the main-class attribute and any library paths are added properly when you "clean and build" the project.
You can run it like java -jar tbs.jar and see the response.
Typical error when you don't define the main class before clean and run.
Click right on the project -> properties ->run section ->define the main class.

Categories