Jan Vladimir Mostert
Jan Vladimir Mostert

Reputation: 12972

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.

Upvotes: 1

Views: 7471

Answers (2)

David Chaava
David Chaava

Reputation: 192

In spring context add this beans

<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer" />
<bean class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer" />

after create class

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;

@Configuration
@PropertySource("classpath:mypropfile.properties")
public class Config {
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
}

and than annotate your variables

@Value("${cert.path}") private String certPath;

Upvotes: 0

yunandtidus
yunandtidus

Reputation: 4086

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

Upvotes: 2

Related Questions