Skip to content
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

Detect circular dependencies within @Configuration classes and throw a helpful exception [SPR-8609] #13252

Open
spring-projects-issues opened this issue Aug 11, 2011 · 2 comments
Labels
in: core type: enhancement

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Aug 11, 2011

Tomasz Nurkiewicz opened SPR-8609 and commented

In the following @Configuration class assertion fails because the SpEL expression is not evaluated prior to running bar():

@Configuration
public class ContextConfiguration {

	@Resource
	private Foo foo;

	@Value("#{2+3}")
	private int value;

	@Bean
	public Bar bar() {
		Assert.isTrue(value == 5, Integer.toString(value));
		return new Bar();
	}

}

Because cyclic dependency is introduced, bar() is executed by the container on ContextConfiguration that is not yet populated:

@Service
public class Foo {

	@Resource
	private Bar bar;

}

public class Bar {
}

I am aware that fixing this might be a bit challenging, but at least an exception should be thrown rather than silently calling @Bean method on uninitialized @Configuration class. Full failing test case is available here (spring-cyclic-dep-bug branch).


Affects: 3.1 M2

Issue Links:

  • #13226 unresolvable circular reference when bean defined in xml config refers to bean defined in outer java config
@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Dec 6, 2011

Chris Beams commented

Tomasz,

This certainly makes sense, however the implementation is not terribly trivial. The only way to track this sort of thing would be via a ThreadLocal registry of bean method invocations interacting with the enhanced CGLIB subclass @Bean methods. It's a fair bit of overhead both at actual runtime and in general implementation complexity to achieve better error reporting for what is probably a relatively infrequent mistake.

For this reason I'm moving this to the General Backlog and marking as 'waiting-for-demand'; we'll certainly pay attention if other users weigh in here with additional comments, votes, etc.

In any case, thanks for the submission.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Apr 10, 2013

Janning Vygen commented

We had a very similar problem with circular references which was really annoying and in my opinion is a bug. I put it here as I think this relates to this issue.

@Configuration
public class ContextConfiguration {

	@Resource
	private Foo foo;

	@Bean
	public Bar bar() {
		Bar bar = new Bar();
                bar.setFoo(foo);
	}
}

@Service
public class Foo {

	@Resource
	private Bar bar;

}

public class Bar {
}

this has worked fine on our development machines, but NOT on our production machines as the "bar" bean was operating with a null value of foo. So we got a NPE.

I guess that component scanning worked differently on my development machine (ubuntu/jetty) than on my production machine (debian/tomcat).

We have four operations which can run like this:

  • Foo.newInstance()
  • ContextConfiguration.inject(foo)
  • bar()
  • Foo.inject(bar)

But on our production machine spring did in a different way so we ended up with NPE because foo was null at the time bar() was called.

This should be fixed as this is not deterministic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core type: enhancement
Projects
None yet
Development

No branches or pull requests

1 participant