Java isn't getting the file in the source code when compiled - java

Recently I have an issue with Java. I've tried some things I found on the web but they haven't worked, so I need help.
I have a Java project in Eclipse. My main class is in src/programCode/UI_Main2.java. In that .java I try to access to a file in src/files/File.file
And this is when the things fo weird.
If I use /src/files/File.file it gives me NoSuchFileException.
If I use src/files/File.file it works in Eclipse but when I compile it to a executable .jar it gives me NoSuchFileException.
If I use /files/File.file it gives me NoSuchFileException.
If I use files/File.file it gives me NoSuchFileException.
If I use files/File.file it gives meNoSuchFileException.
If I use this.getClass().getResource("/files/File.file").getPath().substring(1) (without substring it gives me Invalid character) it gives me NoSuchFileException (but it shows me the absolute path and the file exists there!)
If I use this.getClass().getResource("files/File.file").getPath() it gives me NullPointerException and the program crashes.
If I use this.getClass().getResource("src/files/File.file").getPath() it gives me NullPointerException and the program crashes.
If I use this.getClass().getResource("/src/files/File.file").getPath() it gives me NullPointerException and the program crashes.
So, I don't know what to do. src/files/File.file is the only one that works, but it doesn't when compiled to executable jar. So please, help me, I haven't found any solution yet.
Thanks!

Finding a file depends on two things:
Whether you use absolute or relative path
Where is your working directory
Under Unix-like system when you use path like /dir1/dir2/file you use absolute path, so your working directory doesn't matter, but you must have a file exactly under that path.
In your case you try to use relative path, so you shouldn't use / at the beginning.
This case is crucial to your problem:
"If I use src/files/File.file it works in Eclipse but when I compile it to a executable .jar it gives me NoSuchFileException."
By default Eclipse uses as working directory a parent directory of src (which is usually a direcotry with your project", so starting from there you indeed have a file under that path.
When you start a .jar your working directory is somewhere else. Put your .jar to parent directory of src and it should work.
Now, I suggest that you change location of the file to a directory other than src (call it Resurces or something) and provide it along with the .jar.
Also, here is an interesting discussion about working directories and .jar files:
Current working directory when running a Jar
If you want to distribute a single .jar here is a good packaging instruction:
http://www.cefns.nau.edu/~edo/Classes/CS477_WWW/Docs/pack_resources_in_jar.html

Assuming your intent is to rum your compiled program on YOUR own development computer, you need to provide the full path to the file you want. That full path would be of the form
<Eclipse workspace location>\<project name>\<file location in project>

Related

Create directories and files by given path with jar

I have a java maven project, which converts .json files to .yaml and vice versa. Long story short,I wrote method which creates resulting directory of converting process using path of where jar actually is. Then I created the method which creates files and writes there result of converting process to the /path_of_resulting_dir/file-name.json/.yaml. In case I run jar from my project in IntelliJ idea - everything is ok. However, when I run jar file from random folder on my desktop, nothing happens.
So, how can I correctly make jar to know if there are any files I should convert placed next to the jar file(e.g. C:\path_to_jar\SomeJarDir\jar.jar So files are in the SomeJarDir with a jar), or if there are any files which I access from path I write as jar argument need to be converted.
Link to the GitHub, where is my code placed(old version where I haven’t tried to make jar to know what to convert from any folder it’s placed, which works only if u run jar in IntelliJ idea):
https://github.com/foreverdumb/javaSprSum2021/tree/JavaSprSmrHmwrk/michaelProject
P.S. How can I force log4j to create log file next to jar?
your program maybe using relative path, so when you run your program from different location, it will read the directory relative to itself. Either provide the path during runtime as user input or set the absolute path to the jar.

Java - How does relative folder creation differ from non-compiled code to an executable

I am making a Java program that I will wrap to become an .exe for testing and production. Part of the programs initialization process is to make a folder named "config" on the same level as the executable file. For illustration:
---> Parent Folder
---> myProgram.exe
---> config/
That is what ideally what should happen.
As of now, I'm testing this block of code:
String config_dir = "./config";
if(!new File(config_dir).exists()){
new File(config_dir).mkdirs();
return;
}
And what it does is to check if the directory exists, and create it if it doesn't.
However, this code is run by my Main.java class, and when it goes one level higher to create the config directory, it is still on the same level as the other folders inside the workspace directory:
---> MyProject
---> bin
---> external_lib
---> src
---> config
Which makes sense since I only made the app create the folder one level higher. However, after it is packaged as an exe file, it needs to make that folder on the same level as the exe file. I am just worried that it might not work that way.
Does anyone have a way to ensure that a folder is created on the same level as the packaged executable Java file? I'm working on a Mac and it might take time to be able to test it.
From a "running a JAR" perspective, you could use
System.getProperty("user.dir")
which returns the path where the JVM was started from. Once you turn this into an executable, I'm unsure exactly what you might need. But you might also try
getClass().getProtectionDomain().getCodeSource().getLocation()
Java
Irrelevant.
How does relative folder creation differ from non-compiled code to an executable?
It doesn't.
I am making a Java Program that I will wrap to become an .exe for testing and production. Part of the programs initialization process is to make a folder named "config" on the same level as the executable file.
For that purpose you need to know the location of the executable file. For a C or C++ executable that is given by argv[0] of the main() method. For Java JAR files it is given by getClass().getProtectionDomain().getCodeSource().getLocation().
String config_dir = "./config";
That will create a folder in the current working directory of the user, same as returned by System.getProperty("user.dir"). Not 'at the same level as the executable file'.
However, this code is run by my Main.java class, and when it goes one level higher to create the config directory, it is still on the same level as the other folders inside the workspace directory:
It is still in the current working directory. Your workspace has nothing to do with it unless it is the current working directory.
However, after it is packaged as an exe file, it needs to make that folder on the same level as the exe file.
No. In the current working directory. Always. That's what . means.
Does anyone have a way to ensure that a folder is created on the same level as the packaged executable java file?
See above, but, judging by comments and what you've accepted in your own answer, I don't think that's what you actually want. I think you want it in the current working directory, and that's what you're getting. What the current working directory actually is depends on how you run the program, and where from. If you run from within the IDE you will get the IDE's idea of it. If you run from a command line you will get the shell's cwd. If you run by double-clicking you will get whatever cwd is defined for the double-click, which may be the directory of the executable or JAR file.

Building file.jar, External Executable File missing

Assuming that I use NetBeans 7.3 , I created a project that, in a nutshell, receiving as input a set of parameters, it returns as output a print on screen. The project is made up of a number of directories. Each directory contains a class (in file.class form). One of these directory contains an executable in C. I wrote it as the kernel of the Java project.
I built file.jar and I added it as a library in a new project. When I tried to test it, an error message made ​​me realize that the C written program is not was automatically added to file.jar under construction.
One of my first attempt to solve this problem was to manually add the C-executable file. By using the JAR command from the terminal on my Mac, I was able to update the file.jar adding the executable in the right subfolder.
This solution is not served because, moving from project to file.jar, the relative path that leads to the execution of the C-program has changed. So I tried to change this path seeing it from the point of view of file.jar. Yet this attempt was futile.
I defer to those with more experience than me in the packaging and distribution of Java content.
As far as I know, an operating system cannot directly execute an executable that is inside a zip file (which is what a jar file actually is). It has to be first extracted.
So your program could first open its own jar file and extract the executable file into a file on disk, then run that file.
You can create an installer program, to install both the jar file and the executable file to a suitable location on the user's disk.

How to make jar files that draw from a source folder

I've been wanting to make executable jar files with java lately. When executing my code with Eclipse it works perfectly. But when I use Eclipse to export the same code as a runnable jar, Most of my jars work except the ones that draw from separate source folders.
The jar will be made but when launched it will try and open and then just say to check to console for possible errors. I try and run the jar through the console with the command "java -jar test.jar". and It says it cannot access the jar. Any Ideas? Btw Im on a macbook pro osX. Thank you!!
picture of where my files are within eclipse
If you have a file you want to store in a jar and access from there, you don't really have a Java File any more. Look at Class.getResourceAsStream() and Class.getResource() - the first can give you an InputStream to the (used-to-be) file, the second returns a URL and can be used for things like images. Note that the file being accessed can be accessed relative to the package/folder location of the class or relative to a classpath root (by putting "/" at the front of the resource name ("/resource/funny.jpg")).
When you execute the jar from a command line, be aware that you have a thing called the "default directory"; it is a folder in which your commands execute by default. If your jar is not in the default directory, you have to specify a valid folder path to your jar to execute it.

Converting Java URL to valid File path in Linux

Ok I'm developing in Linux using Eclipse a program that needs to read a text file. The idea is to have the JAR and text file on the same folder. So I'm getting the text file path like this:
Client.class.getClassLoader().getResource("Client.class");
This correctly returns the path and I append the file name and get the below path:
/home/marquinio/workspace/my_project/info.txt
Problem is when I export my project into an executable JAR file. The JAR can't read the file. I double checked and everything looks fine. The only problem I see is that now the path has some "file:" appended at the beginning like this:
file:/home/marquinio/workspace/my_project/info.txt
which is probably why I'm getting a "FileNotFoundException". The JAR and text file are both in the same folder.
Anyone knows how to fix this? Why would Java behave different between Eclipse and executing JAR in command prompt?
Is there a replacement to the "...getResource(...)" provided by Java without that "file:"?
NOTE: this JAR should also be compatible in Windows environment. Still need to test it.
Thanks in advance.
The resource you are referring to is not guaranteed to be a file on the file system. Why not use ClassLoader#getResourceAsStream()? Without looking into the details, my best guess is that the different behavior you are seeing is because a different classloader is being used in each case above.

Categories

Resources