Reputation: 254
I have a shared library that several of my apps use to send emails. It requires authorization to an SMTP server with credentials we keep in a secure file stored on the server filepath instead of in the app classpath. Because we use the lib in several apps, there is a shared config that the apps can import to setup the credentials automatically. It works well on Spring Boot and Spring Web apps, but for some reason when I try it one of our batch jar apps (not Spring Batch!), the application cannot find the secret file and the credentials are null when we try to send an email.
If I have the batch jar app load the secure file itself it works, so the app does have access to file location. But when I @Import the shared config like I do elsewhere, it doesn't seem to find the file. I'm wondering if there's some kind of setup issue that put the cart before the horse so to speak?
shared library config classes:
@Configuration
@PropertySource(value = { "file:/scr/my-lib/${platform.env}-sec.properties" }, ignoreResourceNotFound = true)
public class MyLibraryConfig {
@Bean
public MyLibProperties myLibProperties() {
return new MyLibProperties();
}
@Bean
public JavaMailSender mailSender(final MyLibProperties properties) {
final JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setUsername(properties.getAccount());
sender.setPassword(properties.getPassword());
}
}
public class MyLibProperties {
@Value("${scr.mylib.account:#{null}}")
private String account;
@Value("${scr.mylib.password:#{null}}")
private String password;
}
Notes: The "scr.mylib" props are defined in the secure file. So if it is loaded into the app context, they will be populated, else they will be null. I removed the "ignoreResourceNotFound" flag from the @PropertySource
and the app did not complain about a missing file, but the MyLibProperties fields were both null anyways.
Spring app that uses the library:
/**
* This is not a Spring web app, but rather a jar that is kicked off via a chron script like a batch job.
*/
public class MyAppMain {
public static void main(String[] args) {
final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.registerShutdownHook();
context.register(ApplicationConfig.class);
context.refresh();
context.getBean(AppRunner.class).run();
}
}
@Configuration
@Import(MyLibConfig.class)
@ComponentScan(basePackages = {"..."})
@ImportResource({"classpath:spring.xml"})
public class ApplicationConfig {
private static final String ENV = System.getProperty("platform.env");
@Bean
public static PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() {
final PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
configurer.setLocations(
new ClassPathResource("props/env.properties"),
// NOTE, if I add the library props file here, as below, the credentials DO get
// loaded correctly, but using the @Import above on its own fails.
// new FileSystemResource("/scr/my-lib/" + ENV + "-sec.properties")
);
configurer.setIgnoreResourceNotFound(true);
return configurer;
}
}
An example of another older Spring app where it works:
@Configuration
@Import(SnetEmailConfig.class)
@ComponentScan(basePackages = "...")
public class MySpringAppInitializer extends HttpServlet {
...
An example of a Boot app where it works:
@Import(SnetEmailConfig.class)
@SpringBootApplication
public class MyBootApp extends SpringBootServletInitializer {
...
Upvotes: 0
Views: 37