I have a properties file called app.properties that is correctly put in src/main/resources/app.properties.
In the WAR file it is correctly located in \WEB-INF\classes.
In Standalone mode in my local environment (windows) and standalone mode on a linux test server, the WAR file starts up correctly reading my properties file.
In Jboss Domain mode on another linux server, using the exact same WAR file, I get error file not found app.properties. It is indeed there.
Other than domain mode being the difference between the two servers, the first test server jboss is installed under root and running as root. The other server is running as a user that has read and execute access.
I've thoroughly debugged the code with print statements and im 99% sure it is not a code issue, any ideas what in jboss domain mode may be causing the problem of not being able to read the properties file on the classpath?
Thanks in advance.
Relevant parts of code
MutablePropertySources sources = new MutablePropertySources();
sources.addLast(getEncryptablePropertiesSource(new ClassPathResource("app.properties")));
partial method
private EncryptablePropertiesPropertySource getEncryptablePropertiesSource(Resource propsResource) throws IOException{
//don't use file system resource because property files may be in a jar
System.out.println(">>>> in getEncryptablePropertiesSource filename is :");
System.out.println(propsResource.getFilename());
System.out.print(">>>> URL is: ");
System.out.println(propsResource.getURL());
The last System out print statement throws the error in the 2nd test environment, does not cause problems in any other environment.
If your ClassPathResource is the class from Spring:
public class ClassPathResource extends AbstractFileResolvingResource
Resource implementation for class path resources. Uses either a given
ClassLoader or a given Class for loading resources.
Supports resolution as java.io.File if the class path resource resides
in the file system, but not for resources in a JAR. Always supports
resolution as URL.
Therefore I don't think you can use it in your case.
Have you tried using one of the following methods?
ClassLoader.getResource(String name)
ClassLoader.getResourceAsStream(String name)
Related
I have an application running fine on localhost but I am having issues when It is deployed on tomcat
The code I am using to read the file is :
File jasperFile = new File(getClass().getClassLoader().getResource("reports/Header.jasper").getFile());
I get this error in catalina :
net.sf.jasperreports.engine.JRException: java.io.FileNotFoundException: file:/usr/local/apache-tomcat9/webapps/com.peek.facture.server/WEB-INF/lib/facture.server-1.0.0-SNAPSHOT.jar!/reports/Header.jasper
What triggers me is the "!" at the end of the jar name, where does it come from?
Also I have tried to download the jar, extract it, and my Header.jasper is correctly in the resources/reports/ folder
When you run on your local a stand-alone physical file Header.jasper exists (you can physically see it when you browse the reports directory).
However when you deploy to a tomcat server, that stand-alone physical file no longer exists. Instead, if you set-up your build correctly, when you open up your jar (facture.server-1.0.0-SNAPSHOT.jar), there should be a directory called reports in it with the file Header.jasper within that directory.
So when your try get a resource via getClass().getClassLoader().getResource(...).getFile() you are actually trying to access a stand-alone physical file. Instead you need to get the resource as an InputStream and then work with if from there...
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("reports/Header.jasper");
When working with resources, it's always better to rather access them this way. Especially if you are planning to deploy anywhere with a single artifact, because your resources should be packaged in with your artifact.
I have a .properties file that is under a source folder I made called res (using Eclipse Mars 2). I have two other folders in there called messages and schemas.
I need help in giving a filepath so it works locally and on a server (e.g. JBoss) after making the project into a .war file. This is my .properties file:
# Credentials
user=flow
password=flow
# Path to schema for validation
schemaPath=schemas/Schema1.xsd
# Path to where you want to keep incoming and outgoing messages
messagePath=messages/
The above properties file will only work if I provide the full path to the two different *Path properties (above is not full path). However, I can't do that because it needs to work on the application server and on different operating systems.
In my code, I save the filepaths to Strings and use those Strings to specify where to write or read. How can I make it so it works after deploying to the server using a .war file?
I am using a Dynamic Web Project in Eclipse Mars 2.
EDIT: Since the properties is user configurable, they might give a full path. It should work whether the path is short as shown or the full path.
You have to make sure that the properties file is part of the classpath, that is usually including it in classes/ directory.
Mark the folder with properties file as Source Folder in your eclipse. If it is in a package, then use that package name in your path while loading the file.
For example, if the file is in config/data.properties, then load the file by .getResource("config/data.properties");
I'm running a Spring Boot application in Heroku, using Maven to manage the build lifecycle.
During the initialisation phase of my application, I want to read a file packaged into my JAR file.
To manage to get the content of the file I'm using the Spring utility class ResourceUtils, and I'm expressing the path of the file using the special prefix classpath:.
The code I'm using looks like this:
String pathToMyFile = "classpath:com/myapp/myFile.test"
List<String> fileLines = Files.readLines(ResourceUtils.getFile(pathToMyFile), IOConstants.DEFAULT_CHARSET_TYPE);
This code works as expected when I execute the application in my local machine.
But when I push my application to Heroku I'm getting the following error:
Caused by: java.io.FileNotFoundException: class path resource [com/myapp/myFile.test]
cannot be resolved to absolute file path because it does not reside in the
file system: jar:file:/app/target/myapp.jar!/com/myapp/myFile.test
I've run a heroku run bash and I've checked that the file is just where it should be (inside the jar).
Moreover, according to the error trace, Spring locates the file, because it transform the path from classpath:com/myapp/myFile.test to jar:file:/app/target/myapp.jar!/com/myapp/myFile.test
I suspect that when you are running locally, it is picking up the file on the classpath from an exploded JAR file (i.e. as a regular file on the filesystem).
On Heroku, it is in the JAR file, which means it is not a regular file, and must be read as an input stream, which might look like this:
ClassLoader cl = this.getClass().getClassLoader();
InputStream inputStream = cl.getResourceAsStream(pathToMyFile);
Then you might use a BufferedReader to read the lines. But maybe ResourceUtils has a better method.
You can probably reproduce the problem locally by running the same command that's in your Profile.
I'm having a trouble accessing some files in universal way across app run modes.
I have folder "resources" in app root folder, which contains some crucial files.
When I run in dev mode, I access them in simple manner, like:
Play.application().path().getAbsolutePath()+"/resources/file.file";
But after I package my app via dist commmand (I've modified build.sbt so that "resources" folder is copied near conf and lib folders), the code above stops working, due to this line
Play.application().path().getAbsolutePath()
now returns a path to bin folder, in which app.bat is ran from. So if in dev mode, the code above returns correct path like X:/app/resources/file.file, in prod mode it's like X:/app/bin/resources/file.file which is incorrect.
P.S. I absolutely can't put my files in conf folder and access them as a resource from a classloader because of numerous reasons which are actually not important.
So the question is simple as that: how to access these file resources in a universal manner across modes, without any hardcoding.
TY in advance.
There is a method on Application which lets you access files in the application root.
https://playframework.com/documentation/2.4.x/api/java/play/Application.html#getFile-java.lang.String-
default java.io.File getFile(java.lang.String relativePath)
Get a file relative to the application root path.
Parameters: relativePath - relative path of the file to fetch
Returns: a file instance - it is not guaranteed that the file exists
Since you already have the application, you should be able to use this method to directly access the file.
I have to use a library that accepts path to a directory and loads it via File(path);. What should be the path in tomcat webapp context ?
I always work with classpaths, but this API is really not thought through...
I don't have experience with java execution context in tomcat, but it seems to me a bad idea doing something like this
System.getProperty("catalina.base") + "webapps/app/WEB-INF/classes/profiles"
Does tomcat provides java execution (AKA $PWD) path for resources in application context ?
Use ServletContext#getRealPath() to convert a webapp-relative path to an absolute disk file system path. Given your example, the following should do:
String path = getServletContext().getRealPath("/WEB-INF/classes/profiles");
File file = new File(path);
// ...
Note that this requires that the WAR is expanded, otherwise it will return null. Tomcat by default expands the WAR, but some other servletcontainers/configs don't. Keep this in mind with regard to portability.
Application resources do NOT necessary exist on file system, therefore the search from context path approach is simply wrong.
You should provide an external configuration to your application (a property file or DB), where you should define the path depending on environment.
Suggested order of searching for configuration:
System.properties: -Dmy.configuration=/home/tomcat/my.properties
System environment: MY_CONFIGURATION=/home/tomcat/my.properties
Default value: ./my.properties (for Tomcat it is usually bin folder, but not guaranteed)
Fail and complain.