I read some tutorials on how to read data from a database.properties file- which basically stored key-value pairs.
What i want to know is, in which folder should I place this file? Is it in the root (ie "src") or within a package... And how do I access this file, if it is placed in "src"- my code will be within a package (and the package's directory will be under src)- so how do I access the properties file, which is in "src", from a class within a package?
Ideally it should be in the external folder(src/main/resources) not along with the .java.
Use ResourceBundle for reading it.
Best approach is under src/main/resources.
Where to place your file is a subjective matter (of which I am no expert.) However, you should remember that your classpath begins with your project folder implicitly. Also, you can access your packages the same way as you access a folder on your OS.
So a file in your src package named foo.txt would be : loadingMethod("src/foo.txt")
Related
I have a class within a Maven project that I am trying to use to get user data and map it to a json file located in another folder outside of the one the compiled jar is located.
My question isn't necessarily how to append data to a json file, but rather how I can get the location of the json file I'd like to append my data too.
Take for instance I have a project with folders like:
Project/src/main/java/com.website.project/Class.java
Once that I have this project packaged into a jar file, I would then place it in a folder where it would be run:
App/jars/Project.jar
I want it to access a json within the folder:
App/json/file.json
What code would I need to write to access the directory from my Class.java?
I am sorry if this was confusing, I'm not the best when it comes to Stack Overflow, but thank you so much for any help in advance!
You could keep your App/json/file.json in src/main/resources folder.
Path - src/main/resources/App/json/file.json
Then you could access it by :
JSONTokener parser = new JSONTokener(this.getClass().getResourceAsStream("/App/json/file.json"));
JSONObject jobj = new JSONObject(parser);
jobj.put("style", style[i]); // If you want to add a new key value or just replace it
The file itself will get packaged in JAR file
Don't forget to include org.json in your pom.xml dependency.
Import this in your class:
import org.json.JSONObject;
import org.json.JSONTokener;
First approach:
Please test if you can find the file with:
File file = new File("./../json/file.json");
System.out.println("File exists: " + file.exists());
Relative paths in java start with ./. When you export your jar the relative start path is the location of the jar => App/jars/ so you need to go one folder up with ../ and after that go inside /json/file.json
The disadvantage of this approach:
To work with file outside your java project (assuming your java project is in java directory) means that you have to create every time this folder structure everywhere. For example in your case if you want to work also in you IDE inside of your workspace of projects you have to add directory json and after that your file.json.
Second approach:
Another solution can be to add your file inside the java project itself. Then you will be able to read your file easy with getClass().getResourceAsStream("file.json");. Consider that file.json is inside your class's package. This way you can test and see 'file.json' also inside your IDE.
The disadvantage of this approach:
Pay attention that if you use your file inside the Java project it will end up in the jar. When this happen you no longer can access it as File. That why I am useing getResourceAsStream method in this case. To read more about this see answer:
https://stackoverflow.com/a/20389418/6068297
Also you have to know that getClass().getResourceAsStream("file.json"); will not work in static methods for example in public static main(String[] arg).
Update:
Also the jar file is meant to be archive so it must stay unchanged. So you can not (you should not) write back changes to file inside the jar. If you need to have some modifiable file then you should create it outside the jar. You can add it relative to the jar location or in a place like home directory of the current user where relevant files to the current user (who is using your application) can be created without some additional permissions.
Third approach:
You mention that you are using Maven project. There is a folder in the Maven project which is called resources => src/main/resources. This folder end up in the classpath so you can also put your file file.json there and read it as second approach with getResourceAsStream. This way you can have clear separation between java classes and other files.
The disadvantage of this approach:
The same disadvantages as in the second approach.
I hope it helps.
I'm trying to load a .csv file in a program but for some reason, it's unable to find the file. Where should I place the file?
Console
It looks like the file is in the src directory... which almost certainly isn't the working directory you're running in.
Options:
Specify an absolute filename
Copy the file to your working directory
Change the working directory to src
Specify a relative filename, having worked out where the working directory is
Include it as a resource instead, and load it using Class.getResourceAsStream
The file is located in the src directory so in order to access it you should use
src/Elevator.csv
As long as files are located inside your project folder you can access them using relative paths.
For example if a file is located under the Elevator folder then you access the file by using only its filename.
Elevator.csv
A good principle when using additional files in your project is creating separate folders from the ones that the source files are located. So you could create a folder resources under the project folder and place your file there. You can access then the file by using
resources/Elevator.csv
the path which it is trying to read is surely not exact as the path in which that file is actually present.Try printing absolute path of that file and compare it with actual path of your file.
I tried with all the above mention solution, but it didn't work..
but i went to my project folder and delete the target and tried to compile the project again. it then worked successfully
My code cannot locate the .properties file where i have stored login information.
I have put the file in the src folder to make sure it compiles, and it does correctly.
below is the current location of the file and how i am trying to access it.
I have tried various different paths but no luck.
Change your code;
ResourceBundle bundle = ResourceBundle.getBundle("Selenium/readme");
to
ResourceBundle bundle = ResourceBundle.getBundle("readme");
You don't compile a .properties file, you use it as is.
If you use a FileInputStream it will use the working directory which is set in your Run configuration (most likely the top directory)
But you are loading it as a resource which means it must be in your class path. The simplest thing to do is to create a sub-directory for your configuration and add this to your programs class path.
Read properties file like:
ResourceBundle.getBundle("src/properties/readme.properties"); //Or simply "properties/readme.properties"
Put readme.properties under src/properties directory.
you can use this.getClass().getResourceAsStream("readme.properties");
for more information read:
I see that the .properties file is not inside the src folder. Also check the build path of your project.It will show you the src folders and the output folders location. Once you build the project using eclipse build project option, make sure your properties file is now available in the output folder.
Lots of confusion in this topic. Several Questions have been asked. Things still seem unclear.
ClassLoader, Absolute File Paths etc etc
Suppose I have a project directory structure as,
MyProject--
--dist
--lib
--src
--test
I have a resource say "txtfile.txt" in "lib/txt" directory. I want to access it in a system independent way. I need the absolute path of the project.
So I can code the path as abspath+"/lib/Dictionary/txtfile.txt"
Suppose I do this
java.io.File file = new java.io.File(""); //Dummy file
String abspath=file.getAbsolutePath();
I get the current working directory which is not necessarily project root.
Suppose I execute the final 'prj.jar' from the 'dist' folder which also contains "lib/txt/txtfile.txt" directory structure and resource,It should work here too. I should absolute path of dist folder.
Hope the problem is clear.
You should really be using getResource() or getResourceAsStream() using your class loader for this sort of thing. In particular, these methods use your ClassLoader to determine the search context for resources within your project.
Specify something like getClass().getResource("lib/txtfile.txt") in order to pick up the text file.
To clarify: instead of thinking about how to get the path of the resource you ought to be thinking about getting the resource -- in this case a file in a directory somewhere (possibly inside your JAR). It's not necessary to know some absolute path in this case, only some URL to get at the file, and the ClassLoader will return this URL for you. If you want to open a stream to the file you can do this directly without messing around with a URL using getResourceAsStream.
The resources you're trying to access through the ClassLoader need to be on the Class-Path (configured in the Manifest of your JAR file). This is critical! The ClassLoader uses the Class-Path to find the resources, so if you don't provide enough context in the Class-Path it won't be able to find anything. If you add . the ClassLoader should resolve anything inside or outside of the JAR depending on how you refer to the resource, though you can certainly be more specific.
Referring to the resource prefixed with a . will cause the ClassLoader to also look for files outside of the JAR, while not prefixing the resource path with a period will direct the ClassLoader to look only inside the JAR file.
That means if you have some file inside the JAR in a directory lib with name foo.txt and you want to get the resource then you'd run getResource("lib/foo.txt");
If the same resource were outside the JAR you'd run getResource("./lib/foo.txt");
First, make sure the lib directory is in your classpath. You can do this by adding the command line parameter in your startup script:
$JAVA_HOME/bin/java -classpath .:lib com.example.MyMainClass
save this as MyProject/start.sh or any os dependent script.
Then you can access the textfile.txt (as rightly mentioned by Mark) as:
// if you want this as a File
URL res = getClass().getClassLoader().getResource("text/textfile.txt");
File f = new File(res.getFile());
// As InputStream
InputStream in = getClass().getClassLoader()
.getResourceAsStream("text/textfile.txt");
#Mark is correct. That is by far the simplest and most robust approach.
However, if you really have to have a File, then your best bet is to try the following:
turn the contents of the System property "java.class.path" into a list of pathnames,
identify the JAR pathname in the list based on its filename,
figure out what "../.." is relative to the JAR pathname to give you the "project" directory, and
build your target path relative to the project directory.
Another alternative is to embed the project directory name in a wrapper script and set it as a system property using a -D option. It is also possible to have a wrapper script figure out its own absolute pathname; e.g. using whence.
I have a java desktop app and the issue of config files is vexing me.
What I want is for my distributable application folder to look like this:
MyApp/Application.jar
MyApp/SpringConfig.xml
MyApp/OtherConfig.xml
MyApp/lib
But at the moment SpringConfig.xml is inside Application.jar and I can't even find OtherConfig.xml programmatically.
I don't care how I set up the various files in my compilation path, so long as they end up looking like the above.
So..
where do i put the files in my dev setup?
and how do i access them programmatically?
thanks
the spring config file is related to the code and wiring of your application, hence it'd better be inside the jar, and should be subject to change by the users
(new File(".")).getAbsolutePath(); returns the absolute path of your jar - then you can load the OtherConfig.xml by a simple FileInputStream
if the SpringConfig.xml contains configuration data like database credentials, put them in an external application.properties and use a custom PropertyPlaceholderConfigurer to load the external file.
Answering the question "where do I put the files in my dev setup" is not possible because we don't know your environment.
Actually, if you want to be able to edit the config yourself (and not necessarily end-users), you can open the jar with any zip software (WinRAR for instance) and edit the config file from within the jar.
Update: as it seems you can't make the config files to be places out of the jar. Well, for a start, you can do it manually - whenever the .jar is complete, just remove the config file from inside and place it outside.
I typically create a structure where I have a src/ directory and then other directories exist at the same level. Some of those directories include:
lib/ - External Libraries
config/ - Configuration Files
resources/ - Various resources I use (images, etc)
At that same level, I then create an Ant script to perform my build so that the appropriate config files, resources, lib, etc are copied into my JAR file upon build. It has worked great for me up to this point and is a fairly easy to understand organizational structure.
Update: Accessing my config files is done, typically, by knowing their location and opening them up and reading them in the code. Because I use Ant to build, I make sure that my config files are in a location that I expect. So, for example, in a recent application I created, when I compile, my JAR file is in the top level directory (relative to the application release structure). Then, there is a "main" config file at that same level. And there is a "theme" config file that is in a themes folder.
To read the various files, I just open them up as I would any other file and read them in and go from there. It's nothing particularly fancy but it works well and it makes it easy to manually change configurations if I need to do so.
In dev mode, put them in source dir and they will be copied to your classes folder, you can then access them using classloader.
Example:
URL url = ClassLoader.getSystemResource("test.properties");
Properties p = new Properties();
p.load(new FileInputStream(new File(url.getFile())));
In Prod mode, you can make them part of your jar.