Running and Importing files folder along with runnable jar in eclipse - java

I have a project in eclipse where all my source code is under mbl/src. I am exporting this code as a runnable jar. I have got another folder under mbl/files which contains some of the properties files.I want to export these files also but eclipse doesnt give any such option. I have put the mbl/files under add class folder in build path options but still I am facing similar issues. I have also put the files folder directly under src folder but still it is not able to access it.I am using following options in commandline.
java -jar myprogram.jar arg1
It gives this error:
Unable to find files/text1.properties
text1.properties is under mbl/files/text1.properties
and is referred in the following manner from main class:
FileInputStream fs=new FileInputStream("files\\text1.properties");

Resources in bedded within Jars, need to be read via the Class.getResource(...) method.
This method returns an URL object, from which you can obtain an InputStream

Related

Executable Java JAR can't find file path

I am facing problem while running executable .jar file via java -jar my.jar. I've created a project which contains a .sh file under src/main/resources/ path. In the code i am referring it to execute as:
Process pb = new ProcessBuilder("src/main/resources/stacktrace.sh",pid, traceFilePath,timeInMin).start();
It works just fine when I run my application from Intellij but when I export it to executable jar file and try to run it complains:
Exception in thread "main" java.io.IOException: Cannot run program "src/main/resources/stacktrace.sh": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
The path you used in your ProcessBuilder is relative to the current working directory. When you run your code from your source project the path exists, but when running the jar the current working directory is different as you are not running it from within your source project. Therefore when your code attempts to find "src/main/resources/stacktrace.sh" it fails to find it.
For example, maybe your source project is located in:
/myCodeProject
So when you run your project your path resolves to:
/myCodeProject/src/main/resources/stacktrace.sh
When you run your jar perhaps you're running from somewhere like:
/opt/app/myApp
Therefore your path resolves to:
/opt/app/myApp/src/main/resources/stacktrace.sh
and it is this path which does not exist.
EDIT:
As requested I am adding some ideas regarding how to correct the problem. However, your requirements are not clear as to where you want the file to live. Should it be outside the jar? Inside the jar? If it's outside will it be located in a specific constant path or relative to the jar?
There's the obvious fix: put the file in the expected path so that it will be found.
The other obvious fix: change the relative path so that it points to where the file is actually located.
Build your jar such that the file is included inside the jar and use one of these methods to access it. Note that you may not be able to directly run the file, but you could read its content and generate an external temporary file and run that.

How to load resources from /src/main/resources in a way that will work both directly from Eclipse and in a runnable JAR?

I have a Maven project in Eclipse with a main() method. The project has a dependency that uses embedded resources, i.e. it contains files in /src/main/resources. I would like to create a runnable JAR file from the project. The problem is that - depending on how I load the embedded resources - I can either run the project as a runnable JAR using java -jar my.jar, or I can run it directly from Eclipse, but not both - the reason being that the path to these resources obviously differs between the two cases.
For example, I can load the resources as follows:
// Loads /src/main/resources/script.rb;
// Works when run directly from Eclipse; throws an exception when run as a runnable JAR
InputStream resource = this.getClass().getResourceAsStream("/script.rb");
This way, I can successfully run the project directly from Eclipse. Creating a runnable JAR using Eclipse's Export → Runnable JAR file puts the script.rb resource inside the resources folder in the JAR's root, which makes the above code fail when I try to run it as java -jar my.jar. I can fix this by changing the code to point to the /resources folder:
// Works when run as 'java -jar my.jar', fails when run from Eclipse.
InputStream resource = this.getClass().getResourceAsStream("/resources/script.rb");
Now, the exported JAR file works fine, but I can no longer successfully run my project as a Java application directly from Eclipse.
I read several other posts on loading resources, but nothing helped so far.
Is there a way to fix this and load the resource in a way that works correctly in both cases? What would probably work is convincing Eclipse to put resources inside the JAR's root instead of inside the resources folder, but I'm not sure if this is possible.
Using Class.getResourceAsStream(...) will load relative to the package. You should use Classloader.getResourceAsStream(...) to load from root.
Eg
InputStream resource = this.getClass().getClassloader().getResourceAsStream("script.rb");
(Assuming that src/main/resources is on the ecliplse classpath)
Note: the / has been removed!

Create jar file from java file

I have a java file with few classes.
I have tried to create jar file but it didn't work. I used eclipse and terminal (mac). For the terminal, I tried to use the command:
jar -cvf jar filename class file class file
I created that jar file but then it didn't work.
Please let me know what is the best way to create jar file.
Thank you
I believe that when you say it didnt work, what you mean is, you couldn't execute the packaged jar file that you created.
A jar file is little more than just a zip of all classes and resource files. You need to add details into META-INF/MANIFEST.MF file so that the class containing the main method to be executed is know.
Alternately you can try invoking the jar file as follows:
java -cp <jarfile.jar> <Complete.Package.ClassNameWithMainMethod>
You did not specify what's not working, but here is the official documentation if it helps any: http://docs.oracle.com/javase/tutorial/deployment/jar/build.html.

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.

How should resources in a compiled jar be accessed?

First of all, I have read through many S.O. questions regarding this topic and I have tried the things suggested in them.
Here is my situation. I am writing a Java app using the Processing framework and I'm in the final stages where I need to begin thinking about packaging the app. A jar file that is executable from the command line is what I'm attempting to build using the Export feature in Eclipse.
The structure of my project looks like this:
src/
multiple packages/
libs/
jar files and natives
data/
fonts and images
config/
json files
When I export the jar file and uzip the jar to inspect it's contents, I find that the contents of these dirs have been dumped in the top level of the .jar.
Which looks like this:
.jar
packages
jar files
fonts
json files
So, when I attempt to load a config file with something like:
BufferedReader reader = new BufferedReader( new FileReader( path ) );
Everything works just file when I run the app in Eclipse. But the jar file throws a FileNotFoundException.
Many of the questions that I've seen on S.O. regarding problems like these recommend using using class.getClass().getResource() or class.getResourceAsStream(). I have tried both of these using relative paths and just the file name as in:
class.getResource( 'config.json' );
class.getResources( 'cfg/config.json' );
class.getResourceAsStream( '../../config.json' );
All of these methods return null, when run from either Eclipse or the jar using:
java -jar myjarfile.jar
I am also open to using an Ant file. In fact, I'm now using the Ant file generated by the export feature to build the jar. If there is something I can add to that to add the directories into the jar that would be great too.
To reach resources in the root, prepend a / to the path. If not, you do it relative to the current package, which is usually only useful if the resource is physically next to the class in your sources too.
So use class.getResourceAsStream("/config.json"); to reach config.json in the root of the jar.
Also note that jars-inside-jars are not directly supported.
Your .jar file should just include the directories related to the "package" for the compiled code. You might be referencing a .war structure with /lib /WEB-INF etc. and this is different.
If your package structure is:
com.yourco.authentication
And your class in Login
Then your jar should be
/com/
/yourco/
/authentication/
Login.class
you then need the .jar in your classpath for the env to run via command line.
I see you note it works in Eclipse which likely has environment settings and imported required libs, etc. so hard to tell exactly. If your packages/ folder includes the compiled java code, I'm unsure if that'll work when referenced externally, thus suggesting you start your packages in the root folder.

Categories

Resources