Dashboard > BeanDoc > Home
  BeanDoc Log In View a printable version of the current page.  
  Home
Added by Darren Davison, last edited by Darren Davison on Nov 01, 2007  (view change)
Labels: 
(None)

Spring BeanDoc

Information that used to be maintained here about the project has moved.. please see http://spring-beandoc.sourceforge.net/

I have a problem running BeanDoc as Ant (1.6.1) task (Windows, IBM VM 1.4.2), I get the following result. (Running BeanDoc CLI works without problems...)

— result —
[beandoc] 24.02.2005 10:59:21 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
[beandoc] INFO: Loading XML bean definitions from class path resource [org/springframework/beandoc/client/beandoc.xml]

BUILD FAILED
D:\workspace\global\build-beandoc.xml:34: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [org/springframework/beandoc/client/beandoc.xml]; nested exception is java.io.FileNotFoundException: Could not open class path resource [org/springframework/beandoc/client/beandoc.xml]
— end of result —

Any ideas? Anyone having the same problem?

Felix

BeanDoc is a great tool, especially the visualization of dependencies is very useful.

To make it even better, I have some improvement ideas:

  • detecting <lookup-method> tags as dependencies
  • Model inputFiles argument of the AntTask as a fileset/path reference instead of a string attribute (probably two attributes for classpath / filesystem references)
  • Optionally merge ProxyFactoryBean and it's target (there are reasons not to inline the target of a ProxyFactoryBean, but this separation makes the visualization unnecessary complex).

What do you think?

Felix

1. <lookup-method> - I'll see what can be done about this.

2. inputFiles as fileset - I agree it's more natural for Ant usage, but to permit any Spring resource location string (classpath:/com/foo/bar/context.xml for example, or any of the wildcard options) is IMO superior. I'll probably keep this as it is unless there's great pressure to duplicate the property setting mechanism.

3. Option to merge ProxyFactories and their targets in the graphs - I'll endeavour to add this as soon as I can.

Thanks again for the comments.

I'm going to look at the Ant issue today. Could you let me know a bit more about the command being run (what's in the file "D:\workspace\global\build-beandoc.xml" and how are you invoking the Ant tasks?). Also not entirely clear is whether this error occurs running or building beandoc.

The error occurs while running BeanDoc, building worked after I removed the forkmode="perBatch" option of the <junit> task (don't know why this isn't available in my ant).

Here's the content of "D:\workspace\global\build-beandoc.xml" and beandoc.properties:

  • build-beandoc.xml:
    <project name="global" default="beandoc">
      <path id="beandoc-classpath">
        <fileset dir="lib/beandoc-0.4/lib">
          <include name="spring-beandoc.jar"/>
        </fileset>
        <fileset dir="lib/spring-1.1.4/lib">
          <include name="spring.jar"/>
        </fileset>
        <fileset dir="lib/commons-logging-1.0.3">
          <include name="commons-logging.jar"/>
        </fileset>
      </path>
    
      <taskdef name="beandoc" classname="org.springframework.beandoc.client.AntTask">
        <classpath refid="beandoc-classpath"/>
      </taskdef>
    
      <path id="input.files.path">
        <fileset dir="..">
          <include name="*/conf/classpath/*-context.xml"/>
          <exclude name="*/conf/classpath/test-*-context.xml"/>
        </fileset>
      </path>
    
      <pathconvert pathsep="," property="input.files" refid="input.files.path"/>
      <pathconvert pathsep="," property="beandoc.classpath" refid="beandoc-classpath"/>
    
      <target name="beandoc">
        <echo message="input.files = ${input.files}"/>
        <echo message="beandoc.classpath = ${beandoc.classpath}"/>
        <beandoc
          inputFiles="${input.files}"
          outputDir="beandoc"
          beandocProps="beandoc/beandoc.properties"/>
      </target>
    </project>
    
  • beandoc.properties
    compiler.dotExe=D:/Programme/ATT/Graphviz/bin/dot.exe
    

is it possible for you to verify that the samples from the default beandoc download work under the IBM JDK? If not, do they work for you under a Sun JDK? We need to eliminate these possibilities first.

Cheers.

Sun JDK is exactly the same. But it only appears from within a Cygwin bash - in a "normal" windows shell it works perfectly. Probably some environment variable that's set different. If I can figure it out, I'll send another comment.

Thanks!

Felix

I just committed a change to graph <lookup-method> tags as dependencies.

re: merging ProxyFactory beans and their targets. This is potentially quite tricky to do just for the graphing output. It may be easier to merge them before any transformation occurs but then the HTML docs will show the target as an inner bean rather than a referenceable bean which may not be what you want. What do you think?

There's now code committed to permit merging beans according to entries in beandoc.properties For example, the following entry;

# use a regex Map key to specify the proxy beans and
# a value that is the target property (ie 'target')
processor.mergeProxies[.*Proxy$]=target

would cause the two beans below to be merged in the output;

<bean id="myProxy" class="...">
  <property name="target"><ref local="myTarget"/></property>
</bean>

<bean id="myTarget" class="..."/>

I´m trying to unzip this file, but the winzip say it´s corrupted.

Posted by Anonymous at Mar 04, 2005 06:24

hmm, it works OK for me.. Have you tried saving it to disk and then opening it? It may also work if you just try it again, it may have become damaged during the download.

Beandoc built OK for me too, but running it is another matter - getting "nested exception is java.io.FileNotFoundException: Could not open class path resource [org/springframework/beandoc/client/beandoc.xml]" when trying to run from Ant. I made sure beandoc's jar and its dependancies are in the classpath, confirmed that beandoc.xml is in the jar. Double-checked the Ant task, etc. I'm using Sun's JDK 1.4.2-06 on Windows XP Pro.

Posted by Anonymous at Mar 04, 2005 21:31

does this happen when you run "runbeandoc-ant.bat" from the samples directory too, or does that work?

alternatively, place all the runtime jar's in Ant's /lib folder.

OK, placing the beandoc runtimes in Ant's /lib folder worked - I can now run the ant task and get HTML output. However, none of the graphics are being generated due to missing "map" files...? It says "graphing output probably not configured" but GraphVis is installed and referenced correctly in beandoc.properties. Any ideas? BTW if you unzip the download, the inner tar archive doesn't have a .tar extension - this might confuse some folks. Thanks in advance!

Posted by Anonymous at Mar 05, 2005 14:49

Aha - figured it out! You can't specify an output path that contains spaces. Cool utility - I'll definitely work with it this week.

Posted by Anonymous at Mar 05, 2005 16:55

re: unzipping - are you talking about the beandoc zip or a GraphViz download? The beandoc one is a zip archive rather than a compressed tar - it should just explode the archive into the current directory when you run unzip..

I mean the Beandoc zip - using Winrar it unpacks the initial wrapper into an extension-less file. If you add .tar to that, Winrar is able to subsequently unpack its directory structure. Maybe it's a Winrar thing?

Posted by Anonymous at Mar 07, 2005 07:12

I think it must be WinZip (on 'Doze) and unzip on my *Nix boxes both handle it ok.

That's maybe correct, but neither Winrar nor Winzip will (effortlessly) unpack the archive, and those are the most common tools on Windows. I don't know what to tell you, but you might consider a different packaging method. Anyway, thanks again for this tool - it's very, very cool and even documented my Acegi configuration correctly.

Posted by Anonymous at Mar 07, 2005 08:42

glad to hear the tool's working well for you if not the unzipping of it! I'll generate .tgz files on future releases and see if that helps. Thanks for the feedback.

(Felix's comment below - original removed as code block was throwing page alignment off. Reported as an issue to Atlassian 9 months ago )

I tried the 0.6 release now, but still have some problems:

  • CLI ist working, but the Ant task is not (neither within Cygwin nor within Windows-shell using Sun or IBM JDK). It complaints that it doesn't find the [org/springframework/beandoc/client/beandoc.xml] classpath resource. According to the comment above, I'm not the only one with this problem.
  • if I have the line "processor.mergeProxies[.*Service$]=target" in my beandoc.properties file, it quits working while merging the Proxies. No exception, just the following error. Without the processor.mergeProxies line, everything is fine.

(some code snipped)

INFO: Merging proxy bean [kontoService] and its target bean [kontoServiceTarget]
Unable to run beandoc tool; null

Felix

Posted by Felix von Delius at Mar 09, 2005 03:24


(My response)

hi Felix.
With the Ant issue, how are you invoking Ant? You have to make sure all the runtime deps are available to Ant prior to running it. You can either wrap the ant call in a batch/shell script that sets the classpath or just drop all the runtime jars into $ANT_HOME/lib. That really should fix it.

The proxy problem looks like an old version of the beandoc code - are you certain you don't have a prior jar file on the classpath somewhere? It used to do this if the referenced bean (kontoServiceTarget in your case) wasn't found in the current context.
If that doesn't help, could you send me, or post, a context file showing the bean definitions that cause this error (preferably the smallest possible file that still generates the error) and I'll take a look at it straight away for you.

Cheers.

I'd really like to try the product but only have winzip. Could you please generate a winzip compatible format?

Posted by Anonymous at Mar 09, 2005 06:34

the zipfile attached should work - it works for me in winzip..? I'll recreate it shortly in case it's damaged.

> With the Ant issue, how are you invoking Ant? You have to make sure all the runtime deps are
> available to Ant prior to running it. You can either wrap the ant call in a batch/shell script
> that sets the classpath or just drop all the runtime jars into $ANT_HOME/lib. That really should
> fix it.

That was the reason, after creating a script, now it starts perfectly!

> The proxy problem looks like an old version of the beandoc code - are you certain you don't
> have a prior jar file on the classpath somewhere?

I am, since I introduced debugging statements in the code that appear

> If that doesn't help, could you send me, or post, a context file showing the bean definitions
> that cause this error (preferably the smallest possible file)

This is the shortest I can serve with:

<?xml version="1.0" encoding="ISO-8859-1"?>

<beans>
  <bean id="cacheComponent" class="it.is.anonymized.common.cache.EhCacheManagerImpl">
    <constructor-arg>
      <list>
        <bean class="it.is.anonymized.common.cache.EhCacheImpl">
            <constructor-arg index="0"><value>Mitarbeiter</value></constructor-arg>
        </bean>
      </list>
    </constructor-arg>
  </bean>

  <bean id="foobarManager" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="interceptorNames">
      <list>
      </list>
    </property>
    <property name="target"><ref bean="foobarManagerTarget"/></property>
  </bean>

  <bean id="foobarManagerTarget" class="it.is.anonymized.manager.foobar.SchriftstueckManagerImpl"/>
</beans>

It throws a NullPointerException with 0.6 here. It you comment out the "cacheComponent" definition, it works.

Cheers
Felix

Felix, I can't replicate this at all. It works for me locally using the exact file you posted above, completes OK and merges the proxy without error. I also tried d'loading the zip file from here and installing/building/running from scratch on the same file and that worked too. I don't really know what to suggest here

The problem is perfectly reproduceable here with both, SUN and IBM VM (on Windows XP). Probably for some strange reasons, it doesn't appear on Linux? I'll try parsing the stuff on my Gentoo-Linux setup at home on the weekend, but here I have only access to M$-WinXP

I tracked the problem down to be caused by an anonymous inner class ("cacheComponent" in the example context above). There seem to be two points where the NullPointerException is thrown.

1. In DefaultContextProcessor#mergeProxiesInContextDocs(): The "String[] testForMatches" is initialized with null as first element which is passed to PatternMatcher.matchPatterns().

2. In DefaultContextProcessor#getBeanElement(): the condition "(getBeanIdentifier(targetBean).equals(refId))" is null for the anonymous bean.

Here's a patch for the two places:

In DefaultContextProcessor#mergeProxiesInContextDocs() replace

String[] testForMatches = {idOrName, className};

with

String[] testForMatches = idOrName == null ? new String[] {className} : new String[] {idOrName, className};

In DefaultContextProcessor#getBeanElement() replace

if (getBeanIdentifier(targetBean).equals(refId))

with

final String beanIdentifier = getBeanIdentifier(targetBean);
if (beanIdentifier != null && beanIdentifier.equals(refId))

With this patch, BeanDoc processes the file here without Exception.

Cheers,
Felix

I realized yesterday with my (much longer) context files, that the NullPointerException didn't always happen on the same bean (without modifying anything between two runs!!). I have no clue where this nondeterministic behaviour comes from, but probably it's for the same reason why you can't reproduce the Exception with the short example context I posted above.

Cheers,
Felix

regarding the nulls in PatternMatcher methods, the code already handles null elements in either the collection of String patterns that the Pattern[] is generated from, or the String[] containing test Strings. This should never throw an NPE - check the unit tests for the PatternMatcher class.

The other one is valid since getBeanIdentifier() can return null. I'll fix this and commit tests shortly.

Also, if you use Gentoo (as I do!) you may have a lot of problems with Ant depending on how you installed it. If you emerged it, it's broken and the beandoc code triggers a bizarre ClassCastException when attempting to get the ContextProcessor bean from the bean factory. Probably due to compilation bugs (doesn't it use gcj or something?). I emerged -C ALL of my Ant stuff and just unzipped a binary download into /opt, setting ANT_HOME in /etc/profile, and have had no problems since.

Thanks for your continuing help and feedback!

> regarding the nulls in PatternMatcher methods, the code already handles null elements in
> either the collection of String patterns

You're right, BeanDoc works without the first patch. It was a log-statement that I introduced myself in the PatternMatcher, that caused the NPE...

> if you use Gentoo (as I do!) you may have a lot of problems with Ant

Thanks for the hint. Up to now, I didn't have any problems with my Ant setup.

> Probably due to compilation bugs (doesn't it use gcj or something?).

I also realized, that some packages do not build correctly sometimes, especially when you switched your java-config in the meantime. But usually re-emerging helps (last time I had this with hibernate).

> Thanks for your continuing help and feedback!

I back your pardon, BeanDoc is big help for Spring projects!!

Cheers,
Felix

PS: isn't it time to open a JIRA category for BeanDoc? (or is there already one? )

Darren, I just wantet to let You know, that BeanDoc works perfectly on my Gentoo-Linux. The NPE Exception is reproduceable with the small context file I posted, but it is fixed in the latest CVS snapshot.

>I back your pardon, BeanDoc is big help for Spring projects!!
Oops, I guess I mixed up the phrases. Should read "You're welcome"... sorry from a non-native-speaker !

Felix

Posted by Anonymous at Mar 11, 2005 02:16

Glad it's working now

I asked Juergen about a JIRA category for BeanDoc, but given the low volume of stuff that would go in it, he may decide not to set one up. We'll see what he says. May be better to just use the user mailing list or one of the forums in future.

The download of the ZIP file using IE seems to be broken, try FlashGet or another d/l-manager to get the file correctly. Might as well be a Confluence problem.

Posted by Anonymous at Mar 21, 2005 07:02

Hi,
great tool, and really useful for managing extensive bean contexts...
One thing I noticed: a bean property may have <description> tags as well. This description is shown in the html generated by docbeans, but the actual value or reference is just appended to the description, e.g.

<property name="highRatingLimit">
<description>an upper threshold for qualifying matching results</description>
<value>0.7</value>
</property>

is rendered to:

highRatingLimit an upper threshold for qualifying matching results 0.7

A line break or extra column containing the comment would help. Same thing is true for constructor-args.

cheers
Christian

Posted by Anonymous at Mar 23, 2005 06:45

Thanks for the heads-up. I'll make it handle all the description nodes properly over the weekend

Thanks Darren,
looks a lot better now!

Christian

Posted by Anonymous at Mar 30, 2005 02:24

In order to enable the Ant task to read resources from the classpath that was used to load the task itself from (i.e. the classpath specified in the taskdef), you should make the following changes in the execute() method:

public void execute() throws BuildException {

ClassLoader sysClassLoader = Thread.currentThread().getContextClassLoader();
AntClassLoader newClassLoader = new AntClassLoader(getClass().getClassLoader(), true);

Thread.currentThread().setContextClassLoader(newClassLoader);

try

Unknown macro: { BeanFactory factory = SpringLoader.getBeanFactory( new SpringLoaderCommand( inputFiles, (outputDir != null ) ? outputDir.getAbsolutePath() }
catch (Exception e)
Unknown macro: { throw new BuildException(e); }

finally

Unknown macro: { // rollback of theclassloader change Thread.currentThread().setContextClassLoader(sysClassLoader); }

}

The main reason for this is that Ant does not register the taskdef's classloader at the current thread, thus its entries are not available for e.g. spring, which leads to the famous FileNotFoundException.

Tom

Ups, seems like JIRA doesn't like the code too much (should have used preview and the formatting guide). Here the code again:

org.springframework.beandoc.client.AntTask
public void execute() throws BuildException {           

        ClassLoader    sysClassLoader = Thread.currentThread().getContextClassLoader();
        AntClassLoader newClassLoader = new AntClassLoader(getClass().getClassLoader(), true);

        Thread.currentThread().setContextClassLoader(newClassLoader);

        try {            
            BeanFactory factory = 
                SpringLoader.getBeanFactory(
                    new SpringLoaderCommand(
                        inputFiles, 
                        (outputDir != null ) ? outputDir.getAbsolutePath() : null, 
                        title,
                        (beandocProps != null ) ? beandocProps.getAbsolutePath() : null,
                        (beandocPropsPrefix != null ) ? beandocPropsPrefix : null,                        
                        beandocContext
                    )
                );

            ContextProcessor cp = (ContextProcessor) factory.getBean("processor");
            cp.process();
            
        } catch (Exception e) {
            throw new BuildException(e);
        }
        finally
        {
            // rollback of our classloader change
            Thread.currentThread().setContextClassLoader(sysClassLoader);
        }
    }

Beandoc quits when it encounters <import resource="B.xml"/> within A.xml.

The error given is Unable to parse or validate input resource [A.xml]

Posted by Anonymous at Apr 08, 2005 11:35

Would it be possible to use Grappa instead of GraphViz ?
http://www.research.att.com/~john/Grappa/

From the Home page:

Grappa can be thought of as a port of a subset of GraphViz to Java.

That way, it could be possible to not depend on an external non java program which limits portability and transparent usage.

The main question is:

Is the subset of GraphViz that Grappa implements enough to generate Beandoc graphs ?

An alternate question that is relevant only to maven-beandoc-plugin is

Does the Grappa licence allows the Grappa libraries to be uploaded on a repository such as ibiblio.org in order to be transparently integrated into Maven ?

BTW, I almost forgot: Beandoc is a kickass program
I personally use it through maven-beandoc-plugin

Cédric Vidal

Posted by Anonymous at Apr 10, 2005 12:20

Tom, thanks for the Ant comments, I'll take a look at adding that in.

Re: the <import/> tag. This is one of the things never implemented (I'm sure it used to be on the TODO list page actually, but it's gone now for some reason).

This is definitely to be added soon. Thanks.

Cédric, I looked at Grappa initially since a Java lib would certainly be preferable to an external program. The problem is that I simply couldn't make it work and the documentation was extremely scant. It seemed to be concentrating more on its function as a UI builder (sort of drag'n'drop canvas for generating .dot files).

If you've used it and know a bit more about it I'd be delighted to hear from you. Drop a mail to the dev mail list or post in the forums (comments on here are a bit unweildy!)

Thanks for your comments!

No, sadly, I haven't used it, it's just that I loved the beandoc concept (it gave me some crazy ideas !! ), played with GraphViz (which is amazing) and eventually found Grappa which happened to describe itself as a GraphViz java port (ported by the same lab too), which made me post that comment

Sorry for the false hope, I'll give it a try though !

If I remember correctly, someone else had this issue earlier and it was due to spaces in the directory names on a Windows platform. There are a lot of uncommitted changes to beandoc that I have locally, one of which should fix this problem I think, but for now you need to use an output location with no spaces in the directory names.

Let me know if you're still having trouble (preferably via the Spring forums as comments on here are a bit unweildy and difficult to follow!)

Many thanks,
Darren.

Hi Darren,
You were right: it was due to the spaces in the output dir name. With a output dir without spaces it's working like a breeze.

Thanks!
Steven Sagaert

Posted by Anonymous at May 13, 2005 04:19

Hello Darren,
Do you know if anyone is working on the TODO to make BeanDoc work with <import/> tags?
Regards,
Rune Schürmann

Posted by Anonymous at May 24, 2005 02:27

hi Rune,

no not yet. I've unfortunately had almost no time to do anything in the last two months. I'm hoping to be able to commit a few fixes and changes in the next couple of weeks, I'll have a look to see what's involved for imports in the meantime.

Cheers,

Site running on a free Atlassian Confluence Open Source Project License granted to Spring Framework. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.5 Build:#811 Jul 25, 2007) - Bug/feature request - Contact Administrators