Search code examples
javaspringmaventomcatapache-commons-config

Find absolute path of *.properties file in Spring context


I have some legacy jars I'm trying to get to work inside a spring context.

Inside my applicationContext.xml, I load the property file(s) using:

<context:property-placeholder location="classpath*:META-INF/spring/*.properties" />

... and it works perfect while inside the spring context.

In the legacy code, I need to get the absolute path of that config file(s) and it should work when I run mvn tomcat:run and when it's packaged into a war file and deployed to a Tomcat container (in case you're wondering, yes, spring and the legacy code shares the same application.properties config file).

@Service
public class Startup {    

    Logger log = LoggerFactory.getLogger(Startup.class);   

    @PostConstruct
    public void startup() throws Exception {
        if (!LegacyCode.isInit()){
            // this works using a hardcoded path
            LegacyCode.init("/home/user/absolute/path/to/application.properties"); 
            // this doesn't work, but would the preferred solution if it did
            // LegacyCode.init("classpath*:META-INF/spring/*.properties"); 
        }
    }
}

I've considered using:

    String config[] = { "classpath*:META-INF/spring/applicationContext.xml" };
    ApplicationContext ctx = new ClassPathXmlApplicationContext(config);

and then hijack the path using ctx.getResource, but besides the point that it's very inefficient to load the applicationContext a second time just to get the application.properties' absolute path, it'll also cause an infinite loop of @PostConstruct being executed.

The legacy code uses Commons Configuration (as far as I can see and based on dependency errors) to setup its config, what I'm looking for is a way for Commons Configuration to load the correct application.properties file whether it's running on Linux, Windows, from a WAR file or from an embedded Tomcat, etc.


Solution

  • It seems that you legacyCode wants a proper filePath, and does not understand Spring resources ("classpath*:META-INF/spring/applicationContext.xml")

    I personnaly would do the following :

    LegacyCode.init(new File(this.getClass().getClassLoader().getResource("application.properties").toURI()).getPath());
    

    getResource("application.properties") is the Java equivalent of Spring notation