I'm trying to export my project to a jar file in IntelliJ using these instructions, and failing.
I'm getting a NullPointerException on this line in my application:
ClassLoader.getSystemClassLoader().getResource(".").getPath();
Note that this same project exports fine in Eclipse.
I've tried changing the Class-Path in the manifest to ., as I've noticed this change in the jar exported by Eclipse.
Then, my application gets a bit further, but bails when trying to load any of the resource files included in my jar. This is how:
Assume my jar is placed in
/Users/me/screwed.jar
When my application tries to open resource.file in the root of the jar file, it's searching for it here:
/Users/me/resource.file
This triggers a NullPointerException.
How do I fix this, team?
Use this line to load your path:
this.getClass().getClassLoader().getResource(".").getPath();
This should be the root of your jar file and allow you to open resources within it.
For static context, use
MyStaticClassName.class.getClassLoader().getResource(".").getPath();
where MyStaticClassName is some staic utility class.
Related
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.
I have a jar containing the main class of a project. This depends on several other jars that reside in a lib directory. One class of such a dependend jar loads a ressource "/Data/foo/bar/file.txt". But loading this file as ressource leads to null.
Here is the directory structure:
./main.jar
./lib/lib1.jar
./lib/lib2.jar
./lib/lib3.jar
./lib/runtimedata/Data/foo/bar/file.txt
This is the classpath of the manifest.mf of the main.jar:
lib/lib1.jar lib/lib2.jar lib/lib3.jar lib/runtimedata
I start the application via
java -jar main.jar
The lib2.jar contains a class that tries to load the file with
ThatClass.class.getResource("/Data/foo/bar/file.txt");
But that happens to be null. Why? lib/runtimedata is in the classpath.
I even tried to put the Data directory into lib/lib/runtimedata, in case the path is relative to the jar file containing the loading class. But that doesn't help.
What am I doing wrong here?
EDIT:
Running the application with
java -cp main.jar:lib/*.jar:lib/runtimedata my.package.Main
works correctly.
EDIT 2:
I cannot change that lib that does the resource loading. I am only using that lib. The only things I can change is the main.jar the classpath and the command line.
When you start the path with a "/", it's considered as absolute. Try ThatClass.class.getResource("/runtime/Data/foo/bar/file.txt");
Otherwise, if you cant't change the code, put the file on /Data/foo/bar/file.txt
In a development environment, this can sometimes happen when resources have not been processed during the build. Using Gradle and building your main JAR or main test JAR will depend on the compileJava tasks in your libs, but will not trigger their resources to be processed. You can see if this is happening by looking in your build dir to see if resources for your libs have been copied over. If they haven't been copied the resource loader won't find them at runtime.
If this is the problem, a full build will fix the issue and published JARs should always have their resources. But, it's nice to be able to trigger e.g. the test task for an individual module and know that it will always pull in everything it needs. If you have a library with essential resources that must always be present, you can force them to be processed in partial builds by adding this to the build.gradle of the library:
compileJava.dependsOn(processResources)
In my Maven project I have a properties file that has a property for a location of keystore file file=filename.p12 (I think the file type doesn't really matter now).
The problem I have that when i built it with maven, I see that the file is inside the root of jar and when i run java -jar the-jar-file.jar I get the IO exception that the filename.p12 is not found.
Everything runs fine in Eclipse, it finds the file and the application runs. Not to confuse somebody, I keep a copy of that filename.p12 as well in src/main/resources folder so that the paths are resolved running in Eclipse and standalone. But this is going to be my other question.
What I can't do is to get the filename.p12 as a resource, because I have external jar that gets as argument my properties file and then handles that properties file itself where the row file=filename.p12 is. Why is the file not found inside the jar, even though I see it's there? My other property files that I have open with Spring's ClassPathResource run just fine.
In order to access internal/embedded resources you need to use Class#getResource or Class#getResourceAsStream depending on your needs
I have a maven desktop project that uses JPA as persistent layer; this layer deals with one MySQL database and one SQL Server database.
When I run it inside Eclipse, there is no problema; but when I try to export it outside the output when I run jar the console prints the famous:
javax.persistence.PersistenceException: No persistence provider for
EntityManager named axaptaUnitName
axaptaUnitName is the unit that deals with SQL Server. I have tried all three type of exportation from Eclipse, extract required libraries into JAR, package into JAR, and copy in external folder; none of them works.
All libraries (including the connector with SQL Server) are correctly added to classpath; inside Eclipse all works perfect; so I assume that it's some kind of exportation problem.Any suggestions?
Edit: I've tried to replace Microsoft SQL driver with JTDS driver; but the issue still happening.
Here is Work around for this.
I simply exported it as a runnable Jar with option - "Extract required libraries into generated Jar".
Opened generated Jar with a archiever software.
Then I found there is no "Persistence.xml" in META-INF folder.
I dragged my "Persistence.xml" file in that META-INF folder in achiever's window itself.
Closed archiever program.
After that, the PersistenceException was disappeared.
I'm assuming you use the "uber-jar" method where all dependency jars are exploded into one big jar. The problem with this approach is if the jar has files with same relative path they could override each other. Consider this scneario:
// contents of A.jar
com/foo/Class1.class
com/foo/Class2.class
META-INF/persistence.xml
// contents of B.jar
com/bar/Class1.class
com/bar/Class2.class
META-INF/persistence.xml
When A.jar and B.jar are exploded and re-packaged into Uber.jar, the earlier META-INF/persistence.xml will get overwritten causing errors / unwanted behavior
A better solution to deploy your standalone application is to keep all dependencies in their original jar packaging, place them in a single folder and run using command like this (windows):
java -cp "dependency/;myprog.jar" com.foo.MyMainClass
(all dependency jars are placed on the folder "dependency")
I've found one solution:
Instead of exporting project with Eclipse, I have generated a jar with Maven this way.
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.