1

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.

Jan Vladimir Mostert
  • 12,380
  • 15
  • 80
  • 137
  • 1
    You have multiple properties file in your Spring xml, but you LegacyCode accepts only one ? – yunandtidus Dec 22 '14 at 15:55
  • That's correct, the configuration I need for the legacy stuff is segmented, so for jar1 I need a specific configuration and for jar2 I need a different configuration, both uses Commons Configuration, Spring needs both, your answer looks like it would do the job, will test in a bit and get back your answer. – Jan Vladimir Mostert Dec 22 '14 at 20:51

2 Answers2

2

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

yunandtidus
  • 3,847
  • 3
  • 29
  • 42
  • Works 100%, this is what I used in the end: LegacyCode.init(new File(this.getClass().getClassLoader().getResource( "META-INF/spring/application.properties").toURI()).getPath()); Thanks yunandtidus!! – Jan Vladimir Mostert Dec 23 '14 at 07:51
0

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;

David Chaava
  • 184
  • 1
  • 6