Problem with resources location difference in eclipse and JARs - java

I wrote a program that is based completely on a single text file: I read the file, store the information, then search the information, etc. So, for the program to work, the file just has to be present and detectable by the program.
I use eclipse, so I put the file is in the default resources map (src/main/resources). At the start of my program I create the file:
private static File textFile = new File("src/main/resources/TEXT.TXT")
However, when I try to package my program using Maven, I get a JAR in which all class and resources files are present in the same folder; my program stops working since it cannot find the file anymore.
Any help on how to deal with this problem? I`d prefer a situation in which my program works in eclipse and as a JAR, but as a JAR only would be alright as well.

You can use ClassLoader.getResourceAsStream to load it from the classpath (or getResource to get the URL of the file).
Thread.currentThread().getContextClassLoader().getResource("TEXT.TXT")
This works as long as src/main/resources is on the classpath in eclipse. (The maven eclipse plugin includes it by default.) The file has to be in the jar file to work outside of eclipse.

Nice suggestions, this works perfect in eclipse itself: the correct location of the file is returned and I can use the file to do whatever I like.
When opening the program as a jar, there is still a problem. The getResource method returns a location that looks like the right one:
/something/something/something/something/workspace/program/target/program-0.0.1.jar!/TEXT.TXT.
However, when I convert this url to a string, use that string to create a file object and use this file object in my program, I get the following error:
java.io.FileNotFoundException: file:/something/something/something/something/workspace/program/target/program-0.0.1.jar!/TEXT.TXT (No such file or directory)
So, the getResource method does find the file, but the program somehow can't use it..

Related

Absolute file paths when running program from jar?

I don't understand how Java jar files work. I am trying to understand what is possible and not possible when creating a Java jar file. Is it possible to have a String path running normally in a Java jar file? Will this normally work as it works when running main class in eclipse? I mean, I have an absolute path in my main class that grabs the file and reads from it.
public static final String file1 = "C:\\Users\\Documents\\test1.txt";
public static final String file2 = "C:\\Users\\Documents\\test2.txt";
This is what I have when running my program and it works fine. This is inside a class that is called somewhere along when I want to read a file. My question is... will this prevent my jar file from working properly normally AS when running the main class from eclipse?
I have the jar file but what if it doesn't or does it still look for file1 and file2?
It doesn't matter whether that code is in a jar file or not. The strings will still be exactly as they are, and if you pass them to methods that look for files with those paths, it'll look for files with those paths in the file system of the machine where the code is running. It won't look for them inside the jar file.
A Jar file is basically an executable of your project, it is used for example by frontend's who need a backend but don't want to open an IDE for compiling and executing purposes. Your Jar file contains .class files responsible for the execution of your project, you an execute your jar in a server too, so your application will run for more people (if you configure right).

Loading xml file from within JAR file sometimes works

I'm building a Groovy plugin for Android Studio which will execute some gradle tasks. However I need to load a XML file from within the JAR file from where the code executes.
The JAR file is as following:
com/packagename/code
META-INF/gradle-plugins
filename.xml
Because the xml file is at the root of the JAR I used this to load in the resource into an inputstream
new InputStreamReader(CheckStyleTask.class.getResourceAsStream("/filename.xml"))
The weird thing is that it only works sometimes. Sometimes it returns the file, sometimes it returns null. For example I took this line to check the path:
println(CheckStyleTask.class.getResource("/filename.xml").getPath())
And the path is completely right. So it is able to find the file with getResource, but with getResourceAsStream it returns null.
I think something is wrong with the building of the jar but in IntelliJ I set the gradle task as 'jar' which did create a working jar with working xml file.
Am I doing anything wrong regarding the building or is there anything wrong with the xml file?
There is a difference between the two functions:
https://stackoverflow.com/a/20069798/5387592
You should precise: in which circumstances, the results differ : after create new jar, or after launching again.
1 check if the file is really embedded in the jar: change .jar to .zip and check inside
2 check the real path.
In Eclipse for example, you put in a folder, but this folder doesn't appear in resulting jar
3 use advices: take absolute path as you do

How to refresh src/main/resources folder while executing the code?

When I run my main method it creates src/main/resources/sample.txt file and then read the content of it. Whenever I run the code it gives java.lang.NullPointerException, when it comes to read src/main/resources/sample.txt. However when I refresh the project, it reads the sample.txt but not the new content, it reads the old content.
It's seems like I need to refresh java project in eclipse before read the text file.
Is there a way to refresh src/main/resources while executing?
If you are able to write that file, then you should be able to read it.
My guess is you are writing it using a file path src/main/resources,
but you are reading it using ClassLoader.getResource, which reads from the classpath target/classes.
When you refresh the project and eclipse builds it, the source files in src/main/resources get copied to target/classes, making them available in the class path as resources.
I would advise against writing anything in src/main/resources, since that only works if you are executing the project from the project directory.
Typically, a ClassLoader's class path is set up during program start. Depending on it's caching implementation, it is usually not possible for the classloader to pick up on changes in files in the classpath. You would need to create a new ClassLoader and discard the old one, but this is far too complex for this situation.
To read the file, use code similar to how you wrote the file: If you used FileWriter, use FileReader; if you used FileOutputStream, use FileInputstream, etc.

Netbeans created Jar does not work, but inside IDE program works

The Netbeans created Jar does not work, but inside the IDE program it works perfectly.
I believe that the main class is set, so I'm not sure what the problem is, I think it might have something to do with the txt files I'm using, in the IDE they are in C:\Users\J\Documents\NetBeansProjects\PointOfSale\src\pointofsale (the text files are with my java files). After building the dist/ jar though the text files are inside the jar with no folders or anything (Jar is in C:\Users\J\Documents\NetBeansProjects\PointOfSale\dist). I this this might be the problem, if its helpful, I access the files using
File file = new File(System.getProperty("user.dir")+"\\src\\pointofsale\\list.txt");
You need to use Class.getResourceAsStream() to load the file. It searches from inside the classpath (and therefore from inside the jar). Now you can't load the list.txt because it doesn't exist in the directory you're specifying, it's inside your jar.
Something along the lines of
getClass().getResourceAsStream("list.txt"); // Or "/list.txt"
Will give you an InputStream you can use to load the file contents.

Accessing a file within Java project

I have a Java project which uses a third party application. I have the license file (.lic format) stored in the resources folder. Upon running the Ant script, it will copy this file into the /lib/jar directory as it rolls up the project into a Jar file to use on the server. This is where I will need to access the file when running the system live. Here is how the folder structure looks
MyProject
src
package
AccessingClass.java
resources
File.lic
lib
jar
File.lic (upon copy from Ant)
I am not sure the best way to do this so any suggestions other than how I have been trying will probably be helpful. The 3rd party project has a method in a class like License.setLicense(), which can either take a String to the location or an InputStream of the file.
I have been playing around with feeding it an InputStream, but always get a null value when calling getClass().getResourceAsStream(). Here is everything I have tried:
getClass().getResourceAsStream("../../../lib/jar/File.lic");
getClass().getResourceAsStream("/File.lic");
And as a backup I also tried (for local builds I figure I would try the resource folder):
getClass().getResourceAsStream("../../../resources/File.lic");
getClass().getResourceAsStream("/File.lic");
Is there a better method to perform this action? Or would someone be able to tell me why what I am trying is failing? Thanks ahead of time.
Are you running this code standalone or in IDE env looks like classpath issue. If you are running at command prompt you have to set classpath to lib dir if in ide make sure you resources dir is in classpath.
First, you need to ensure that the JAR is added in your class path.
Below should work.
InputStream inputStream =
getClass().getClassLoader().getResourceAsStream("/resources/File.lic");
Assuming File.lic is placed in root folder of the jar.

Categories