tags:

views:

517

answers:

3

Just to keep my sanity, I'm telling Spring to barf on circular references:

    _context = new ClassPathXmlApplicationContext(getApplicationContextFiles(), false);
    _context.setAllowCircularReferences(false);
    _context.refresh();
    _context.start();

The problem is that the resulting stack trace actually does look like barf :|

How can I get a simple output of a circular references, similar to:

Unresolved circular reference: [aBean->nextBean->otherBean->aBean]

?

+1  A: 

Hi Robert, have you tried the "Spring IDE"? It shows a graphical depiction of your dependencies. Not sure if it supports annotation based DI yet, but it should...

ThaDon
I'm afraid it does not help - the bean graph is huge and I can't see the depedencies.
Robert Munteanu
Robert, can you dump the bean graph somewhere downloadable and post a link to it so we can see what you mean by "huge" and get a look at the problem in a little more detail?
Vinay Sajip
I'm afraid I can't post the graph. I'll get a bean count though.
Robert Munteanu
+2  A: 

If all your cycles are between registered components this may help (as far as I can recall you can't reference inner beans easily as they are not registered). You can register a custom listener on events generated by the bean parsers, to do so extend the application context and override initBeanDefinitionReader(), in that method set your custom listener on the beanDefinitionReader using setEventListener (you'll need to cast to XmlBeanDefinitionReader).

The listener will be notified when ComponentDefinitions are registered and store them in a Map. Once processing of the configuration is complete, you can then process the ComponentDefinitions to identify cycles using something similar to JDepend's jdepend.framework.JavaPackage.. For each ComponentDefinition, iterate the getBeanDefinitions() and getBeanReferences() (and maybe getInnerBeanDefinitions()) and add create a "JavaPackage" for each definition and a dependency for each reference. After processing each reference and declaration, you can then interrogate the JavaPackage-like objects and spit out the results of any that return true for containsCycle()

Rich Seller
+1  A: 

The approach I'd take is to write a script (probably in Python, though Groovy is probably also quite suitable) to do the following:

  1. Parse the text of the bean graph dump to generate a directed graph of single dependencies of the form (A, B) indicating that B has a reference to A. Here A, B etc. are the nodes in the graph, and the (A, B) pairings are edges.
  2. Run a topological sort on the graph. This removes nodes in several passes. There are numerous implementations in numerous languages. Pick one for your chosen scripting language, Google is your friend.
  3. If there are any nodes left, they are your cycle (set of circular references).

It may sound a bit complicated, but actually it's not. I've solved similar problems using Python scripts many a time.

Vinay Sajip