cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Leszek Gawron <>
Subject Re: JXTemplate is broken by implementing Recycable interface
Date Wed, 10 Oct 2007 08:45:01 GMT
Giacomo Pati wrote:
> Hash: SHA1
> Grzegorz Kossakowski wrote:
>> Hi
>> Following Giacomo's comment that Forms samples are broken I tried to run this sample:
>> http://localhost:8888/cocoon-forms-sample/form1.flow (first one in Forms samples)
>> I got following exception:
>> Caused by: java.lang.NullPointerException
>> 	at org.apache.cocoon.template.JXTemplateGenerator.setup(
>> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>> 	at sun.reflect.NativeMethodAccessorImpl.invoke(
>> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(
>> 	at java.lang.reflect.Method.invoke(
>> 	at
>> org.apache.cocoon.core.container.spring.avalon.PoolableProxyHandler.invoke(
>> [...]
>> After taking quick look on this problem I saw that JXTemplateGenerator is broken
by the fact that it
>> implements (indirectly, by extending AbstractXMLProducer) Recycable interface. Implementing
>> interface makes JXTemplateGenerator handled by our Avalon-Spring bridge instead of
pure Spring and
>> treated as an Avalon component.
>> Obviously, if component is treated as an Avalon bean the setter injection will not
work causing NPE
>> I showed above. I'm not sure if it's a bug in our bridge because the situation we
are seeing now is
>> a conflict of two different concepts from two different worlds - singleton beans
of Spring and
>> poolable component of Avalon.
>> Do you have an idea how to fix that? Maybe we should create new AbstractXMLProducer
>> that is free of Avalon interfaces?
> An Avalon-free AbstractXMLProducer might solve these problems for short term migrations
but at the
> end we probably need new concepts (as mentioned by Daniel in a previous mail).

I have been able to fix JXTemplateGenerator without using any superclass 
  at all. I have still some questions though:

1. Can somebody tell me why do we need all these:

protected static final ContentHandler EMPTY_CONTENT_HANDLER = new 

/** The <code>XMLConsumer</code> receiving SAX events. */
protected XMLConsumer xmlConsumer;

/** The <code>ContentHandler</code> receiving SAX events. */
protected ContentHandler contentHandler = EMPTY_CONTENT_HANDLER;

/** The <code>LexicalHandler</code> receiving SAX events. */
protected LexicalHandler lexicalHandler = 

in AbstractXMLProducer?

I might understand why the need for separate lexicalHandler and 
contentHandler. Still why the need for the default value? Why aren't 
they simply null?

  * Set the <code>XMLConsumer</code> that will receive XML data.
  * <br>
  * This method will simply call <code>setContentHandler(consumer)</code>
  * and <code>setLexicalHandler(consumer)</code>.
public void setConsumer(XMLConsumer consumer) {
     this.xmlConsumer = consumer;

It looks like we are fulfilling some really old dependencies here...

2. Look at SitemapModelComponent:

> public interface SitemapModelComponent {
>     /**
>      * The Sitemap will call the setup() method to prepare the component for
>      * use.  This is where you start the process of getting your information
>      * ready to generate your results.  See {@link org.apache.cocoon.environment.ObjectModelHelper}
for help with the <code>objectModel</code>.
>      *
>      * @param resolver     The <code>SourceResolver</code> to find resources
within your context.
>      * @param objectModel  A <code>java.util.Map</code> that contains the
request and session information.
>      * @param src          The value of the "src" attribute in the sitemap.
>      * @param par          The sitemap parameters passed into your component.
>      *
>      * @throws SAXException if there is a problem reading a SAX stream.
>      * @throws IOException  if there is a problem reading files.
>      * @throws ProcessingException if there is any other unexpected problem.
>      */
>     void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)

>     throws ProcessingException, SAXException, IOException;
> }

It looks like we could drop the source resolver and objectModel. Both 
can be injected and AFAIU both are properly scoped with some custom 
scope of ours.

Please review my JXTemplateGenerator migration and recheck if the 
samples work again (worked for me).

Leszek Gawron               
CTO at MobileBox Ltd.

View raw message