3

I have an application that requires configuration on start-up. However, I can't store this in /resources since every environment that will host this application will be completely different. For now, I want to add a directory from the filesystem to the classpath - let's say /tr/apps/ (where /tr/apps/ is the root of where the application is deployed).

I found a Maven plugin which looked like it would do the job: https://maven.apache.org/surefire/maven-surefire-plugin/examples/configuring-classpath.html

So I added this to my pom:

<build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.0.0-M3</version>
        <configuration>
          <additionalClasspathElements>
            <additionalClasspathElement>/tr/apps</additionalClasspathElement>
          </additionalClasspathElements>
        </configuration>
      </plugin>
    </plugins>
  </build>

Now I have to use the following method to get the file:

InputStream inputStream = Thread.currentThread().getContextClassloader().getResourceAsStream("tr/apps/myFile.txt")
if(inputStream == null) {
    throw new Exception("myFile.txt not found");
}

This exception always seems to be thrown (i.e. it isn't able to find the file on the classpath). Does anybody know why this is? Or if there is an alternative plugin/solution for this?

Would really appreciate any input!

reyusay
  • 31
  • 1
  • The documentation for getResource says this is not possible. Possibly catch the exception and open it with FileInputStream instead. Given the nature of computing these days (cloud, docker) it is probably not a good idea to rely on host (container) directories for environment variables. There are many alternative designs. – fedup Nov 11 '19 at 23:09
  • Is this an application run from a command line, or is it server based (such as Tomcat)? – Steve C Nov 12 '19 at 06:00
  • It is server-based – reyusay Nov 12 '19 at 11:31

1 Answers1

1

maven-surefire-plugin is used to execute unit tests and the resources added to the classpath using additionalClasspathElement is only available during Maven's test phase. (i.e. You can not use these files in your actual application code other than your unit tests).

Update: I am not sure whether this solution is applicable to you but A possible workaround/solution is to pass the file location as a JVM argument and then using FileInputStream read the file.

Example: Pass a jvm argument as -Dexternal.config.file.path=/Users/Documents/my-app-config.properties and in your java code read the file.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class ConfigFileReader {

    private static final Logger logger = LogManager.getLogger(ConfigFileReader.class);

    public static void readConfigFile() {

        String configFilePath = System.getProperty("external.config.file.path");
        try (InputStream inputStream = new FileInputStream(new File(configFilePath))) {
            // Do your stuff
        } catch (FileNotFoundException e) {
            logger.error("{} File not found", configFilePath);
        } catch (IOException e) {
            logger.error("IOException occurred while reading {}", configFilePath);
        }
    }

}
Ramu
  • 641
  • 6
  • 9
  • Hi @Ramu, this is not really an answer to the question. But it does echo a comment I was about to add to the question... – Steve C Nov 12 '19 at 05:02
  • @SteveC My answer was specific to this question _Does anybody know why this is?_ – Ramu Nov 12 '19 at 05:07
  • Thanks for the answer, however as stated in the question I MUST use InputStream inputStream = Thread.currentThread().getContextClassloader().getResourceAsStream("tr/apps/myFile.txt") – reyusay Nov 12 '19 at 11:31
  • @reyusay please see this URL. https://stackoverflow.com/questions/1010919/adding-files-to-java-classpath-at-runtime. It might give you an idea on how to do it. – Ramu Nov 12 '19 at 12:36
  • @reyusay Also, any particular reason you want to use ClassLoader to read the file? – Ramu Nov 12 '19 at 18:01