how to add a file to Java EE projects? - java

I want to add a xml file to my Java ee project and use it in my code but when I address the file from src directory it does not understand my address and search for file in bin directory of tomcat.
My project is using wicket framwork and JavaEE.
does any one know how to address the file or where should I place the file to access is from project?

If your xml file is a resource that must be accessed server-side only, then the best choice is to place it in the WEB-INF directory inside your war, or in some subdirectory inside the WEB-INF. This way you ensure the resource will not be accessible by the web.
Then you can retrieve it using ServletContext.getResource, as pointed out by Peter D.
For example, in a servlet you can retrieve it this way (exception handling omitted):
String path = "/WEB-INF/my.xml";
URL url = getServletConfig().getServletContext().getResource(path);
InputStream in = url.openStream();
// read content from input stream...

Inside your servlet you can:
this.getServletContext().getResource( path );
public java.net.URL getResource(java.lang.String path)
throws java.net.MalformedURLException
Returns a URL to the resource that is mapped to a specified path. The path must begin with a "/" and is interpreted as relative to the current context root.
This method allows the servlet container to make a resource available to servlets from any source. Resources can be located on a local or remote file system, in a database, or in a .war file.
The servlet container must implement the URL handlers and URLConnection objects that are necessary to access the resource.
This method returns null if no resource is mapped to the pathname.
Some containers may allow writing to the URL returned by this method using the methods of the URL class.
The resource content is returned directly, so be aware that requesting a .jsp page returns the JSP source code. Use a RequestDispatcher instead to include results of an execution.
This method has a different purpose than java.lang.Class.getResource, which looks up resources based on a class loader. This method does not use class loaders.

Normally src is not used at runtime. I don't use tomcat, but in my environment I have build tasks that copy non-Java files from src to the bin directory.
You may find it necessary to open the file by using the classloader getResourceAsStream() so that you are searching the same directories as your classes come from.
This assumes that you want to deliver the XML in the application. Alternatively you may prefer to have it somewhere else. URI resource references may help

Why don't you place the XML file in your resources directory. You can access it from any class with:
MyClass.class.getClassLoader().getResourceAsStream(filename);

Related

Instancing a java.io.File to read a resource from classpath

Supposing that I've a project structure as follows:
+ src
---+ main
------+ java
------+ resources
How can I define a java.io.File instance that is able to read an xml from resources folder?
It depends on what your program's working directory is.
You can get your working directory at runtime via System.getProperty("user.dir");
Here's a link with more info
Once you've got that, create a relative filepath pointing to your resource folder.
For example, if your working directory is src, create a relative filepath like so:
new File(Paths.get("main","resources").toString());
There are weaknesses with this approach as the actual filepath you use may change when you deploy your application, but it should get you through some simple development.
No, use an InputStream, with the path starting under resources.
InputStream in = getClass().getResourceAsStrem("/.../...");
Or an URL
URL url = getClass().getResource("/.../...");
This way, if the application is packed in a jar (case sensitive names!) it works too. The URL in that case is:
"jar:file://... .jar!/.../..."
If you need the resource as file, for instance to write to, you will need to copy the resource as initial template to some directory outside the application, like System.getProperty("user.home").
Path temp = Files.createTempFile("pref", "suffix.dat");
Files.copy(getClass().getResourceAsStream(...), temp, StandardCopyOption.REPLACE_EXISTING);
File file = temp.toFile();
As #mjaggard commented, createTempFile creates an empty file,
so Files.copy will normally fail unless with option REPLACE_EXISTING.

How can I access a css file located in my "src/main/resources" folder from my JSF controller at runtime

I need to be able to access my web application's css files, that are stored under src/main/resources/styles, from the backend java controller. I want to use them for creating PDF output with iText.
In other words, I want to do something like this:
CssFile cssFile1 = XMLWorkerHelper.getCSS(new FileInputStream("src/main/resources/styles/my.css"));
However, I'm clearly not going about this correctly, as I am receiving Exceptions like this:
java.io.FileNotFoundException: styles\standard.css (The system cannot find the path specified)
How can a retrieve these files in the controller?
I tried this, but it did not work, same error:
String rcp = econtext.getRequestContextPath();
CssFile cssFile1 = XMLWorkerHelper.getCSS(new FileInputStream(rcp + "src/main/resources/styles/my.css"));
The FileInputStream operates on the local disk file system and all relative paths are relative to the current working directory, which is the local disk file system folder which is been opened at exactly the moment the JVM is started. This is definitely not the root of src/main/resources folder.
Given that the /src/main/resources is recognizable as a Maven folder structure for root of classpath resources, then you just need to obtain it as classpath resource by ClassLoader#getResourceAsStream() instead.
InputStream input = getClass().getResourceAsStream("/styles/standard.css");
// ...
Or if the class is possibly packaged in a JAR loaded by a different classloader.
InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream("styles/standard.css");
// ...
See also:
getResourceAsStream() vs FileInputStream
Thats because the JSF is a web app.
Now move the styles/my.css to WEB-INF/styles/my.css this ensures the files your accessing within the controller are part of the WebApp
and now you can access the resource using
XMLWorkerHelper.class.getResourceAsStream("styles/my.css")

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.

use a URL object to read a resource in web content

Im working in a web application using JSF2 and in one of my forms I create a PDF file that contains a image and a specific font. The ressorces are located in the WebContent directory.
My problem is when I want to create the pdf File I want to read the ressources and pass it in parameters to the method creating PDF FILE. I dont know how to use the URL object or any other way to do the task.
Thanks.
The ressorces are located in the WebContent directory.
WebContent directory is just for development environment under eclipse. When deployed the files there would go into the root of the web-app. So I take it that you want to access files in the root of your web-app.
You can use ServletContext.getResource(String path) with a path as "/myFileName" where the / signifies the web-app context root.
To get the reference to the ServletContext you may try this
The URL class has an openStream() method which gives you an InputStream of the resource's content:
URL resource = externalContext.getResource("/image.png");
InputStream input = resource.openStream();
// ...
You can also immediately get the resource as stream without getting it as URL first:
InputStream input = externalContext.getResourceAsStream("/image.png");
// ...
Having the InputStream, you can just read it into whatever target object which your PDF creator is expecting as input.

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