0

I have seen some similar questions asked but the solutions for them haven't worked for me.

I have created a very simple project in which I am able to read the appconfig.xml file when running in an IDE but when I try to run the compiled JAR from the command line finding the resource fails. The following is my project structure: screenshot of project structure in Eclipse

This is my config reader class:

package helpers;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import test.Main;

public class ConfigReader {

    private static Map<String, String> config;
    private static boolean configLoaded = false;

    public ConfigReader() {
        loadConfig();
    }

    public boolean isLoaded() {
        return configLoaded;
    }

    public void loadConfig() {
        ClassLoader loader = ClassLoader.getSystemClassLoader();
        InputStream stream = loader.getResourceAsStream("appconfig.xml");
        
        if(stream == null)
        {
            stream = loader.getResourceAsStream("../resources/appconfig.xml");
        }
        
        if(stream == null)
        {
            stream = Main.class.getResourceAsStream("appconfig.xml");
        }
        
        if(stream == null)
        {
            stream = Main.class.getResourceAsStream("../resources/appconfig.xml");
        }       
        
        if(stream == null)
        {
            stream = Main.class.getClassLoader().getResourceAsStream("appconfig.xml");
        }
        
        if(stream == null)
        {
            stream = Main.class.getClassLoader().getResourceAsStream("../resources/appconfig.xml");
        }

        if (stream == null) {
            throw new NullPointerException("Unable to find appconfig.xml");
        }

        Properties props = new Properties();
        config = new HashMap<String, String>();
        try {
            props.loadFromXML(stream);
        } catch (IOException e) {

            e.printStackTrace();
        }

        for (String key : props.stringPropertyNames()) {
            String value = props.getProperty(key);
            config.put(key, value);
        }

        configLoaded = true;
    }

    public String getConfig(String key) {
        if (!configLoaded) {
            loadConfig();
        } else if (config.containsKey(key))
            return config.get(key);
        return config.get(key);
    }
}

My main class is like this:

package test;

import helpers.ConfigReader;

public class Main {
 public static void main(String[] args) {
     ConfigReader configReader = new ConfigReader();
     System.out.println(configReader.getConfig("example"));
 }
}

I am running the main with the command 'java -jar poc.jar'

I have checked that the resources are inside the compiled jar. Inside the JAR looks like this: screenshot of JAR root

My classpath file contains the following:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" output="target/classes" path="src/main/java">
        <attributes>
            <attribute name="optional" value="true"/>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="src" output="target/test-classes" path="src/test/java">
        <attributes>
            <attribute name="optional" value="true"/>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="output" path="target/classes"/>
</classpath>

Thanks in advance for any replies.

R Brandon
  • 1
  • 1
  • 1
    Try replacing `../resources/appconfig.xml` with `/resources/appconfig.xml`, and make sure your resources folder exists in both the src folder, and inside your classpath (which for Eclipse is in the bin folder) – thorin9000 Mar 01 '22 at 17:02
  • @thorin9000 Thanks, that's got it working! I found that Main.class.getResourceAsStream("/resources/appconfig.xml"); was able to find the resource when running as a JAR but not the other methods. I updated the question to include the classpath contents in case they are 'wrong'- unfortunately I'm not sure what's supposed to be in there. However, very pleased this is now working. – R Brandon Mar 02 '22 at 10:07
  • Awesome- also, the classpath (`bin` folder) isn't visible from Eclipse, it'd need to be opened manually (before it's packaged to a jar); though Eclipse _should_ copy the resources folder from `src` to `bin` automatically. If the path sent into `getClass().getResourceAsStream(path)` starts with a `/`, then it'll search for resources from the root folder of the classpath. This post explains it in detail - https://stackoverflow.com/a/14739608/7254424 – thorin9000 Mar 02 '22 at 15:12

0 Answers0