Access .properties file at same level as working directory - java

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

Related

How to give relative path in a executable jar?

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

How to add a .dic and .aff file to a java jar?

I was wondering if there is a way to add .dic and .aff files to a java project jar file (using eclipse for example)?
I have in my code a dictionary:
URL dicDic = CipherTextAttack.class.getResource("en_US");
static Hunspell.Dictionary dict = Hunspell.getInstance().getDictionary(dicDic.toString());
I need the jar file to run everywhere without needing the en_US dictionary file..
Is that possible?
Yes, a jar file is basically a zip file with a .jar extension, so you can put any file in the archive. You can then access that file from your code as long as it is in the classpath. One easy way to do it (but not so clean for big codebases) is to put the file in the same directory structure as your class files.
To access the file, you can use Class.getResource() as you show, giving a path relative to the class used, and it will be searched using the class loader of the class used.
So in your use case, the easiest is probably to put the file in the same directory as the class using the dictionary. For example, in your code is in MyClass, you would write:
URL dicDic = MyClass.class.getResource("file.dic");
C.f. the javadoc of the method.
Then to add the files in the jar, this will depend on your workflow and how your build your project (using Eclipse, ant, maven, etc). For example, if you use ant to compile and package your project, there must be somewhere in your build file a jar task that creates the jar file. You should then modify that task to include the dic file in the jar file. In case of doubt, and if you can't find an existing answer, I'd suggest opening a separate question about your particular tool.
In any case, for the purpose of the test, you can simply open the jar file with Winzip or 7-zip or whatever zip file manager that you use, and add the dic file to the archive.

Launch .jar with config outside of jar, but be able to do it from ANY current directory

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.

How to build a java project with all the required files and folders?

I created a simple application which will read all the files and folders kepts inside a folder. Whenever I build the project, I only get the jar file but the folder where the file and folders are kept have to be created. Is this supposed to be like this or I have to code something, which will create the folder upon the final build.
Compilation gives you only executable file (i.e. *.jar). If you need something else to make you application works - you must do it (programmatically or not).

Properties file in Eclipse

I have an application that uses a properties file that was added by hand at the /project/bin folder (Eclipse project). The application locates the file using:
this.getClass().getClassLoader().getResourceAsStream("filename.properties")
Now I want to add this file in Eclipse, so it's actually part of the project. In which directory should I create the file and how can I make sure the application will find it?
Thanks.
You can put the .properties file anywhere under a project source directory (src by default) to make it wind up in the build directory (bin by default) as a "resource", when the project is built. Since the bin directory is generated, you can't modify its contents by hand, in the way you describe.
There's no need to call getClassLoader(); just getClass().getResourceAsStream("foo") is fine.

Categories

Resources