Deployed WAR can't access a file - java

I have a spring application, and i'm trying to access a json file with the following code :
try (FileReader reader = new FileReader("parameters.json")) {
Object obj = jsonParser.parse(reader);
parameterList = (JSONArray) obj;
}
I have put the parameter.json file in the project folder and I'm accesing the file data from an angular app through a rest api, and that works fine when I run the application on local machine, but when I deploy the war file on tomcat, my application can't load the file, should I put parameter.json file somewhere else on tomcat or what is the best solution for it.

Your question states you are attempting to access a file called parameter.json, while your code excerpt shows parameters.json. Perhaps that discrepancy indicates a typo in your source code?
If not, there are various ways to access a file from the classpath in Spring, with the first step for each being to ensure the file is in the project's src/main/resources directory.
You can then use one of the Spring utility classes ClassPathResource, ResourceLoader or ResourceUtils to get to the file. The easiest approach, though, may be to put your properties in a .properties file (default file name application.properties) and access the values using Spring's #Value annotation:
#Value("${some.value.in.the.file}")
private String myValue;
You can use other file names as well by utilizing #PropertySource:
#Configuration
#PropertySource(value = {"classpath:application.properties",
"classpath:other.properties"})
public class MyClass {
#Value("${some.value.in.the.file}")
private String myValue;
...
}

Make sure your parameters.josn filename is exactly same in the code.
Move you parameters.json file in the resources folder and then use the classpath with the filename.
try (FileReader reader = new FileReader("classpath:parameters.json")) {
Object obj = jsonParser.parse(reader);
parameterList = (JSONArray) obj;
}

Try to put the file under resources folder in your spring project. You should be able to access the file from that location.

FileReader is looking for a full-fledged file system like the one on your computer, but when your WAR is deployed, there just isn't one, so you have to use a different approach. You can grab your file directly from your src/main/resources folder like this
InputStream inputStream = getClass().getResourceAsStream("/parameters.json");

Related

Reading files from relative paths on Tomcat

I need to run a web-app on Tomcat, but it cannot read the txt files(from a relative paths as below) on Tomcat. However, it does work if I use a full path.
So I am wondering where can I put these txt files so that when Tomcat started, the app can successfully read the txt files from a relative path.
Currently, the project structure is as follows, the txt files is located on the same directory as src file in Project Explorer in Eclipse.
Project_Name
src
java files
EDGES.txt
NODES.txt
The code is as follows, I am appreciated if someone can give me an answer in details, since I am quite new to Java.
The code is as follows:
public class RouteingDao {
NodeJSONReader nodeInput = new NodeJSONReader("NODES.txt");
EdgeJSONReader edgeInput = new EdgeJSONReader("EDGES.txt");
...
}
The NodeJSONReader/EdgeJSONReader class is as follows:
public class EdgeJSONReader {
private EdgeEntity[] edgeEntity;
// constructor
public EdgeJSONReader(String JSON_FILE) {
edgeEntity = readEntityFromFile(JSON_FILE);
}
// load the JSON data from local file
public EdgeEntity[] readEntityFromFile(String JSON_FILE) {
try {
Reader reader = new FileReader(JSON_FILE);
Gson gson = new Gson();
edgeEntity = gson.fromJson(reader, EdgeEntity[].class);
}
...
}
}
If you are using a servlet, then access the servlet context and the getRealPath method.
this.getServletContext().getRealPath("WEB-INF/nodes.txt")
The relative path sent to getRealPath will be expanded to the location of the files for your web app. You can add any path you like, even to a hidden file in WEB-INF.
From a JSP you can use
${pageContext.servletContext.getRealPath("WEB-INF/nodes.txt")}
Be careful, this will be in the build directory, so any changes to nodes.txt will not be saved to the original file.

load a folder from a jar

I am trying to access a directory inside my jar file. I want to go through every of the files inside the directory itself. I tried using the following:
File[] files = new File("ressources").listFiles();
for (File file : files) {
XMLParser parser = new XMLParser(file.getAbsolutePath());
// some work
}
If I test this, it works well. But once I put the contents into the jar, it doesn't because of several reasons. If I use this code, the URL always points outside the jar.
structure of my project :
src
controllers
models
class that containt traitement
views
ressources
See this:
How do I list the files inside a JAR file?
Basically, you just use a ZipInputStream to find a list of files (a .jar is the same as a .zip)
Once you know the names of the files, you can use getClass().getResource(String path) to get the URL to the file.
I presume this jar is on your classpath.
You can list all the files in a directory using the ClassLoader.
First you can get a list of the file names then you can get URLs from the ClassLoader for individual files:
public static void main(String[] args) throws Exception {
final String base = "/path/to/folder/inside/jar";
final List<URL> urls = new LinkedList<>();
try (final Scanner s = new Scanner(MyClass.class.getResourceAsStream(base))) {
while (s.hasNext()) {
urls.add(MyClass.class.getResource(base + "/" + s.nextLine()));
}
}
System.out.println(urls);
}
You can do whatever you want with the URL - either read and InputStream into memory or copy the InputStream into a File on your hard disc.
Note that this definitely works with the URLClassLoader which is the default, if you are using an applet or a custom ClassLoader then this approach may not work.
NB:
You have a typo - its resources not ressources.
You should use reverse domain name notation for your project, this is the convention.

How can I get real path for file in my WebContent folder?

I need to get real path for file in my WebContent directory, so that framework that I use can access that file. It only takes String file as attribute, so I need to get the real path to this file in WebContent directory.
I use Spring Framework, so solution should be possible to make in Spring.
If you need this in a servlet then use getServletContext().getRealPath("/filepathInContext")!
getServletContext().getRealPath("") - This way will not work if content is being made available from a .war archive. getServletContext() will be null.
In this case we can use another way to get real path. This is example of getting a path to a properties file C:/Program Files/Tomcat 6/webapps/myapp/WEB-INF/classes/somefile.properties:
// URL returned "/C:/Program%20Files/Tomcat%206.0/webapps/myapp/WEB-INF/classes/"
URL r = this.getClass().getResource("/");
// path decoded "/C:/Program Files/Tomcat 6.0/webapps/myapp/WEB-INF/classes/"
String decoded = URLDecoder.decode(r.getFile(), "UTF-8");
if (decoded.startsWith("/")) {
// path "C:/Program Files/Tomcat 6.0/webapps/myapp/WEB-INF/classes/"
decoded = decoded.replaceFirst("/", "");
}
File f = new File(decoded, "somefile.properties");
you must tell java to change the path from your pc into your java project so
if you use spring use :
#Autowired
ServletContext c;
String UPLOAD_FOLDEdR=c.getRealPath("/images");
but if you use servlets just use
String UPLOAD_FOLDEdR = ServletContext.getRealPath("/images");
so the path will be /webapp/images/ :)
In situations like these I tend to extract the content I need as a resource (MyClass.getClass().getResourceAsStream()), write it as a file to a temporary location and use this file for the other call.
This way I don't have to bother with content that is only contained in jars or is located somewhere depending on the web container I'm currently using.
Include the request as a parameter. Spring will then pass the request object when it calls the mapped method
#RequestMapping .....
public String myMethod(HttpServletRequest request) {
String realPath = request.getRealPath("/somefile.txt");
...
You could use the Spring Resource interface (and especially the ServletContextResource): http://static.springsource.org/spring/docs/current/javadoc-api/org/springframework/core/io/Resource.html
This approach uses the resource loader to get the absolute path to a file in your app, and then goes up a few folders to the app's root folder. No servlet context required! This should work if you have a "web.xml" in your WEB-INF folder. Note that you may want to consider using this solely for development, as this type of configuration is usually best stored externally from the app.
public String getAppPath()
{
java.net.URL r = this.getClass().getClassLoader().getResource("web.xml");
String filePath = r.getFile();
String result = new File(new File(new File(filePath).getParent()).getParent()).getParent();
if (! filePath.contains("WEB-INF"))
{
// Assume we need to add the "WebContent" folder if using Jetty.
result = FilenameUtils.concat(result, "WebContent");
}
return result;
}
my solve for: ..../webapps/mydir/ (..../webapps/ROOT/../mydir/)
String dir = request.getSession().getServletContext().getRealPath("/")+"/../mydir";
Files.createDirectories(Paths.get(dir));
try to use this when you want to use arff.txt in your development and production level too
String path=getServletContext().getRealPath("/WEB-INF/files/arff.txt");

How I can specify directories in war file?

I am new to servlet . I use the following code in servlet.then deployed to Jboss 4.1 . backup_database_configuration_location is location of properties file.But it can't be find. how I can specify directories in war file ?
Thanks all in advance
try {
backupDatabaseConfiguration = new Properties();
FileInputStream backupDatabaseConfigurationfile = new FileInputStream(backup_database_configuration_location));
backupDatabaseConfiguration.load(backupDatabaseConfigurationfile);
backupDatabaseConfigurationfile.close();
} catch (Exception e) {
log.error("Exception while loading backup databse configuration ", e);
throw new ServletException(e);
}
If it is placed in the webcontent, then use ServletContext#getResourceAsStream():
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/file.properties"));
The getServletContext() method is inherited from HttpServlet. Just call it as-is inside servlet.
If it is placed in the classpath, then use ClassLoader#getResourceAsStream():
InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream("file.properties");
The difference with Class#getResourceAsStream() is that you're not dependent on the classloader which loaded the class (which might be a different one than the thread is using, if the class is actually for example an utility class packaged in a JAR and the particular classloader might not have access to certain classpath paths).
Where is your properties file located? Is it directly somewhere in your hard drive, or packaged in a JAR file?
You can try to retrieve the file using the getResourceAsStream() method:
configuration = new Properties();
configuration.load(MyClass.class.getResourceAsStream(backup_database_configuration_location));
(or course, replace MyClass by your current class name)

How to load properties file in Google App Engine?

So I'm trying to add some ability to my project to allow user-defined properties in my deployment artifact - a simple key:value .properties file. I place the service.properties file in
war/WEB-INF/my-service.properties
And in my ServiceImpl.java constructor I have the following:
String propertiesFileName = "my-service.properties";
URL propertyURL = ClassLoader.getSystemResource(propertiesFileName);
URL propertyURL2 = this.getClass().getClassLoader().getResource(propertiesFileName);
URL propertyURL3 = this.getClass().getClassLoader().getResource( "WEB-INF/" + propertiesFileName);
URL propertyURL6 = this.getClass().getClassLoader().getResource(
"E:/Projects/eclipse-workspace/projectName/war/WEB-INF/" + propertiesFileName);
All instances of Property URL are null. I know I'm missing something absolutely obvious, but I need a second pair of eyes. Regards.
EDIT:
Ah, it seems I was confused as the default GAE project creates a logging.properties file in /war. From the Google App Engine documentation:
The App Engine Java SDK includes a template logging.properties file, in the appengine-java-sdk/config/user/ directory. To use it, copy the file to your WEB-INF/classes directory (or elsewhere in the WAR), then the system property java.util.logging.config.file to "WEB-INF/classes/logging.properties" (or whichever path you choose, relative to the application root). You can set system properties in the appengine-web.xml file, as follows:
Try putting the service.properties in WEB-INF/classes. Then it should be accessible just with :
this.getClass().getClassLoader().getResourceAsStream("/filename.properties");
As Mike mentioned in his comment to jsights answer, it worked for me if I used
this.getClass().getClassLoader().getResourceAsStream("filename.properties");
(removed the first slash) after placing the file in WEB-INF/classes.
I think what you will need is something like this:
String filePath = servletContext.getRealPath("/WEB-INF/views/") + "/" + mav.getViewName() + ".vm";
FileInputStream in = new FileInputStream(filePath);
I get the servletContext from spring: #Autowire ServletContext.

Categories

Resources