[BLOSSOM-144] Spring Profiles not supported Created: 10/Oct/13 Updated: 12/Nov/13 Resolved: 12/Nov/13 |
|
| Status: | Closed |
| Project: | Blossom |
| Component/s: | None |
| Affects Version/s: | 3.0 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Neutral |
| Reporter: | Sigurd Rolfes | Assignee: | Tobias Mattsson |
| Resolution: | Not an issue | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Environment: |
Windows 7 professional |
||
| Attachments: |
|
| Template: |
|
| Acceptance criteria: |
Empty
|
| Task DoD: |
[ ]*
Doc/release notes changes? Comment present?
[ ]*
Downstream builds green?
[ ]*
Solution information and context easily available?
[ ]*
Tests
[ ]*
FixVersion filled and not yet released
[ ] 
Architecture Decision Record (ADR)
|
| Bug DoR: |
[ ]*
Steps to reproduce, expected, and actual results filled
[ ]*
Affected version filled
|
| Date of First Response: |
| Description |
|
When using profiles in Spring the active profile settings seem to get loss in application context initialization. Application/Servlet context gets initialized in the BlossomModuleSupport class which will be extended by the Mgnl module class. Usually there are a few ways to set the active profile in Spring (spring.profiles.active): 1. via <context-param> in the web.xml The latter should automatically be called when providing the profile name via system property (VM arg). We tried system property, context-param and bean xml definition, no success. If the profile definition is missing several beans are just ignored during instantiation process. We use xml profile and annotation based profiles, this makes no difference. |
| Comments |
| Comment by Tobias Mattsson [ 10/Oct/13 ] |
|
I can't reproduce your problem. I'm using a test bean which looks like this: public class ProfileTestBean { @PostConstruct public void init() { System.out.println(""); System.out.println(""); System.out.println(""); System.out.println(" YES I AM STARTED"); System.out.println(""); System.out.println(""); System.out.println(""); } } And I add it to the applicationContext.xml like this: <context:annotation-config /> <beans profile="development"> <bean class="info.magnolia.blossom.sample.module.ProfileTestBean"/> </beans> I get the output when I add this to the web.xml <context-param> <param-name>spring.profiles.active</param-name> <param-value>development</param-value> </context-param> I get the output when starting with -Dspring.profiles.active=development. And when setting it manually like this: public void start(ModuleLifecycleContext moduleLifecycleContext) { if (moduleLifecycleContext.getPhase() == ModuleLifecycleContext.PHASE_SYSTEM_STARTUP) { // super.initRootWebApplicationContext("classpath:/applicationContext.xml"); initRootWebApplicationContext(new ContextLoader() { @Override protected void customizeContext(ServletContext servletContext, ConfigurableWebApplicationContext applicationContext) { applicationContext.getEnvironment().setActiveProfiles("development"); applicationContext.setConfigLocations(StringUtils.tokenizeToStringArray("classpath:/applicationContext.xml", ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS)); } }); // this servlet will pick up the active environments from the parent super.initBlossomDispatcherServlet("blossom", "classpath:/blossom-servlet.xml"); } } I'm not aware of a way to specify the active profile within the beans xml file. As far as I know the profile you specify there is the condition, the profiles for which the beans are active. Could you show me an example? Spring reads the properties using the PropertySources configured, by default in a web application these include system properties and context init parameters, if you have modified these then maybe that's what's causing the problem. |
| Comment by Sigurd Rolfes [ 10/Oct/13 ] |
|
Hi Tobias, your code example is close to what I'm currently trying. I extended the BlossomModuleSupport and try tried to set the profile via ConfigurableEnvironment. Well, I need it in the servlet context and also tried this: CustomServletConfig servletConfig = new CustomServletConfig(servletName, getServletContext()); I think I have to reduce complexity and try a simple profile. Just setting -Dspring.profiles.active=development should already do the job without any further changes? Spring should automatically recognize and call setActiveProfile() in the context initialisation process. Sigurd |
| Comment by Sigurd Rolfes [ 10/Oct/13 ] |
|
and I'll have a look at the PropertySources first. |
| Comment by Tobias Mattsson [ 10/Oct/13 ] |
|
Yes, this all takes place in org.springframework.core.env.AbstractEnvironment#doGetActiveProfiles. It will first look for it in ServletConfig, then ServletContext, then system properties and finally in system environment variables. Could you show me the bean definition xml file? Maybe that's where the problem is. |
| Comment by Sigurd Rolfes [ 10/Oct/13 ] |
|
Tobias, did you test profiles with the BlossomDispatcherServlet and corresponding component-scan for Blossom? <context:annotation-config/> Sigurd |
| Comment by Sigurd Rolfes [ 10/Oct/13 ] |
|
Example for defining the active profile in the bean tag: <?xml version="1.0" encoding="UTF-8"?> |
| Comment by Tobias Mattsson [ 10/Oct/13 ] |
|
Right, so that whole file will only be parsed if the "development" profile is active. Tried it now with the blossom servlet, works as expected, even tried with the component scan within a <beans profile="development"> and i could switch it on and off using -Dspring.profiles.active=development |
| Comment by Sigurd Rolfes [ 10/Oct/13 ] |
|
We've got hundreds of classes and most profile settings annotation driven. I'll reduce complexity and make a simple test. |
| Comment by Sigurd Rolfes [ 10/Oct/13 ] |
|
ok, I've made a test in a simple mgnl module with annotated classes and beans in the servlet context xml. Works fine with just specifying -Dspring.profiles.active=development. I will have a look at the property hint. |
| Comment by Sigurd Rolfes [ 11/Oct/13 ] |
|
Hi Tobias, I've got it working now and found very strange behaviour that is related to Spring, I guess. Let me explain. We've got lots of classes and all annotation driven. Regarding the problem it's basically this: public interface MyTestComponent () {} @Component("testComponent") @Component("testComponent") @Component("useTestComponent") @Autowired } Application context is empty, servlet context has some classes (webflow configuration etc.), but nothing related to the problem. When starting up I got an exception "no default constructor found for class Test". For whatever reason Spring tries to use a default constructor, which of course is not there. Although I would expect an exception like "no bean of type testComponent found" my conclusion was either: 1. component-scan does not work Even a @DependsOn("testComponent") did not work on class Test. Now the strange thing: Defining the beans in the servlet context xml works fine: <bean class="de.itr.Test" id="useTestComponent" > <beans profile="development"> I already mentioned in an other bug we've got a web application we're trying to integrate via Blossom and standalone this application works fine. Well, I already noticed that there is some different behaviour when using either Tomcat or JBoss. My conclusion for now is that there must be a difference between the XMLProcessor and the AnnotationProcessor. Just to let you know: when deleting your includes for the Blossom annotations in the component scan: everything still works fine. Well, I'm sorry to bother you with my problems. Sigurd |
| Comment by Tobias Mattsson [ 11/Oct/13 ] |
|
Interesting, could I see the full stack trace for the "no default constructor found for class Test" problem. Is the test bed you're using something you could share with me? |
| Comment by Sigurd Rolfes [ 11/Oct/13 ] |
|
find attached my simple test case. Currently I've got the WEB-INF stuff in the webapp module. The other files in a separate module. I hope I didn't miss anything. |
| Comment by Sigurd Rolfes [ 11/Oct/13 ] |
|
Tobias, for the log output: can I send you a private message, it's customer code... Sigurd |
| Comment by Sigurd Rolfes [ 11/Oct/13 ] |
|
mmh, I've overseen something. The problematic class is implementing FactoryBean<JavaMailSender> and JavaMailSender is used in the constructor of a service class. Have to investigate some more details... |
| Comment by Tobias Mattsson [ 12/Nov/13 ] |
|
Did you find the cause of this problem? |
| Comment by Sigurd Rolfes [ 12/Nov/13 ] |
|
no, I just moved the problematic classes to xml file. Now it works. You may close this as profiles work. |