How to read an internal file in a web project - java

All, Forgive me I am still learning the Java development right row.
Say we have the structure of web project like below.
The src and config is under the Java Resources folder of web project.
src
...
|- a.b.c.package
|-test.java
...
config
|-1.xml
|-2.xml
...
configfolder
|-1.properties
|-2.properties
testfolder
|-test.properties
I want to know if I use the dom4j. How to read the xml file(1.xml) within the test.java. Thanks.
My Experiment
In the test.java. I found I can succeed to use the class.getClassLoader().getResourceAsStream("test.properties") to load test.properties in any folders or sub folder of src.
Does it mean getResourceAsStream can search the specified file in any of the folders of project recursively? I just can't understand it how it works. Thanks.

getResourceAsStream() method searches for resources with classpath as root. I suppose in your case 'testfolder' is source folder. I you would have your 1.properties in 'testfolder/mypath/1.properties' then you need to specify getResourceAsStream("mypath/1.properties")

Related

Using relative path in a maven project

I have a maven project with these standard directory structures:
src/main/java
src/main/java/pdf/Pdf.java
src/test/resources
src/test/resources/files/x.pdf
In my Pdf.java,
File file = new File("../../../test/resources/files/x.pdf");
Why does it report "No such file or dirctory"? The relative path should work. Right?
Relative paths work relative to the current working directory. Maven does not set it, so it is inherited from whatever value it had in the Java process your code is executing in.
The only reliable way is to figure it out in your own code. Depending on how you do things, there are several ways to do so. See How to get the real path of Java application at runtime? for suggestions. You are most likely looking at this.getClass().getProtectionDomain().getCodeSource().getLocation() and then you know where the class file is and can navigate relative to that.
Why does it report "No such file or dirctory"? The relative path should work. Right?
wrong.
Your classes are compiled to $PROJECT_ROOT/target/classes
and your resources are copied to the same folder keeping their relative paths below src/main/resources.
The file will be located relative to the classpath of which the root is $PROJECT_ROOT/target/classes. Therefore you have to write in your Pdf.java:
File file = new File("/files/x.pdf");
Your relative path will be evaluated from the projects current working directory which is $PROJECT_ROOT (AFAIR).
But it does not matter because you want that to work in your final application and not only in your build environment. Therefore you should access the file with getClass().getResource("/path/to/file/within/classpath") which searches the file in the class path of which the root is $PROJECT_ROOT/target/classes.
No the way you are referencing the files is according to your file system. Java knows about the classpath not the file system if you want to reference something like that you have to use the fully qualified name of the file.
Also I do not know if File constructor works with the classpath since it's an abstraction to manage the file system it will depend where the application is run from. Say it is run from the target directory at the same level as source in that case you have to go one directory up and then on src then test the resources the files and finally in x.pdf.
Since you are using a resources folder I think you want the file to be on the classpath and then you can load a resource with:
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("<path in classpath>");
Then you can create a FileInputStream or something to wrap around the file. Otherwise use the fully qualiefied name and put it somewere like /home/{user}/files/x.pdf.

Why does getResource return null

I'm trying to access a file in my project. But getResource method returns null.
This is how my project looks like:
Thread.currentThread().getContextClassLoader().getResource("assets/xxx.png"); //returns null
And how project folder in eclipse workspace looks like:
Why? I want to access files in my assets folder?
Edit
I created a jar file and this is content of the jar:
Solved
First of all, I've a lot of image files so I want to organize all them in a folder. I put the assets folder in src directory and finally I was able to access the files.
this.getClass().getClassLoader().getResource("assets/xxx.png");
There are lot of ways to add a resource to the jar file, you can put it in src, add as a resource if you use maven, ant etc... If you able to bundle whole directory then you should be able to use your original piece of code.
With the current structure you can use following piece of code.
Thread.currentThread().getContextClassLoader().getResource("/xxx.png").
Try using / prefixing.
Thread.currentThread().getContextClassLoader().getResourceAsStream("/xxx.png")
For someone struggling as me. For Maven just run mvn clean install.
After that Thread.currentThread().getContextClassLoader().getResource() should work.
Is there a reason you're using the the class loader of the current class? Something like this.getClass().getClassLoader().getResource("/xxx.png") should be more reliable.
Use the following code, it should work.
YOUR_CLASS_HERE.class.getClass().getResource( "/xxx.png" );
e.g.
Signin.class.getClass().getResource( "/xxx.png" );
Either Approach will work. its just Filepath issue.
Your Jar Structure shows no "asset" Folder
xxx.png file is directly in Jar File.
Try to remove "assets" from below line of code.
Thread.currentThread().getContextClassLoader().getResource("assets/xxx.png"); //returns null
Also, if you want to use "assets" folder in ur classpath, please ensure that your jar contains "assets" folder.

Adding resources in IntelliJ for Maven project

I have a project structure like this:
src
|-main
|-java
|-com.abc.xyz
|-Login.java
I have to add a resource file to this and read the resource with
InputStream is = getClass().getResourceAsStream("launchers.properties");
This is giving null.
In Intellij I am not able to add a new package under src/main for resources folder so
that the project structure looks like this. How can I load the launchers.properties resource file into the project?
src
|-main
|-java
|-com.abc.xyz
|-Login.java
|-resources
|-com.abc.xyz
|-Login
|-launcher.properties
I tried the solution suggested by #maba but still not working
The launcher.properties should not be under a folder called Login. It should be placed directly in the src/main/resources/com/abc/xyz folder.
It is really as simple as I said but if the resources folder is not marked as a sources folder then this may be the problem.
This is the initial class and setup:
Now create the resources folder:
This newly created folder should be automatically marked as a sources folder and if it is blue color marked then it is. Otherwise you'll have to mark it manually:
Now you'll be able to add packages to it:
And now you can add the file to it:
And rerunning the application will not give you any null value back:
And the package view will surely show the launchers.properties file as well:
As #maba pointed out, your properties file should be in the same package as your class for your code to work.
So, you should have two files:
src/main/java/com/abc/xyz/Login.java
src/main/resources/com/abc/xyz/launcher.properties
If IntelliJ is showing the resource or not is beside the question. What you need to do is check if the results are included in your target artefact.
Do a build all in IntelliJ, open up the resulting WAR/JAR/EAR with your favorite ZIP viewer and browse into the "com/abc/xyz" folder. You should see both files there.
If they are, you are doing something wrong in your code. Check for typos, especially dots and spaces at the end or beginning (e.g. "launcher.properties[space]"), copy/paste the file name to make sure
If they are not there, your IntelliJ setup is wrong. Resources do not get included in your target build. Check online for tutorials how to do this with IntelliJ idea.
Follow these two steps
1) Create a directory
Right Click ==> New ==> Directory
2) Mark Directory as Resources Root
Right Click on the Direcory ==> Mark Directory as ==> Resources Root
No..... the structure is wrong.... you should not create the same package under resources, that is ugly and not proper: resources is for resources, and should not contain source packages.
When using ClassLoader.getResources(asStream)(path) method, the method just starts searching from the root of the classpath and the path name cannot start with / as leading characters. What you have to do, is to mark the resources as resources folder in IntelliJ. Then the files under resources will be listed under classpath and you can easily use them like you have done.
(I see in previous answers this option is not available yet in 2013, you only have mark as source folder, just like in Eclipse till now we have "add source folder", but now in 2018 it is available in Intellij: you can mark a folder as source, resources, test source, test resources, and all of them will be add to the root of classpath. )
I had the same problem and noticed that the resource file, for example: my.properties is not copied to the corresponding module folder in the target directory after build occurres. In order to solve that, I had to instruct Maven to copy the resources from the module directory to the target directory during the build process. In the .pom file I added <resource> element like that:
<project ...>
...
<build>
...
<resource>
<directory>src/main/java/com/abc/xyz</directory>
<targetPath>com/abc/xyz</targetPath>
</resource>
</build>
...
</project>
Note that the <directory> element is relative to the location of the .pom file , i.e. the root directory of the project, and the <targetPath> element indicates the package name separated by slashes.
from menu Run/edit configuration
in VM option you should add
-Dspring.config.location=path-file
I've tried it in IntelliJ, and it works!
Only solution worked for me:
File -> Project Structure -> Modules -> Dependencies Tab -> + Sign -> JARs or directories -> select resources directory -> Classes

The correct place to put the config file in Eclipse

I have created a Dynamic Web Project in Eclipse and I have a following Java statement that needs to read a config file:
Document doc= new SAXReader().read(new File(ConstantsUtil.realPath+"appContext.xml"));
Basically, ConstantsUtil.realPath will return an empty string.
I tried putting "appContext.xml" under both "src" folder and under "WEB-INF" folder. However, I will always get the following error:
org.dom4j.DocumentException: appContext.xml (The system cannot find the file specified)
I am really confused: in Eclipse, where is the correct place to put my config xml file?
Thanks in advance.
Your concrete problem is caused by using new File() with a relative path in an environment where you have totally no control over the current working directory of the local disk file system. So, forget it. You need to obtain it by alternate means:
Straight from the classpath (the src folder, there where your Java classes also are) using ClassLoader#getResourceAsStream():
Document doc= new SAXReader().read(Thread.currentThread().getContextClassLoader().getResourceAsStream("appContext.xml"));
Straight from the public webcontent (the WebContent folder, there where /WEB-INF folder resides) using ServletContext#getResourceAsStream():
Document doc= new SAXReader().read(servletContext.getResourceAsStream("/WEB-INF/appContext.xml"));
The ServletContext is in servlets available by the inherited getServletContext() method.
See also:
Where to place and how to read configuration resource files in servlet based application?
getResourceAsStream() vs FileInputStream
What does servletcontext.getRealPath("/") mean and when should I use it
You can embed your config files into your jar/war files
InputStream is = MyClass.class.getResourceAsStream("/com/site/config/config.xml");
You could either create a folder with all your configurations and reference it on the class path of the web application when published on the server, or place them under the WebContent folder, in both cases you need to reference them relatively.
There can be multiple places where you could place your property files. The selection of the location depends on the architeture of the project.
Commonly used location are:
/YourProjectRootFolder/src/main/webapp/WEB-INF/properties/XYZ.properties
: in the same folder where you have your java class files.
YourProjectConfFolderNAme/src/main/resources/XYZ.properties: here all the property files are kept in a seperate location than your project class files.
Both are the same as you need to move all your property files to you server's conf folder.

Getting XML file not in the same root as the source file in Java

I have a problem where I can't seem to link to a xml file, see the layout below:
Folder Name
-Folder
-Folder
-SourceFiles
-packagename
-all my java files
-myXml.xml
Build is where all the class files etc is stored.
src is where the projectFolder is, and within it the java files
Code I am using to link XML File for Synth: SynthDialog.class.getResourceAsStream("synthtest/synthDemo.xml")
Now I want to link to the myXML.xml file in the top-level folder. It would be the PHP Equivelent of ../../Folder/
Thanks
You appear to be attempting to access the file using getResourceAsStream with a relative name. If that is the case, then the resource should be in located in a JAR file or directory on the classpath, and the location will be resolved relative to the FQN of the class.
I can't tell where the ".class" files are located in the tree, or how your classpath is set up, so I can't be more specific.
UPDATED
If you are executing out of that build directory, then your build process needs to copy the XML file to the appropriate place in the build tree so that the class-relative path ends up referring to the file. (Or use a path that starts with "/" so that you don't depend on the classes FQN at all.)
In the long term, you will probably execute out of a JAR file, and the data file will need to be inside it.
Use "getSystemResourceAsStream" instead of "getResourceAsStream" to access files outside of your codebase.

Categories

Resources