Skip to content

Singleton-scoped @Bean methods behave like prototypes in a Spring DM environment [SPR-5932] #10601

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Jul 11, 2009 · 8 comments
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Jul 11, 2009

David Fogel opened SPR-5932 and commented

What we are seeing is that when we use @Configuration-annotated configuration classes to define our beans, that our singleton beans are instead treated as prototype beans. This means that we get new instances of our singletons for each time they are referenced (!!!).

I have created sample code which demonstrates this broken behavior.

This code, when run as a regular spring-ified java application, (NOT OSGi), works as expected (only ONE instance of Foo and Bar are created).

BUT, when the identical code is run via Spring DM, THREE different instances of Bar are created!

Note: I used a FileSystemXmlApplicationContext to load this when running as a normal java application, and put the config.xml file inside a /META-INF/spring folder when running in Spring dm.


Affects: 3.0 M3

Reference URL: http://forum.springsource.org/showthread.php?t=74458

Attachments:

Issue Links:

Referenced from: commits 9e0d87c

@spring-projects-issues
Copy link
Collaborator Author

Chris Beams commented

A quick update: I have reproduced the problem under equinox, and will pick up tomorrow and see if we can come to a solution.

In the meantime, a question: In the attached config.xml, you both explicitly register a bean for your @Configuration class, and declare <context:component-scan base-package="com.example.configtest"/>. Why was this done? The only @Component in that package is the Config class itself. Was this perhaps just to enable processing of @Configuration in the first place?

Either way, as you may well know, component-scanning does not work in a plain (non-dm Server) environment, and to enable annotation processing, the more clear way to do it would be declaring <context:annotation-config/>

@spring-projects-issues
Copy link
Collaborator Author

David Fogel commented

Hi Chris- Thanks very much for looking into this!

Regarding our bean definition and the component-scan entry, we tried to follow the instructions in the spring-reference PDF included with the 3.0M3 distribution, where it's describing the new java configuration features, page 14. It gives an example of an @Configuration-annotated class, and then says the following:

"To get this to work you need to add the following component scanning entry in your minimal application context XML file:"
<context:component-scan base-package="com.myco.config"/>

I'm pretty sure we tried it without actually having the bean also declared in the XML, and it didn't work (no beans were defined). I'm happy to change it to whatever way you think is the best- we were just taking a stab in the dark.

In general, it's not very clear to us what all these special xml entries like this do, precisely. (Our sources of understanding are the spring reference docs in general, which sometimes don't explain the inner workings...) The whole mechanism seems kind of hackish, to be honest. Pretty much the reason we wanted to use javaconfig in the first place was to get as far away as possible from crazy xml context land, where we felt like there was an increasing amount of baggage being hung on a declarative XML doc. So we're really looking to do as much of our configuration as possible in javaconfig, and just need to kick it off from XML land. The only complicating factor for us is that we're trying to use DM, which as far as I can tell mandates using the XML file for <osgi:service ...> declarations as well as <osgi:reference ...> declarations. If you know of any way for us to pull those things as well into the @Configuration class, we'd be thrilled!

@spring-projects-issues
Copy link
Collaborator Author

Chris Beams commented

I moved this bug from it's original location (OSGI-761), because it's actually an issue with JavaConfig, specifically how ConfigurationClassEnhancer works. Some time ago, a related issue, SJC-259 identified a similar issue, as did SJC-89. The fix at that time was to begin registering CGLIB callbacks statically (Enhancer.registerStaticCallbacks) instead of registering them in threadlocal fashion (Enhancer.registerCallbacks). While SJC-256 was resolved, somehow the update from registerCallbacks->registerStaticCallbacks never happened (registerStaticCallbacks was commented out.

To resolve this issue, I'll simply be making the change that should have been made back then. I have tested this against the original environment above (Spring DM 1.2, Equinox 3.5, Spring 3 trunk), and singleton-scoped @Bean methods now behave properly.

The change will be checked in shortly, and the tonight's nightly build will make the fix available.

@spring-projects-issues
Copy link
Collaborator Author

David Fogel commented

Chris, that's great news, thanks again.

You mention this will be in the nightly build. Are these nightly builds approximately as stable as the 3.0M3 milestone release? If not, are you able to let us know when the RC1 is scheduled for?

Did you get a chance to read my comment above? I realize that it might be out of the scope for this bug report, but I'd definitely like to know more about the recommended best practice for our situation regarding the XML glue, as well as some of the other things I've mentioned. you can reach me at carrotsalad@gmail.com . Thanks again!

@spring-projects-issues
Copy link
Collaborator Author

Chris Beams commented

Regarding our bean definition and the component-scan entry, we tried to follow the instructions in the spring-reference PDF included with the 3.0M3 distribution, where it's describing the new java configuration features, page 14. It gives an example of an @Configuration-annotated class, and then says the following:

"To get this to work you need to add the following component scanning entry in your minimal application context XML file:"
<context:component-scan base-package="com.myco.config"/>

I see. This will be updated in the final reference documentation to be clearer. What is required is <context:annotation-config/>. Because <context:component-scan/> is a superset of the functionality of <context:annotation-config/>, it too can be used.

In general, it's not very clear to us what all these special xml entries like this do, precisely. (Our sources of understanding are the spring reference docs in general, which sometimes don't explain the inner workings...) The whole mechanism seems kind of hackish, to be honest. Pretty much the reason we wanted to use javaconfig in the first place was to get as far away as possible from crazy xml context land, where we felt like there was an increasing amount of baggage being hung on a declarative XML doc. So we're really looking to do as much of our configuration as possible in javaconfig, and just need to kick it off from XML land.

Understood. While we hope that the XML namespaces are convenient and useful, you certainly may have a preference toward an all-or-mostly-Java approach, and that's what @Configuration class support is all about! As to the clarity of the documentation for namespaces, please do raise an issue if there's something that is not made clear in the reference docs. Did you also notice that the XSDs themselves are documented? If you're using Eclipse or IntelliJ, you should get documentation dialogs popping up when you attempt to auto-complete elements off of any of the namespaces (<context:...).

The only complicating factor for us is that we're trying to use DM, which as far as I can tell mandates using the XML file for <osgi:service ...> declarations as well as <osgi:reference ...> declarations. If you know of any way for us to pull those things as well into the @Configuration class, we'd be thrilled!

There is no way right now to declare OSGi services and references from within a @Configuration class, but this doesn't mean it can't be done. Please raise an issue for this (in the SPR project). While we don't necessarily want to provide 100% coverage of all the XML namespace features in Java, if users demand it, it certainly becomes higher priority for us!

You mention this will be in the nightly build. Are these nightly builds approximately as stable as the 3.0M3 milestone release?

Yes. Of course, there are no guarantees with a trunk build, but all tests must pass for a nightly build to be released. If anything, the nightlies should be more stable, because they contain bugfixes, much like this one ;) At this point, we're not adding too many new features to 3.0, so there shouldn't be any big worry. If you need help syncing up to the nightlies via Maven, see the comments on my blog post on Building Spring 3. I mention the Maven instructions there. Regarding RC1, I do not have a hard date on this.

Thanks for providing feedback - we'd love to hear about your ongoing experience with 3.0, especially regarding @Configuration support.

@spring-projects-issues
Copy link
Collaborator Author

David Fogel commented

Not sure if we're doing this right: we don't use maven, and the maven repo doesn't appear to be browsable. So we attempted to get the nightly build from last night by going to springsource.org, clicking on "downloads", and then clicking on the link to the nightly download area, which opened a new window at this URL:

http://static.springsource.org/downloads/nightly/snapshot-download.php?project=SPR

These builds don't appear to have dates on them, so we took the one with the highest number, in this case we downloaded "spring-framework-3.0.0.CI-330"

After updating my environment with the 3.0.0.CI-330 jars, our test case still doesn't work- multiple "Bar" objects are being created when it's supposed to be a singleton. We did change to using the <context:annotation-config /> as well.

Did we get the wrong build?

@spring-projects-issues
Copy link
Collaborator Author

David Fogel commented

following your advice in the forum thread, we downloaded what we think are the correct nightly build files, e.g.:

org.springframework.context-3.0.0.BUILD-20090715.194855-92.jar
org.springframework.context-3.0.0.BUILD-20090715.194855-92-sources.jar

but our test still fails, and 3 Bar objects are created.

looking in the source code in the unpacked sources.jar above in the file ConfigurationClassEnhancer.java, I see the following method:

private Class<?> createClass(Enhancer enhancer) {
	Class<?> subclass = enhancer.createClass();
	Enhancer.registerCallbacks(subclass, this.callbackInstances.toArray(new Callback[this.callbackInstances.size()]));
	return subclass;
}

where I notice that the call to Enhancer.registerCallbacks(...) has not been changed to Enhancer.registerStaticCallbacks(...), which is what you described changing. Do we still have the wrong nightly?

@spring-projects-issues
Copy link
Collaborator Author

Chris Beams commented

Sorry for the run-around on this. As I mentioned in the forum post, my change did not make it into yesterday's nightly build like I thought it would.

It did, however, make it into the nightly build that just finished moments ago.

You can access it here: http://static.springsource.org/downloads/nightly/snapshot-download.php?project=SPR

It is build CI-331, at the very bottom of the page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

1 participant