What is the path to resource files in a Maven project? - java

In my Maven project, I have the following code in the main method:
FileInputStream in = new FileInputStream("database.properties");
but always get a file not found error.
I have put the file in src/main/resources and it is properly copied to the target/classes directory (I believe that is the expected behavior for Maven resources) but when actually running the program it seems it can never find the file. I've tried various other paths:
FileInputStream in = new FileInputStream("./database.properties");
FileInputStream in = new FileInputStream("resources/database.properties");
etc. but nothing seems to work.
So what is the proper path to use?
Based on "disown's" answer below, here was what I needed:
InputStream in = TestDB.class.getResourceAsStream("/database.properties")
where TestDB is the name of the class.
Thanks for your help, disown!

You cannot load the file directly like that, you need to use the resource abstraction (a resource could not only be in the file system, but on any place on the classpath - in a jar file or otherwise). This abstraction is what you need to use when loading resources. Resource paths are relative to the location of your class file, so you need to prepend a slash to get to the 'root':
InputStream in = getClass().getResourceAsStream("/database.properties");

Related

Eclipse can't read text file in src folder

I am implementing a Branch Predictor for one of my classes and I am trying to read files from my src folder in Eclipse but for some reason it is not able to open the files. I have done this before with the exact same process so I'm not sure what is different.
traceFile is set from the command line and if I print "input", it will print out the correct file path and I have confirmed it is there manually.
ClassLoader loader = BiModalPredictor.class.getClassLoader();
File input = new File(loader.getResource(traceFile).getFile());
Scanner fin = new Scanner(input);
Is there any insight as to why this might be happening? I've tried restarting Eclipse, refreshing the files, and I've also tested it on another program which worked. No idea why it can't find this file.
Resources on the classpath, i.e. available through the classloaders getResource method, will not be files on the file system when your application is deployed as a jar file, or deployed in general. Do not use File with such resources, instead use getResourceAsStream to access the resource content.
Besides, your code is wrong. getResource() returns a URL. If you want a File object from a URL, you should use new File(uri), where the URI is obtained by calling url.toURI().
File input = new File(loader.getResource(traceFile).toURI());

unable to get file using classLoader.getResource(fileName).getFile()

I made a maven web-app project in eclipse it was working fine on the machine on which I made this. but when importing this project to other machine in eclipse it gives me this exception while getting the file:
exception:D:\Eclipse%20Workspace.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\example\WEB-INF\classes\file.txt
(The system cannot find the path specified)
I am using this code to get a file:
public File getFile (String fileName) {
//Get file from resources folder
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource(fileName).getFile());
return file;
}
the file is in the resources folder of the project:
D:\Eclipse Workspace\Sentiment Analysis\example\src\main\resources
I go the path the exception message showing and found that the file is already been there.
The getFile method of URL does not convert a URL to a file. It just returns the portion of the URL after the host and port. URLs need to percent-escape a lot of characters, including spaces, so you cannot reliably use the URL's path portion as a file name. In fact, the exception is telling you exactly that: There is no directory named D:\Eclipse%20Workspace.metadata.plugins on your computer. (Go ahead and check.)
When you have a URL, you should not be trying to convert it to a File at all. You don't need to. You can read from a URL just as easily as from a file using the openStream method of URL.
But even that is not necessary, because you can also use the getResourceAsStream method to skip the URL entirely and get a readable InputStream:
InputStream stream = getClass().getResourceAsStream("/file.txt");
The code is looking for the file in the same directory as this code class resident. What is the package structure of this code?
Also, only Maven copy the resources into the class path. So if you compile and run using Eclipse then the resources folder won't be copied automatically.

Absolute path of a file inside a project package

I've created a file inside a project package using this code:
File xmlFile = new File("src/com/company/project/xml/tags.xml");
I am able to read the file while running from eclipse. However, after creating .jar, I'm unable to read the file. So I want to put absolute path while reading the file from the project package. How it can be done? Help and suggestions are appreciated.
In most cases, IDE's will include no Java files in the resulting Jar. Most IDE's will also include the src directory in the classpath when you run/debug the program from within them.
As a general rule of thumb, never include src in any path, src will simply not exist once the program is built.
Instead you need to make use of Class#getResource or Class#getResourceAsStream, depending on your needs. You should remember, you should never treat an "embedded" resource as a File, as in most cases it won't be, it'll be a stream of bytes in a zip file.
Something like...
URL xmlFile = getClass().getResource("/com/company/project/xml/tags.xml");
will return a URL reference to the resource. Remember, if you need a InputStream, you'll have to Class#getResourceAsStream.
If you want the resource to be writable, then you will need to find a different location to store it, as embedded resources are read only
Try with getClass().getResource()
new File(getClass().getResource("src/com/company/project/xml/tags.xml").toURI());

File path errors in eclipse? (Java Spring)

InputStream inp = new FileInputStream("src/main/resources/ExportHour.xls");
I have a file in the src/main/resources folder of my Java Spring project.
I am attempting to create an inputstream in one of my Controllers, however I always get a file not found exception. When I change the path location to point specifically to the file on my machine, it works fine.
Any way I can make it so the file can be found within the java project?
Try with spring ClassPathResource.
InputStream inp = new ClassPathResource("ExportHour.xls").getInputStream();
That is because the resources folder in maven is put in your jar file directly i.e. the ExportHours.xls file is put inside your jar in the root directory.
It sounds like you could just change the working directory of your process - it's not where you think it is, I suspect. For example, I suggest you write
File file = new File("src/main/resources/ExportHour.xls");
and then log file.getAbsolutePath(), to see what exact file it's using.
However, you should almost certainly not be using a FileInputStream anyway. It would be better to use something like:
InputStream inp = Foo.class.getResourceAsStream("/ExportHour.xls");
... for some class Foo which has a classloader which includes the resources you need.
(Or possibly /resources/ExportHour.xls", depending on your build structure.)
That way even when you've built all of this into a jar file, you'll still be able to open the resource.

open resource with relative path in Java

In my Java app I need to get some files and directories.
This is the program structure:
./main.java
./package1/guiclass.java
./package1/resources/resourcesloader.java
./package1/resources/repository/modules/ -> this is the dir I need to get
./package1/resources/repository/SSL-Key/cert.jks -> this is the file I need to get
guiclass loads the resourcesloader class which will load my resources (directory and file).
As to the file, I tried
resourcesloader.class.getClass().getResource("repository/SSL-Key/cert.jks").toString()
in order to get the real path, but this way does not work.
I have no idea which path to use for the directory.
I had problems with using the getClass().getResource("filename.txt") method.
Upon reading the Java docs instructions, if your resource is not in the same package as the class you are trying to access the resource from, then you have to give it relative path starting with '/'. The recommended strategy is to put your resource files under a "resources" folder in the root directory. So for example if you have the structure:
src/main/com/mycompany/myapp
then you can add a resources folder as recommended by maven in:
src/main/resources
furthermore you can add subfolders in the resources folder
src/main/resources/textfiles
and say that your file is called myfile.txt so you have
src/main/resources/textfiles/myfile.txt
Now here is where the stupid path problem comes in. Say you have a class in your com.mycompany.myapp package, and you want to access the myfile.txt file from your resource folder. Some say you need to give the:
"/main/resources/textfiles/myfile.txt" path
or
"/resources/textfiles/myfile.txt"
both of these are wrong. After I ran mvn clean compile, the files and folders are copied in the:
myapp/target/classes
folder. But the resources folder is not there, just the folders in the resources folder. So you have:
myapp/target/classes/textfiles/myfile.txt
myapp/target/classes/com/mycompany/myapp/*
so the correct path to give to the getClass().getResource("") method is:
"/textfiles/myfile.txt"
here it is:
getClass().getResource("/textfiles/myfile.txt")
This will no longer return null, but will return your class.
It is strange to me, that the "resources" folder is not copied as well, but only the subfolders and files directly in the "resources" folder. It would seem logical to me that the "resources" folder would also be found under `"myapp/target/classes"
Supply the path relative to the classloader, not the class you're getting the loader from. For instance:
resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
In the hopes of providing additional information for those who don't pick this up as quickly as others, I'd like to provide my scenario as it has a slightly different setup. My project was setup with the following directory structure (using Eclipse):
Project/
src/ // application source code
org/
myproject/
MyClass.java
test/ // unit tests
res/ // resources
images/ // PNG images for icons
my-image.png
xml/ // XSD files for validating XML files with JAXB
my-schema.xsd
conf/ // default .conf file for Log4j
log4j.conf
lib/ // libraries added to build-path via project settings
I was having issues loading my resources from the res directory. I wanted all my resources separate from my source code (simply for managment/organization purposes). So, what I had to do was add the res directory to the build-path and then access the resource via:
static final ClassLoader loader = MyClass.class.getClassLoader();
// in some function
loader.getResource("images/my-image.png");
loader.getResource("xml/my-schema.xsd");
loader.getResource("conf/log4j.conf");
NOTE: The / is omitted from the beginning of the resource string because I am using ClassLoader.getResource(String) instead of Class.getResource(String).
When you use 'getResource' on a Class, a relative path is resolved based on the package the Class is in. When you use 'getResource' on a ClassLoader, a relative path is resolved based on the root folder.
If you use an absolute path, both 'getResource' methods will start at the root folder.
#GianCarlo:
You can try calling System property user.dir that will give you root of your java project and then do append this path to your relative path for example:
String root = System.getProperty("user.dir");
String filepath = "/path/to/yourfile.txt"; // in case of Windows: "\\path \\to\\yourfile.txt
String abspath = root+filepath;
// using above path read your file into byte []
File file = new File(abspath);
FileInputStream fis = new FileInputStream(file);
byte []filebytes = new byte[(int)file.length()];
fis.read(filebytes);
For those using eclipse + maven. Say you try to access the file images/pic.jpg in src/main/resources. Doing it this way :
ClassLoader loader = MyClass.class.getClassLoader();
File file = new File(loader.getResource("images/pic.jpg").getFile());
is perfectly correct, but may result in a null pointer exception. Seems like eclipse doesn't recognize the folders in the maven directory structure as source folders right away. By removing and the src/main/resources folder from the project's source folders list and putting it back (project>properties>java build path> source>remove/add Folder), I was able to solve this.
resourcesloader.class.getClass()
Can be broken down to:
Class<resourcesloader> clazz = resourceloader.class;
Class<Class> classClass = clazz.getClass();
Which means you're trying to load the resource using a bootstrap class.
Instead you probably want something like:
resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()
If only javac warned about calling static methods on non-static contexts...
Doe the following work?
resourcesloader.class.getClass().getResource("/package1/resources/repository/SSL-Key/cert.jks")
Is there a reason you can't specify the full path including the package?
Going with the two answers as mentioned above. The first one
resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()
Should be one and same thing?
In Order to obtain real path to the file you can try this:
URL fileUrl = Resourceloader.class.getResource("resources/repository/SSL-Key/cert.jks");
String pathToClass = fileUrl.getPath;
Resourceloader is classname here.
"resources/repository/SSL-Key/cert.jks" is relative path to the file. If you had your guiclass in ./package1/java with rest of folder structure remaining, you would take "../resources/repository/SSL-Key/cert.jks" as relative path because of rules defining relative path.
This way you can read your file with BufferedReader. DO NOT USE THE STRING to identify the path to the file, because if you have spaces or some characters from not english alphabet in your path, you will get problems and the file will not be found.
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(fileUrl.openStream()));
I made a small modification on #jonathan.cone's one liner ( by adding .getFile() ) to avoid null pointer exception, and setting the path to data directory. Here's what worked for me :
String realmID = new java.util.Scanner(new java.io.File(RandomDataGenerator.class.getClassLoader().getResource("data/aa-qa-id.csv").getFile().toString())).next();
Use this:
resourcesloader.class.getClassLoader().getResource("/path/to/file").**getPath();**
One of the stable way to work across all OS would be toget System.getProperty("user.dir")
String filePath = System.getProperty("user.dir") + "/path/to/file.extension";
Path path = Paths.get(filePath);
if (Files.exists(path)) {
return true;
}

Categories

Resources