Reputation: 1750
I'm using Spring (without spring-boot). I want to build standalone application that can be run with default configuration (logback.xml
and application.properties
in resource folder) or with -Dconfig.folder=/path/to/custom/external/directory
(logback.xml
and application.properties
in /path/to/custom/external/directory). When application will be run with -Dconfig.folder param AppConfig
should load both logback and properties from external directory.
Is there anyway to make external folder act like a resource folder?
If not, what is a common solution for this?
My current implementation (using default resource folder only):
App.java
public class App {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
SampleAction p = context.getBean(SampleAction.class);
p.performTask();
}
}
AppConfig.java
@ComponentScan
@PropertySource("classpath:application.properties")
class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
SampleAction.java
@Component
public class SampleAction {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Value("${sample.prop}")
private String sampleProp;
public void performTask(){
logger.debug(sampleProp);
}
}
logback.xml and application.properties are not relevant to the problem
Upvotes: 0
Views: 1837
Reputation: 24583
Unlike the other answer suggests, if you use file
prefix in @PropertySource
, you're screwed because it won't be able to load the default application.properties
from the jar. What you should do is the following:
@PropertySource("${config.folder:'classpath:'}/application.properties")
public class AppConfig
For logback.xml
:
@Value("${config.folder}:")
private String configFolder;
InputStream = Optional.of(new ClassPathResource(configFolder + "/logback.xml"))
.filter(r -> r.exists())
.orElse(new ClassPathResource("classpath:/logback.xml"))
.getInputStream();
In both cases, I gave preference to the command line argument over the default packaged files. Of course, I didn't compile the above, so there may be typos or minor errors, but you get the idea.
Edit:
Since OP claims to not understand where to run the above code -
public class AppConfig {
@PostConstruct
void init() {
// init logback here
}
}
Upvotes: 1
Reputation: 6818
For log4j.xml
-Dlog4j.configuration=C:\neon\log4j.xml
as VM argument
In main() method:
String filename = System.getProperty("log4j.configuration");
DOMConfigurator.configure(filename);
For external properties file:
-Dext.prop.dir=C:\neon
as VM argument
Change in your AppConfig class will be like
@PropertySource("file:///${ext.prop.dir}/application.properties")
public class AppConfig{
}
Run App class with VM arguments as below and both file will be use from external location
-Dlog4j.configuration=C:\neon\log4j.xml -Dext.prop.dir=C:\neon
Upvotes: 0