jboss: accessing file resource through java code? - java

I am reading properties file from java DAO implementation for loading properties object as in code given below
this.getErrorproperties().load(
new FileInputStream(new File("").getAbsolutePath()
+ "/conf/error/error.properties"));
While testing it works fine but when i try to deploy application on jboss 5 server. application deployment fails because absolute path is considered to be bin directory of jboss.
I want Jboss to find it relative to path of ear file. One more problem i face is my path relative to home path of project or ear file will be different for first and later.
Please suggest current approach programmers follow for such scenario. (I am a fresher)

You need to have your properties file in your classpath. If you have your properties file in the package foo.bar then you can load the properties file using,
this.getErrorproperties().load(getClass().getResourceAsStream("/foo/bar/error.properties"))
The leading slash in the path indicates an absolute path. Without the leading slash, the path is relative to the package of the class in.

Related

Java find the relative path of the configuration file in the war file

I am trying to access the config.properties file which was previously placed in the config folder. after some research, I moved it to the WEB-INF folder. but even after I moved it, it still return java.lang.NullPointerException whenenver I run my my program. code used to store some password information as below:
ClassLoader resource = ConnectionManager.class.getClass().getClassLoader();
URL path = ConnectionManager.class.getClass().getResource("/WEB-INF/config.properties");
props.load(new FileInputStream(path.getFile()));
String passwordds = props.getProperty("datasource.password");
these are the codes that I found and I try to use it but still I got the null exception.
I cannot use absolute path due to this project will be deploy to production server as in .war file. please advise what is the best way as I am still beginner.
You should check the war your build tool generated, and find where your config file really are.
For maven project, the default resource dir is /src/main/resources/
So /src/main/resources/config.properties will be put at /WEB-INF/classes/config.properties in a war.
You can use getClass().getResourceStream("/config.properties") (getResource sometimes not work will in j2ee environment) to get it.

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.

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.

Classpath Resource in Tomcat6 (Works in Jetty)

I'm having trouble with a legacy Web Application that I'm migrating to Maven3.
I need to obtain a file from the Classpath that in the directory structure is located in:
/src/main/resources/com/thinkglish/geoip/GeoIP.dat
When I create the .war file with the Maven build, I can confirm that this .dat file is located (as it should be) in:
WEB-INF/classes/com/thinkglish/geoip/GeoIP.dat
I'm trying two different approaches to get the resource from one of my classes, which implements javax.servlet.Filter:
ClassPathResource resource = new ClassPathResource("com/thinkglish/geoip/GeoIp.dat");
and
URL resource = getClass().getResource("/com/thinkglish/geoip/GeoIp.dat");
If I start the application using Maven's Jetty plugin, that works fine in both ways. However, when I deploy the application in a Tomcat and start the server, the resource cannot be located.
In the first case I get a java.io.FileNotFoundException: class path resource [com/thinkglish/geoip/GeoIp.dat] cannot be resolved to URL because it does not exist and in the second case the resource is null.
A curious thing about all this is that if I use one method or the other trying to obtain another resource from the Classpath (e.g. com/thinkglish/struts/i18n/MessageResources.properties or com/thinkglish/filter/LanguageFilter.class) it works without any problems.
Do you have any guess about this? Is it possible that the .dat extension has anything to do with this?
Edited - More data!
I added a new .properties mock file to the exact same directory in which the .dat file lives:
/src/main/resources/com/thinkglish/geoip/mock.properties
I tried to obtain it in Tomcat6 and it worked!
ClassPathResource resource = new ClassPathResource("com/thinkglish/geoip/mock.properties");
I'm starting to think that I need to do something else configuration-wise to make Tomcat6 accept the .dat file as a Classpath resource.
Thanks in advance!
I might be barking up completely the wrong tree here... but have you checked the capitalisation of GeoIP.dat / GeoIp.dat? Is Tomcat running on a case-sensitive OS?
Following should work:
String classpathLocation = "com/thinkglish/geoip/GeoIp.dat";
URL classpathResource = Thread.currentThread().getContextClassLoader().getResource(classpathLocation);
// Or:
InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream(classpathLocation);

Java file path in web project

I need to access the resource files in my web project from a class. The problem is that the paths of my development environment are different from the ones when the project is deployed.
For example, if I want to access some css files while developing I can do like this:
File file = new File("src/main/webapp/resources/styles/some.css/");
But this may not work once it's deployed because there's no src or main directories in the target folder. How could I access the files consistently?
You seem to be storing your CSS file in the classpath for some unobvious reason. The folder name src is typical as default name of Eclipse's project source folder. And that it apparently magically works as being a relative path in the File constructor (bad, bad), only confirms that you're running this in the IDE context.
This is indeed not portable.
You should not be using File's constructor. If the resource is in the classpath, you need to get it as resource from the classpath.
InputStream input = getClass().getResourceAsStream("/main/webapp/resources/styles/some.css");
// ...
Assuming that the current class is running in the same context, this will work regardless of the runtime environment.
See also:
getResourceAsStream() vs FileInputStream
Update: ah, the functional requirement is now more clear.
Actually I want to get lastModified from the file. Is it possible with InputStream? –
Use getResource() instead to obtain it as an URL. Then you can open the connection on it and request for the lastModified.
URL url = getClass().getResource("/main/webapp/resources/styles/some.css");
long lastModified = url.openConnection().getLastModified();
// ...
If what you're looking to do is open a file that's within the browser-visible part of the application, I'd suggest using ServletContext.getRealPath(...)
Thus:
File f = new File(this.getServletContext().getRealPath("relative/path/to/your/file"));
Note: if you're not within a servlet, you may have to jump through some additional hoops to get the ServletContext, but it should always be available to you in a web environment. This solution also allows you to put the .css file where the user's browser can see it, whereas putting it under /WEB-INF/ would hide the file from the user.
Put your external resources in a sub-directory of your project's WEB-INF folder. E.g., put your css resources in WEB-INF/styles and you should be able to access them as:
new File("styles/some.css");
Unless you're not using a standard WAR for deployment, in which case, you should explain your setup.
Typically resource files are placed in your war along with your class files. Thus they will be on the classpath and can be looked up via
getClass.getResource("/resources/styles/some.css")
or by opening a File as #ig0774 mentioned.
If the resource is in a directory that is not deployed in the WAR (say you need to change it without redeploying), then you can use a VM arg to define the path to your resource.
-Dresource.dir=/src/main/webapp/resources
and do a lookup via that variable to load it.
In Java web project, the standard directory like:
{WEB-ROOT} /
/WEB-INF/
/WEB-INF/lib/
/WEB-INF/classes
So, if you can get the class files path in file system dynamic,
you can get the resources file path.
you can get the path ( /WEB-INF/classes/ ) by:
this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath()
so, then the next ...

Categories

Resources