I have a Spring app that I am deploying as a .jar.
The app has to write to a folder located in /src (precisely /src/main/resources/patches). I have this path directly in the code.
In application.properties: PATCH_DIR = src/main/resources/patches
The app has to also read a json file from src/main/resources/myJson.json, the path also being directly written in the code.
Prior to deploying, while running from the IDE everything goes well, the app sees the file and the folder and reads and writes correctly.
After building the .jar the paths change, the file is located in myJar.jar/BOOT-if/classes/myJson.json and the folder is respectively in myJar.jar/BOOT-if/classes/patches.
How can I specify these paths in the code in a way that even after building the jar they stay relevant to my application?
Edit: I can specify the path of the file as: PatchApplication.class.getClassLoader().getResource("myJson.json").getPath();
This should solve the problem, as the path is relative to the class and not to the root of the project, but it does not improve anything.
You should specify a path in your file system,instead of the path inside a .jar.When you run your app ,it would access the given path.
generally all the classes goes to classes folder in jar.
all the classes ending after src/main/java goes to /classes/ folder
and similarly all the resources file
Eg. your source folder have src/main/java/com/mypack/ABC.java than you will find this in jar as /classes/com/mypack/ABC.class .
Try using /classes/patches and /classes/myJson.json.
This should work
Related
I would like to ask how to define path to files stored directly in my project folder. When i generate .jar file, xml file is stored in main folder in .jar.
private static final String PATH_TO_XML = "xmlOutput.xml";
This is working when I run project in Netbeans IDE. However, executing .jar file throws exception that file cannot be found. I tried some ways but i cannot find the way to specify path to file to be working in IDE and also as .jar file.
I read information about access as stream. However, my application executes XSLT transformation using XsltTemplate.xsl, xmlOutput.xml and htmlOutput.html so I need to use this file for transformation.
Thanks for help.
It might help to think about where the referenced files are stored in each context. If these are not packaged in the JAR like they are located in the IDE's project, then they won't be found. It might be best to configure the location in some configuration file and/or use an absolute path which is also available when running the JAR.
I am trying to export my app into jar using intelij Idea artifacts. I export everything except for resources (14,5GB is in my opinion too much for .jar file) so I have put /res folder inside same folder as jar.
Right now my structure looks like this:
/SAR.jar
/res/colors/
/res/icons/
/res/map/
However I cant access this resources. I am using the following code to get path:
dir = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath() + "/res/icons/");
It works when running from IDE and it prints correct location. But when I build an artifact and run it through cmd I get the null pointer and it prints this path: D:/JavaProject/SAR/out/artifacts/SAR_jar/SAR.jar/res/icons. But my resources are not inside jar file they are only in same directory.
Any ideas? I have done only android projects in path and I simply cant get this resources system with jars to work.
Thanks in forward
You are trying to access the ressources with a path dependent of your source code location, which is obviously not the case since you separated the code (or bytecode in the case of the jar) and the ressources. You must access them with a path relative to the jar or an absolute path.
I think you just need the following path (if the jar was ran from the directory containing the jar) :
new File("res/icons/icon.png")
We have a jar which needs to read a properties file. The properties file needs to edited without rebuilding the application, therefore it is excluded from the build.
In order for the application to see the properties file, it is placed it a folder which is on the java classpath. The format of the Windows command line used to run the application is as follows:
java -cp application.jar;.\lib_folder\*; com.company.Start
Java correctly picks up all the jar files in the lib_folder. The properties file is placed in the same folder, but the application cannot see it and is throwing a FileNotFoundException. Are we doing anything obviously wrong?
Thanks very much
The class resolution happens starting from the path given in cp. If you provide .\lib_folder in the classpath without the star, and the properties file is inside this folder, then it will be picked up. Currently the properties file itself is in the classpath.
it is placed it a folder which is on the java classpath
Your class path only contains JARs, the notation .\lib_folder\* means every jar from a folder, but not the folder itself.
The properties file is placed in the same folder, but the application cannot see it
The folder itself need to be added, however I suspect you shouldn't be adding files to the "lib" directory and you should be using a different directory like "config"
and is throwing a FileNotFoundException.
When you try to obtain a Resource you get null not this exception. Try the following
InputStream is = getClass().getClassLoader().getResourceAsStream("resource.properties");
This returns null if the file is not found.
Are we doing anything obviously wrong?
FileInputStream looks for a direct file, it doesn't use the classpath.
If you're using ResourceBundle to read the property files, then just add the top level project containing the .properties files to the classpath.
I've been wrestling with a particular problem. I have a Java program in a .jar file, and I have a lib directory and a config directory outside of the .jar, but in the same directory as the jar itself exists in.
I am trying to reference config/foo.config from within the code. Referencing it as a relative file works if I'm in the same directory as the jar. I've also tried using getResourceAsStream and making sure config is in the classpath.
So far, so good, but I also have to be able to launch the .jar from any directory.
So, if my structure is like so:
/prog/util/myprog/myprog.jar
/prog/util/myprog/config
/prog/util/myprog/config/foo.config
/prog/util/myprog/lib
(and a whole bunch of 3rd party jars within lib)
How do I correctly set up the classpath in my Manifest file so that config can be referenced?
The classpath in my manifest looks like so:
Class-Path: config/ lib/jar1.jar lib/jar2.jar (etc)
I am currently using getResourceAsStream("/foo.config").
This all works if I am in the /prog/util/myprog directory and run:
java -jar myproj.jar
However, I cannot, say, be in /prog and run:
java -jar util/myprog/myprog.jar
When I do this, the config file cannot be found.
How do I solve this issue?
EDIT: Some additional notes based on comments/suggestions, though I'm not sure this is feasible:
1) We can't use an absolute path for the file system, we don't know where the program will be stored, just that the config directory will be in the same directory as the jar.
2) I would like to be able to have something that works both when the code is jar'd, but also would work not-jar'd such as when I'm running in debug mode in Eclipse. At that point, the config directory is a sibling of the src, bin, and lib directories.
EDIT Part 2: Ok, between a colleague and myself, we came up with the following:
String configDirectory = new File(QueueMonitor.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getParent() + "/config";
When we are in Eclipse and running in debug mode, the File object points to the bin directory, so getting the parent then appending "/config" works for our needs during development/testing.
Likewise, from a .jar file, the File object points to the jar itself, so getting the parent and appending "/config" gives us what we need as well.
I'm a little hesitant, though. I'm wondering if there's some potential problem or unintended consequence that I am not seeing in this solution. Any thoughts on that?
You should be able to use the Finding the path to a jar from a Class inside it? technique to find the location of your jar. From there it's just a matter of climbing in/out of folders.
I am working on a Java project that I want to deliver to my client as a .jar file. However, I want to allow the client to be able to change the parameters of the program without having to recompile or recreate the .jar. Basically, I want to be able to load .properties files from classes inside the .jar but locate those .properties files outside of the .jar and even outside the working directory.
I have been testing my attempts inside Eclipse, which might be causing some of the problem but I don't see how at the moment. My setup is a follows. I have one project that contains a few classes that I build a .jar file from. I have a .properties file that is used to create a ResourceBundle whenever a class for the .jar is created. I specify that an additional directory, "conf/", be included in the .jar classpath within the .jar manifest.
Once the .jar file is built, it is copied to the lib/ directory of another project which I am using for testing. This test project includes the .jar file as a library ("Add External Jars..") in the Java Build Path. The .properties file is located the conf/ directory which is at the same level as lib/, src/, and bin/ but I am unable to accces it there. The only way I have been able to get it to work is to locate conf/ under src/ (and bin/) but I would like to be able to use it up one level. Is this possible?
Here's the entry in the .jar manifest file...
Class-Path: ../conf/
Here's the ResourceBundle call that I tried (didn't work)...
rb = ResourceBundle.getBundle("..conf.BaseProject");
Here's the directory structure that works now (names have been changed to protect the innocent)...
/Project
/Project/bin
/Project/bin/conf
/Project/bin/conf/BaseProject.properties
/Project/bin/TestClass.class
/Project/lib
/Project/lib/BaseProject.jar
Here's the directory layout I want (again, file names not important)...
/Project
/Project/bin
/Project/bin/TestClass.class
/Project/conf
/Project/conf/BaseProject.properties
/Project/lib
/Project/lib/BaseProject.jar
You can get it using the Classloader.
I like Spring's ClassPathResource