I am working on an hibernate project in which I need to read an xml. I placed those xmls in the same folder as the servlet from which I am trying to access those xmls. Now I don't know what is the correct path to access those xmls. Here is my project file structure. As can see, xmls are placed in com.strategycreator folder.
I can't place the xmls in a public directory as they need to be in a secure location.
If you need these files to be inaccessible to web page requests, you need to put them in your classpath and use them as resources.
The easiest way to find out the path to use for a classpath resource, is to generate the WAR, look inside the WAR in the appropriate JAR and see what path it ended up having and use that. If the file is "next to" a the class that needs to load it, you can use a relative path, otherwise you need to use the full "/com/strategycreator/groups.xml" path.
Related
Need help in understanding about classpath and file path. We have a third party jar where they need to refer commons-logging property file . The have specified in below way to refer it.
String fileLocation="commons-logging.properties";
If i place the file inside jar it works fine, which is not permitted. IS there any way to make the jar refer the file outside the jar. I cant make any code change. I tried to search for solution, but couldnt get what i want.
Everything depend on how this jar trying to read this file. If it tries to open it as a resource, via ClassLoader, then it should be inside your jar, but if like a external file, then no problem to put it outside and use absolute path into that file.
So just check this functionality and if you need to use file from outside - you have to change it and open this file via Path or File classes.
You need to put the properties file on the classpath of your Java application. You already did this by adding it to the root of the jar file.
One possibility is to add a specific folder, e.g. config, to your classpath. The properties file should then be placed in that folder.
Another option is to put the properties file into its own jar file and add this to your applications classpath.
But in the end I prefer the first option to add the file in a folder which is available in the classpath.
I was trying to load a file in a webapp, and I was getting a FileNotFound exception when I used FileInputStream. However, using the same path, I was able to load the file when I did getResourceAsStream().
What is the difference between the two methods, and why does one work while the other doesn't?
The java.io.File and consorts acts on the local disk file system. The root cause of your problem is that relative paths in java.io are dependent on the current working directory. I.e. the directory from which the JVM (in your case: the webserver's one) is started. This may for example be C:\Tomcat\bin or something entirely different, but thus not C:\Tomcat\webapps\contextname or whatever you'd expect it to be. In a normal Eclipse project, that would be C:\Eclipse\workspace\projectname. You can learn about the current working directory the following way:
System.out.println(new File(".").getAbsolutePath());
However, the working directory is in no way programmatically controllable. You should really prefer using absolute paths in the File API instead of relative paths. E.g. C:\full\path\to\file.ext.
You don't want to hardcode or guess the absolute path in Java (web)applications. That's only portability trouble (i.e. it runs in system X, but not in system Y). The normal practice is to place those kind of resources in the classpath, or to add its full path to the classpath (in an IDE like Eclipse that's the src folder and the "build path" respectively). This way you can grab them with help of the ClassLoader by ClassLoader#getResource() or ClassLoader#getResourceAsStream(). It is able to locate files relative to the "root" of the classpath, as you by coincidence figured out. In webapplications (or any other application which uses multiple classloaders) it's recommend to use the ClassLoader as returned by Thread.currentThread().getContextClassLoader() for this so you can look "outside" the webapp context as well.
Another alternative in webapps is the ServletContext#getResource() and its counterpart ServletContext#getResourceAsStream(). It is able to access files located in the public web folder of the webapp project, including the /WEB-INF folder. The ServletContext is available in servlets by the inherited getServletContext() method, you can call it as-is.
See also:
Where to place and how to read configuration resource files in servlet based application?
What does servletcontext.getRealPath("/") mean and when should I use it
Recommended way to save uploaded files in a servlet application
How to save generated file temporarily in servlet based web application
getResourceAsStream is the right way to do it for web apps (as you already learned).
The reason is that reading from the file system cannot work if you package your web app in a WAR. This is the proper way to package a web app. It's portable that way, because you aren't dependent on an absolute file path or the location where your app server is installed.
FileInputStream will load a the file path you pass to the constructor as relative from the working directory of the Java process. Usually in a web container, this is something like the bin folder.
getResourceAsStream() will load a file path relative from your application's classpath.
The FileInputStream class works directly with the underlying file system. If the file in question is not physically present there, it will fail to open it. The getResourceAsStream() method works differently. It tries to locate and load the resource using the ClassLoader of the class it is called on. This enables it to find, for example, resources embedded into jar files.
classname.getResourceAsStream() loads a file via the classloader of classname. If the class came from a jar file, that is where the resource will be loaded from.
FileInputStream is used to read a file from the filesystem.
I am here by separating both the usages by marking them as File Read(java.io) and Resource Read(ClassLoader.getResourceAsStream()).
File Read -
1. Works on local file system.
2. Tries to locate the file requested from current JVM launched directory as root
3. Ideally good when using files for processing in a pre-determined location like,/dev/files or C:\Data.
Resource Read -
1. Works on class path
2. Tries to locate the file/resource in current or parent classloader classpath.
3. Ideally good when trying to load files from packaged files like war or jar.
I have a maven project with typical project structure. At the base of the project, I have a directory names res that has some resources (> 500 MB).
I am trying to use
this.class().getClassLoader().getResourceAsStream("res/xxx")
this code fragment to read from that folder, but it returns a null resource stream.
I have a few workarounds below, but none of these are acceptable due to reasons explained below.
I can move the folder to {base}/target/classes, and it will be read, but it will also get cleaned when I do a mvn clean. Hence, this approach doesn't work. For some reason, specifying the path as ../../res/xxx also doesn't work.
I can move the folder to {base}/src/resources, but then it will get copied to target/classes and the jar. Hence this is also not acceptable.
Though I am open to trying some other java APIs, I may have to use the class loader mechanism only as there is some external library component that is also trying to access the res folder using the similar approach.
Is there some way I can read the res folder from projects base directory? Is there some setting in pom.xml file that can help me with that?
Use this.class().getClassLoader().getResourceAsStream("/res/xxx") and then you will be reading from the root of the classpath irrespective of the actual file/folder location in windows or Linux. This is actually one of the safest ways to read files especially when you do not know how your application will eventually be deployed.
It means though that your classpath must include the parent of res and that res/ must be copied over when you deploy your app
Otherwise, if you want to use relative paths, try this snippet (taken from this SO answer):
String filePath = new File("").getAbsolutePath();
filePath.concat("path to the property file");
If you use this.class().getClassLoader().getResourceAsStream("/res/xxx"), it is going to try to load resources from the classpath. If that's not want you want to do, you're going to need to specify an absolute path.
Resource on Classpath
If you don't want the resource built into your JAR, I'd suggest having a different maven project with the file in it, under the src/main/resources directory. This will create a jar file with the file in it, which will be ~500MB.
After this, you can include a dependency on this project in your project containing your application code. This will then be able to reference it from the jar file using getResourceAsStream(...).
If you don't want this large jar file to ship with your application, make sure you mark the dependency with <scope>provided</scope>.
File from Absolute Path
You will need to take the file location as a parameter in your main method, and then use new File("C:\\path\\to\\your\\file.txt") and then use a FileReader to read it in.
I am using jquery i18n plugin to internationalize the messages placed in jquery/js.
i have below project structure.
I have some.js file in js folder and inside some.js file i have to refer a properties file which is located in src/main/resources folder. can i do as below?
jQuery.i18n.properties({
name:'Messages',
path:'resources/', //as i have properties file in src/main/resources am referring.
mode:'both'
});
Maybe. You need to understand that Java source paths and Web paths are unrelated unless you write some code to connect the two.
My suggestion for requirements like this is to put all resources into a certain package (which doesn't contain anything else, especially no classes in src/main/java).
Also note that src/main/resources will be gone when you deploy. After deployment, all resources will be available from the Java Classpath and relative to the classpath root. So if the source path is src/main/resources/foo/, it will be foo/ at runtime.
If you use Spring on the server side, you can use mvc:resources.
This question has a solution without Spring: Servlet for serving static content
So this might be a stupid question but...
I want to package a specific WSDL file in with an EJB project within eclipse. What would be the best way to refer to this file in my code?
I would like to use a relative path but the current directory starts off in the /bin directory of my JBOSS installation. It seems like there should be a way to refer to the file in relation to the project file structure.
Any ideas?
getClass().getResource(String path) uses a relative path to locate a classpath resource. It returns a java.net.URL. Alternatively, you can use getResourceAsStream(..) to obtain the InputStream to the resource.