Loading xml file from within JAR file sometimes works - java

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

Related

Accessing files with relative filepath inside built jar java

I have a project which uses relative file paths to access resources. While the project is run in IDE, the path looks like.
\\src\\musicTest\\Track4O.mp3
When the project is built into a jar file, this no longer works. Upon opening the jar file, I noticed that the file structure looked like
musicTest.jar\\musicTest\\Track4O.mp3
In both cases, the class attempting to load the resource was in the same location as the mp3.
If anyone has a solution for either: maintaining the file path so that the build will run as intended or: solving the relative file path problem, it would be much appreciated.

Reading and writing files within Jar

I have finally completed a program in Java and I have to upload it.
The problem is that I have to upload also the executable .jar file and not only the eclipse project.
The main functionality of my program consists by reading and writing .xml files (for example one file is used to read and add new users), and the files in the project folder are so located:
-Project Name
src
default package
main and all other classes
file1.xml
file2.xml
So the two .xml files are in the root of the project.
My question is: It is better to save the .xml files in the JAR and then writing and reading them from the executable program or it is better to store them in a folder outside the .JAR and reading and writing them as externally files?
It is a good practice to create a folder like that?:
-ProjectName
file1.xml
file2.xml
project.jar
I read in Stackoverflow a lot of people having my same issue and a lot of people doesnt know how to manage this problem properly.
Thank you in advance for the reply :)
Changing files in JAR-files can have all sorts of problems. That starts with simple things such as what should happen when you want to update your program to the newest version? Usually you'd just swap the jar, but then you loose everything you edited so far. You'd need a process to update inside the jar.
Other problems include that for changing the jar file you need to open it, possibly realign contents and rewrite the index which could conflict with the JVM that is reading the jar at the same time causing odd behaviour. On some systems (windows...) the Jar file might even be locked while the application is running and thus you cannot write to it at all.
I'd suggest that you add "default files" (in case that your files are initially not just empty) to you Jar file that represent the initial state. If the application is started you check if the XML files exist in the some normal writable directory and if they don't just copy the default files to that directory. This allows you to deploy still just a single jar file, but once started the appropriate files will be created.
You may read a XML file located inside the executable Jar but it is not possible to update (write) a XML file located inside that executable Jar file. So the best option would be:-
-ProjectName
file1.xml
file2.xml
project.jar
The jar should be kept read-only, the XML "files" inside the jar should be read using getResource[AsStream] (class path). You can use those resources as templates to create a copy in the user's (or application's) directory/sub-directory. For the user's directory:
System.getProperty("user.home")

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.

Jar cannot find the path to the file inside

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

Problem with resources location difference in eclipse and JARs

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..

Categories