URI is not hierarchical when loading file from .jar - java

So I have a problem with loading a file when running my program from a jar file. I am aware that questions very similar to this exist but I can find none that work for me or do what I need. I would like to load an object file from a folder in my jar but when I do I get the following error:
Exception in thread "main" java.lang.IllegalArgumentException: URI is not hierarchical
at java.io.File.<init>(Unknown Source)
at bbsource.BouncyBallV5.loadLevels(BouncyBallV5.java:370)
at bbsource.BouncyBallV5.<init>(BouncyBallV5.java:243)
at BBDriver.main(BBDriver.java:18)
Line 370 is as follows
initSource = new File(getClass().getResource("/resources/levels").toURI());
I have no problems with this line when running from Eclipse but I am aware that things act differently in jar files. The folder hierarchy is:
src
resources
levels
tier_one
Level1.cbbl
Level2.cbbl
tier_two
Level1.cbbl
levels is a directory that it will not let me access, and I'm not sure how to get it to work. I have seen suggestions such as using InputStream but I'm not sure how to use that and still treat it as a file from which I can read objects.
Any help would be appreciated.

This is because /resources/levels is a directory not a file. Check the answers for this question

Related

Spring boot: trying to read directory content inside resources folder produces FileNotFoundException when reading from jar

so I have a problem with Spring-boot. Basically the idea is that in resources i have a directory called migrations which stores sql scripts that needs to be launched. It works well on local machine. But, as soon as I upload project to server i get greeted with error of:
Caused by: java.io.FileNotFoundException: class path resource [migrations] cannot be resolved to absolute file path because it does not reside in the file system:
A lot of googling helped me to identify problem. It has to do with file being in .jar, when I do read directory as InputStream, as stated in other issues like this one, I can get specific file and access it's scripts if I specify full name of that resource, like
resourceLoader.getResource("classpath:migrations/file.sql")
But, specifying full name of resource like that and defining all the file names is not an option, since in the future this folder can expand a lot and i don't want to manually edit code to add file to running.
Is there any workaround for this issue that would allow me to at least read file names from directory and then access them one by one?
i don't think there is a good solution for that if it deploy has a jar unless you use docker file to copy the resource and deploy it. getInputStream() was always the best solution to get file from anywhere.
maybe this solution but not try yet
ClassLoader cl = this.getClass().getClassLoader();
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
Resource[] resources = resolver.getResources("classpath*:/*.sql") ;
for (Resource resource: resources){
do your things maybe print the name resource
}

NPE while try to get Resource in jar

I have tried many variants but I cant find correct.
I have something like
Inside my jar, which created by Maven I can see that
That is my folder with classes. And, by the way, If I start my program in IDEA, not from Console, there is not any exception with paths
Here, I am in debug mode start my jar trying to see, where is the problem.
If I do 'file.exists()' it would be false but file inside. I think, that problem because of '.jar!\' in the path, but I don`t know how to remove that.
Anyway I've tried absolute and relative path, I've tried
Thread.getCurrentThread.getContextLoader.getResource()
GUI.class.getResource()
GUI.class.getClassLoader.getResource()
Nothing help
You can't use File to open resources inside a jar file. File can only be used with normal files and directories.
Note: using File works fine within in the IDE, since all files are not packaged in a jar file yet. But the program will break after you package it.
Once you locate the resource eg. URL res = GUI.class.getResource("/rxtx64/myres.dll") , you can open that resource as a stream InputStream is = res.openStream(); .
See also related answers Utils to read resource text file to String (Java) and How to read a text-file resource into Java unit test?

Unable to reach resources folder when compiling from .jar to .exe using Launch4j

I made a small Java program for academic purposes, its main focus is to read some .txt files and present the information to the user. These files are present in the resources folder, under the src folder.
The program runs as intended when launched from Eclipse.
Using the Launch4j app I was able to successfully create an exe which runs fine and does what's intended, up until I try to read the .txt files I have in the resources folder, which appears not to be able to reach.
I'm guessing that when I launch the exe the run time path would change to where the exe was created, so I created the program in a desktop folder and specified this path in the program, but that doesn't seem to solve the situation.
As an alternative, I moved the .txt files out of the program and once again created the exe in a desktop folder with said .txt files, linked the program to this path and once again it didn't work.
The command used to get the .txt files is:
Files.readAllLines(Paths.get(doc)).get(line)
And doc is simply the path to the intended .txt file.
It's worth noting that I have no previous experience in Java and throughout the development of the program I tried my best to use commands I'd fully understand and to keep it as simple as possible. I hope the solution can be along these lines! I'm very confident this must be a rookie mistake, but I can't seem to find the solution to this specific problem anywhere.
The paths to files in Eclipse are different than the paths to files in an .exe or JAR file.
I will let this other user explain it because I am lazy :p
Rather than trying to address the resource as a File just ask the
ClassLoader to return an InputStream for the resource instead via
getResourceAsStream:
InputStream in = getClass().getResourceAsStream("/file.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
As long as the file.txt resource is available on the classpath then
this approach will work the same way regardless of whether the
file.txt resource is in a classes/ directory or inside a jar.
The URI is not hierarchical occurs because the URI for a resource
within a jar file is going to look something like this:
file:/example.jar!/file.txt. You cannot read the entries within a jar
(a zip file) like it was a plain old File.
This is explained well by the answers to:
How do I read a resource file from a Java jar file?
Java Jar file: use resource errors: URI is not hierarchical
The original post is here, all credit to its author.
Fixing your URL should let you read from that file when you are using the .exe.
EDITED FOR CORRECTION. Thanks #VGR (see comments) for correcting my mistake.

tuProlog - using multiple files with consult - can't get engine to load additional files with consult(otherFile.pl)

Edit: Clarity - the main .pl file loads, it's all the subfiles that it has been told to load which don't load. (all the consult('subfile.pl').)
I have a Java project that uses tuProlog. It calls a theory as:
Theory theory = new Theory(":-consult('main.pl').");
engine.setTheory(theory);
This is as per the manual.
file.pl exists in the same folder as other prolog files.
Inside of main.pl, I have further
consult('otherfile.pl').
statements to load additional files (several).
The folder structure is:
src/main.pl
src/Prolog_Files/otherfile.pl (multiple)
src/main/java/JavaStuff
I can't get the engine to load the theories that I've told it to consult inside of the main file.pl
I have tried: giving it absolute path instead of just filename.
moving files around.
I'm wondering if there is something about usage of tuProlog I'm not understanding?
The theory works when loaded with:
Theory theory = new Theory(new FileInputStream(url_of_file)).
However, this is causing me issues when building the jar, as it can't find the file location.
Am I attempting to load the file correctly? Are my consults inside of the main .pl file correct?
Could someone please post an example of how this should be done if not? The manual doesn't elaborate very much on this topic.
Thanks
The manual is slightly outdated in parts - it says to use consult/1, whereas elsewhere it states that consult/1 is deprecated, whereas include/1 is the replacement.
Secondly, when using 2p.jar, it reads Prolog files from the Project root as its root. When creating a jar, 2p.jar cannot be inside of the project jar. They should be in relative folders, and 2p.jar reads Prolog files with the location of 2p.jar as root. It doesn't seem that it can read inside of project jar.
Hopefully that's clear enough!

Java FileInputStream can't find file (LibGDX)

So I have this class:
http://pastebin.com/EwXFwuZz
And this directory tree:
http://s14.directupload.net/file/d/3099/uskko5mo_png.htm
And I'm working with the LibGDX Framework on this project. This is basically my problem:
I have a file that contains level information in "chunks". Each line is one chunk. I want to read the file line per line. Unfortunately the built in FileHandling system of LibGDX doesn't support line by line reading so I thought to stick to the stock java one.
However I'm getting this "FileNotFound" Exception:
java.io.FileNotFoundException: ./assets/data/lvls/example.txt (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:120)
at java.io.FileReader.<init>(FileReader.java:55)
at gemini.cute.game.xvii.database.LevelReader.<init>(LevelReader.java:49)
at gemini.cute.game.xvii.core.MainLauncher.create(MainLauncher.java:40)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:124)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:107)
With LibGDX the file is found but read into ONE single gigantic string. And for some reason with the same path (even going from the root) the file isn't found.
For people not familiar with LibGDX I'm coding in the upper "CuteGameXVII" project but for compilation I run the "Main" in "CuteGameXVII-desktop". The assets folders are linked via eclipse and worked for other resources so far.
Am I missing something super obvious here? If so, please help me :P Thank you in advance.
If you're running the Java program from a directory with path $DIR, the input file should be at $DIR/assets/data/lvls/example.txt. Based on the exception that you've received, the input file doesn't exist at this location.
I'd suggest that you first try using the absolute path to the input file in your code. Then, figure out what the relative path to it is.
I experienced this issue too. In order to read a file from your asset directory with LibDGX you must use the LibGDX method replacing:
new FileInputStream("SomeFile.txt")
by
Gdx.files.internal("SomeFile.txt").read()
assuming "someFile.txt" is in your asset root folder.

Categories