Spring include relative path in properties - java

I'm trying to make it so that in config/app.properties, I can have:
myfile.location=./myfile
where . is relative to said properties file. Is this possible ? I tried:
resourceLoader.getResource(appConfig.getMyFileLocation());
where resourceLoader and appConfig are autowired, but it won't work.

I usually reference my files like this:
myfile.location=classpath:myfile
where myfile is at the same location as the properties file.

Java properties are key-value pairs. So when you specify myfile.location=./myfile, this means appConfig.getMyFileLocation() will return './myfile' which is not the correct location.
As a workaround, you can get the location of the properties file and then use it along with the relative location to find the absolute path.
File propertyFileDirectory = .... // get the property file directory
String myfilePath = appConfig.getMyFileLocation();
File file = new File(propertyFileDirectory, myfilePath);

Related

How to use SpringBoot PropertySource to read from an external configuration file

I've created a configuration class that will store configuration values. These configuration values should be read in from a configuration file "config.properties". Below is the config class:
#Configuration
#ComponentScan(basePackages = {"com.boot.Training.*"})
#PropertySource("file:/src/main/java/config.properties")
public class AppConfig {
#Value("${myFirstName}")
private static String myFirstName;
#Value("${myLastName}")
private static String myLastName;
public static void showVariables() {
System.out.println("firstName: " + myFirstName);
System.out.println("lastName: " + myLastName);
}
}
And below are the contents of the config.properties file:
myFirstName=John
myLastName=Doe
Running my program should simply print the values of these variables. But instead, Eclipse tells me it cannot find the config.properties file, even though I specified that it is located in /src/main/java/config.properties .
I'm likely specifying the file location without taking something else into account. What am I missing here?
The location you are using (file:/src/main/java/config.properties) refers to an absolute path rather than one relative to your project home.
A more common way to do this is to ship config.properties as part of your project in a resources directory, and refer to it via the classpath. If you move it to /src/main/resources/config.properties, you can load it this way:
#PropertySource("classpath:config.properties")
I believe in theory you could just leave it in /src/main/java and change your #PropertySource location to what I have above, but moving it to /resources is the more idiomatic way of doing this.
The basic way to specify a file: location to appoint a properties file that is located elsewhere on your host environment is:
#PropertySource("file:/path/to/application.properties")
Note that /path/to/application.properties should be absolute path pointing to your .properties file (in your example you are mixing file: usage and relative path which is not correct )
it is also possible to specify a system property or an environment variable that will be resolved to its actual value when your application starts. For example, ${CONF_DIR} below will be replaced with its associated value when the Spring application starts:
Open /etc/environment in any text editor like nano or gedit and add the following line:
CONF_DIR=/path/to/directory/with/app/config/files
Check it system variable has been set:
echo $CONF_DIR
/path/to/directory/with/app/config/files
use PropertySource like:
#PropertySource("file:${CONF_DIR}/application.properties")

correct way to read properties file

I am having trouble finding out the right way to load a properties file.
The structure is : Inside src/com.training , I have my class and the properties file as well. I have to read it using the absolute path as shown in the code below to get it to work:
Properties prop = new Properties();
InputStream input = null;
input = new FileInputStream("D:/Dev/workspace/Training/src/com/training/consolemessages.properties");
prop.load(input);
System.out.print(prop.getProperty("INITIAL_MESSAGE"));
How can I use the relative path to work in this code for accessing the properties file. The properties file and the class which is accessing are both at the same level '/src/com.training'
You could put your properties files into src/resources folder, and fetch them on classpath.
You could do something like this:
ResourceBundle bundle = ResourceBundle.getBundle("resources/consolemessages");
System.out.println(bundle.getString("INITIAL_MESSAGE"));
When using ResourceBundle, Locale support is also easy to implement, should you need to have language specific properties.

Relative to absolute path in java

I have have a file that I want to use in my project which is in the resources package
src.res
Following what was stated in this answer, I believe that my code is valid.
File fil = new File("/res/t2.nii");
// Prints C:\\res\\t2.nii
System.out.println(fil.getAbsolutePath());
The problem is that I that file is in my projects file not there, so I get an Exception.
How am I suppose to properly convert from relative path to absolute?
Try with directory first that will provide you absolute path of directory then use file.exists() method to check for file existence.
File fil = new File("res"); // no forward slash in the beginning
System.out.println(fil.getAbsolutePath()); // Absolute path of res folder
Find more variants of File Path & Operations
Must read Oracle Java Tutorial on What Is a Path? (And Other File System Facts)
A path is either relative or absolute.
An absolute path always contains the root element and the complete directory list required to locate the file.
For example, /res/images is an absolute path.
A relative path needs to be combined with another path in order to access a file.
For example, res/images is a relative path. Without more information, a program cannot reliably locate the res/images directory in the file system.
Since you are using a Java package, you must to use a class loader if you want to load a resource. e.g.:
URL url = ClassLoader.getSystemResource("res/t2.nii");
if (url != null) {
File file = new File(url.toURI());
System.out.println(file.getAbsolutePath());
}
You can notice that ClassLoader.getSystemResource("res/t2.nii") returns URL object for reading the resource, or null if the resource could not be found. The next line convertes the given URL into an abstract pathname.
See more in Preferred way of loading resources in Java.
validate with
if (fil.exists()) { }
before and check if it really exist. if not then you can get the current path with
System.getProperty("user.dir"));
to validate that you are starting fromt he proper path.
if you really want to access the path you shouldnt use absolut pathes / since it will as explained start from the root of your Harddisk.
you can get the absolut path of the res folder by using this what my poster was writte in the previous answer:
File fil = new File("res");
System.out.println(fil.getAbsolutePath());

Reading from src/main/resources gives NullPointerException

In my Maven project, I have a xls file in src/main/resources.
When I read it like this:
InputStream in = new
FileInputStream("src/main/resources/WBU_template.xls");
everything is ok.
However I want to read it as InputStream with getResourceAsStream. When I do this, with or without the slash I always get a NPE.
private static final String TEMPLATEFILE = "/WBU_template.xls";
InputStream in = this.getClass.getResourceAsStream(TEMPLATEFILE);
No matter if the slash is there or not, or if I make use of the getClassLoader() method, I still get a NullPointer.
I also have tried this :
URL u = this.getClass().getResource(TEMPLATEFILE);
System.out.println(u.getPath());
the console says.../target/classes/WBU_template.xls
and then get my NullPointer.
What am I doing wrong ?
FileInputStream will load a the file path you pass to the constructor as relative from the working directory of the Java process.
getResourceAsStream() will load a file path relative from your application's classpath.
When you use .getClass().getResource(fileName) it considers the location of the fileName is the same location of the of the calling class.
When you use .getClass().getClassLoader().getResource(fileName)
it considers the location of the fileName is the root - in other words bin folder.
The file should be located in src/main/resources when loading using Class loader
In short, you have to use .getClass().getClassLoader().getResource(fileName) to load the file in your case.
I usually load files from WEB-INF like this
session.getServletContext().getResourceAsStream("/WEB-INF/WBU_template.xls")

Spring MVC Read and Parse a file in

I'm new to Spring and I'm just trying to open a simple text file and parse it so I can create some POJOs. My problem is I can't get Spring to find the txt file.
I've tried putting the file all over the place and right now I've put it in
/myAop/src/main/resources/myFile.txt
and I'm referencing it in a file called
com.myApp.pojo.Team.java
using code like this:
FileSystemResource resource = new FileSystemResource("/myApp/src/main/resources/myFile.txt");
File f =resource.getFile();
However, I'm not having any luck.
I've also tried several other locations.
Thanks in advance for the help.
You need to specify file name only as src/main/resource is already in classpath.
Try this:
FileSystemResource resource = new FileSystemResource("myFile.txt");
File f =resource.getFile();
Try
New Xmlclasspathresource() .
Try anothe path
FileSystemResource resource = new FileSystemResource("/main/resources/myFile.txt");
Actually the file from resources is placed under classes.
Try using absolute path
FileSystemResource resource = new FileSystemResource("file:C:/test/workspace/src/myApp/src/main/resources/myFile.txt");
You may use classpath as well, but the file should be in the classpath.
FileSystemResource resource = new FileSystemResource("classpath:myApp/src/main/resources/myFile.txt");
What I wound up doing was putting the file in base directory with the POM.xml file and then i could get to it just by using the name and not by having to use any kind of path. I'm sure there are better ways but for the time being I just needed to move on.

Categories