How to add path to resource directory to an executable jar - java

I am trying to create an executable jar (code.jar) that depends on another jar file (other.jar) that I create in a separate project(=directory).
The problem I'm having is that there is a class in other.jar that looks for an image file (xyz.gif) that is contained within that project:
e.g., project 'other' looks like: build/ images/xyz.gif src/... etc.
I make other.jar (including the /images directory) and then I make code.jar.
However, when I run
java -jar code.jar - it is unable to locate xyz.gif:
java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(ImageIO.java...)
I have tried everything I can think of to communicate the path to images/xyz.gif to the jar, including:
1. I tried adding the CLASS-PATH: images/ to the MANIFEST.MF for other.jar
2. I tried copying the images directory into the build for code.jar and adding CLASS-PATH: images/ to the MANIFEST.MF for code.jar
3. I tried putting CLASS-PATH: images/xyz.gif - in both manifest files
This seems like a general problem: How to include a (non-class) resource (e.g., an image file) to a java jar file in
such a way that java can locate it (without subsequent packages that utilize the sub-package - e.g., code.jar uses other.jar)
needing to know the details.
Say I can successfullly run the code project using:
java -cp somepath/images com.xyz.code
What I want to do is run:
java -jar code.jar - and have it locate the images/ directory on the classpath.
I should add that the image-containing jar (other.jar) project is not my code - I am just trying to compile it to use. That code tries to load the image using:
javax.imageio.ImageIO.read(ClassLoader.getSystemResource("xyz.gif");
There seems to be a lot of discussion about whether this is the correct/best way to load an image - I assume that the authors of this code DID have it working using Eclipse (whi
ch likely sorted out the paths), and I simply want to get it working on the command line (and eventually in ant).
Any help would be greatly appreciated. I don't understand why the documentation on jar creation is so minimal.

Instead of running jar directly try putting it in classpath. Something like this:
java -cp code.jar MainClass
This might work.
EDIT:
Above solution will not work. Try the below code to get image.
ImageIcon myIcon = new ImageIcon( this.getClass().getResource("/resources/icon.gif"));
and place the image at below locations:
/myApp/src/resources/icon.gif
/myApp/bin/resources/icon.gif

Related

Java -jar ERROR: could not find or load main class

I am making a 2d game, which I have compiled into a .jar to test if it works.
When in run the jar file with java -jar command I get the following error:
Error: Could not find or load main class com.grizeldi.splatoon.Main
I know that there are many solutions here on StackOveflow, but I have tried updating java, messing with -cp... Nothing worked so far.
Code: github repo
Help anyone?
EDIT1: I have my code on a USB stick, but I have tried moving it to C: and D: but nothing worked.
EDIT2: I have added the .jar on the github.
One way is to update the Manifest with the classpath to the other jars:
Class-Path: lib.jar
An alternative is to add the contents of the jars your main jar depends on to your main jar, so you have only one jar file. Make sure you don't add the jars themselves to the main jar, as nested jars won't work.
When dealing with native libraries (.so, .dll), simply place these in the same directory as the jar. The downside of this is that you have multiple files.
In that case, it might be easiest to just add a startup script (.sh, .bat), specifying the classpath and the classname of Main, aswell as a -Djava.library.path.
There is also another way: extract the native library from the jar at runtime, save it to a temporary location, and load it explicitly. See here for more info on that.

Adding jar in classpath using regexp

I have a question around addition of specific jars from a specific folder.
Scenario:
I have a lib folder which contains a number of jar files. Due to some issue, I have to give preference to a jar file over others.
Refer this issue: http://bugzilla.slf4j.org/show_bug.cgi?id=327
Now am trying to put a specific jar file to be loaded first here log4j-1.2.17.jar
One option is I simply hardcode this in my app script to make sure this jar is always added firstly in the classpath.
Problem in the approach:
Since the project is maven based, there is a chance that log4j version changes. And in that cases I am prone to same issue again, as I have to go and change the version in the script too.
Other option (for which I am searching the solution), there is some possibility like:
Example command (Expected, but this is not working though):
java -cp <path to my app>/lib/log4j*:<path to my app>/lib/* MainClass
The advantage I see here, even if log4j version changes, I will not have to change the script.
Need inputs how can I achieve approach 2?
Thanks
According to this: http://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html
Class path entries can contain the basename wildcard character , which is considered equivalent to specifying a list of all the files in the directory with the extension .jar or .JAR. For example, the class path entry foo/ specifies all JAR files in the directory named foo. A classpath entry consisting simply of * expands to a list of all the jar files in the current directory.
So "*" is equivalent to all *.jar files in a directory. Maybe you could put the log4j in a lib/log directory? The following is working for me under Windows:
java -cp "lib\*;lib\log\*" MainClass

Exported Runnable Jar File - I know what's wrong but not how to fix

How to export to runnable java file with eclipse using slick and lwjgl (Light Weight Java Graphics Library)?
So, I have done some research into this and believe I have found the root of the problem and what needs fixing, now I need to figure out how to fix it.
I have a fairly large project that use slick and lwjgl. These are both provided as .jar files that I have added to the java build path in my IDE (Eclipse INDIGO, in case you where wondering).
My goal is to export the piece into a single runnable jar file. Eclipse gives me three options for this:
Extract required libraries into generated JAR
Package required libraries into generated JAR
Copy required into a sub-folder next to the generated JAR
I have been gunning for the second options and it seems the easiest to deal with logically. Anyway when I select this option I press the FINISH option (the only one available to me other than BACK and CANCEL) I get the generation progress popping up for a sec and all seem well. However, if I run the resulting file I get an Unresolved Linker Error as it cannot find lwjgl.
Seeing as both slick.jar and lwgjl.jar are inside the generated JAR when viewed with winRar, I assume that some information is being lost about the java build path when everything goes from the IDE to the runnable JAR.
My research so far seems to suggest I can point the generated JAR to the enclosed files it needs through something in the manifest.txt file but this is were I have been unable to find anything more concrete.
Can anyone please advise me where to go from here?
P.S: I have tried almost every permutation of the export option and environmental options for the build path but when I run the generated JAR it get various differing errors that still all mean "I cannot find this here external".
P.P.S: I forgot to add, eclipse itself is mentioned in the manifest file as follows:
Manifest-Version: 1.0
Rsrc-Class-Path: ./ lwjgl.jar slick.jar
Class-Path: . lwjgl.jar slick.jar
Rsrc-Main-Class: Game.Game
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
Every bit of common sense tells me that needs to be changed as it refers to the .jars' location but again, not sure what to or where to begin.
You could use JarSplice, just export the jar from Eclipse, with your classes and resources (don't include any libraries at this point), then use JarSplice to add any libraries and natives (like lwjgl and slick) and make the jar runnable.

where to place jar in order to run a program from command-line?

this will sound silly but i am executing my code from command prompt and have to use a jar in my class.
I have placed my jar in lib folder of JDK..
but i am still getting error of file not found
any explanation??
EDITED : guys tried all but still not working
EDIT 2 :i am trying to work as was told by this link i am using js-1.6R5.jar
Edit 3 : i undestand all the things you ppl have told but nothing working for me.. pls give me a link to upload my example that i can share with you all.
Edit 4 : i am fed up by setting classpaths but its not working... i have SDK installed in my system, do i need an extra JDK to run my programs from command prompt??
You need to add the jar to the class path by doing the following...
java -classpath D:\myprogram;D:\myprogram\lib\supportLib.jar org.mypackage.HelloWorld
Please see Wikipedia - Classpath_(Java)
You can place it anywhere, as long is you include it in your classpath. See Setting the Class Path for how to include jars in the classpath.
Have in mind that adding something in the JDK lib is almost never a good idea.
You can make a lib folder in your application's directory and put jar files there, then make your application find them by adding lib to your application's classpath.
And, don't put your jar files in JDK's lib folder. It's not good practise.
You need to let Java know that you want to include the jar in your classpath (the list of folders and jars it checks for classes). One way to do this is with the -cp command line argument, something like
java -cp ".;pathToMyJar\myJar.jar" MyClass
Another is to edit the CLASSPATH environment variable in your OS to include your jar.
A simple solution will be to place the jar fiel inside the windows folder if you are doing it in a Windows machine.
Unfortunately your question contains a lot of question signs and few information.
If you are using java.io.File to open jar as a regular file this jar should not be in lib directory. You just have to provide correct path in file system.
If however you are just trying to use jar as a part of your application it should be in classpath. Use either command line java -cp myjar.jar MyMainClassor put full path to this jar to global environment variableCLASSPATH`.

Java: Loading resources from the file system

My Project Setup
I have the following project setup:
\program.jar
\images\logo.png
In my code, I reference the image with the relative URL "images/logo.png".
Problem
If I run this program with the following command while in the directory:
c:\projects\program_dir\bin\>java -jar program.jar
Then everything works and Java is able to locate the image.
Now, my problem is, that I need to be able to run the program from a different directory.
c:\>java -jar c:\projects\program_dir\bin\program.jar
The program is executed, but now all the relative URLs no longer work.
What I need
How do I calculate the execution home of the program.jar file, so that I can change my relative URLs into absolute URLs?
What I would do, if possible, is package your images in with your Jar.
That way you don't have to worry about where your Jar is launched from.
You would then need to load images similar to the following:
InputStream stream = this.getClass().getClassLoader().
getResourceAsStream("/images/logo.png");
You should really include your resources in your JAR.
Failing that, you can parse the absolute path out of the Main class resource. Assuming your Main class is actually called "Main":
Main.class.getResource("Main.class").getPath();
Resources have to be in the class path(s). You may try one of these:
Placing the images into the program.jar.
Like most of the programs, they have a APP_HOME directory, e.g. MAVEN_HOME, register that and refer to your files as File instead - $APP_HOME/the-file.ext (with System.getenv()).
As Nelson mentioned, package them with your JAR (just copy them alongside your .class files), then you can find them via a simple this.getClass().getClassLoder().getResource("images/foo.png").
You need to add a parameter which describes your class path. Should look something like
java -cp c:\projects\program_dir\bin -jar program.jar
this will put your jar and image on the class path and it will load successfully.

Categories