Issue
I basically have a bean in Spring that I wanted to activate only when 2 profiles are active. Basically, it would be like:
@Profile({"Tomcat", "Linux"})
public class AppConfigMongodbLinux{...}
@Profile({"Tomcat", "WindowsLocal"})
public class AppConfigMongodbWindowsLocal{...}
So I'd like that when I use -Dspring.profiles.active=Tomcat,WindowsLocal
, it would try to use only the AppConfigMongodbWindowsLocal
, but it still tries to register the AppConfigMongodbLinux
.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appConfigMongodbLinux': Injection of autowired dependencies failed
Is it possible to make the bean be registerd only when both profiles are active or am I using it incorrectly? :)
Thanks!!
Edit: Posting the full stack.
The error is actually on a property that is missing on the properties, but will this bean get activated? I wanted to understand this to ensure I'm not activating a wrong bean..
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appConfigMongodbLinux': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.Integer mycompany.config.AppConfigMongodbLinux.mongoPort; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'mongo.port' in string value "${mongo.port}"
... 40 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.Integer mycompany.config.AppConfigMongodbLinux.mongoPort; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'mongo.port' in string value "${mongo.port}"
...
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'mongo.port' in string value "${mongo.port}"
Solution
Unfortunately, @Profile
activates if any listed profile is active. There are a couple of ways around this.
- Apply the common
@Profile("Tomcat")
annotation to a top-level configuration class, and then apply@Profile("Windows")
to a nested configuration class (or@Bean
method). - If Spring Boot is acceptable as a dependency, use
@AllNestedConditions
to create an annotation that's the AND instead of the OR.
It looks like what you're trying to do would be clean to write if you were using Spring Boot autoconfiguration classes; if it's practical to introduce autoconfiguration at this stage of your application's lifecycle, I recommend considering it.
Answered By - chrylis -cautiouslyoptimistic-
Answer Checked By - Terry (JavaFixing Volunteer)