Re: [aspectwerkz-user] [patch] DTD error after reload

Alexandru Popescu <[email protected]> Wed, 23 Nov 2005 09:19:24 +0200
Newsgroups gmane.comp.java.aspectwerkz.user
Message-ID <[email protected]>
#: Mattias Jiderhamn changed the world a bit at a time by saying on  11/22/2005 10:41 AM :#
> [Nobody answered this in the dev list, so I'll givet it a try on the user list]
> 
> I believe I have finally tracked down and fixed a problem with 
> reading the DTD file after web application reload. Since long we have 
> experienced now and then that - using online weaving - after the 
> application has been reloaded a couple of times, the XML parser 
> claims the DTD is invalid. Here is an example:
> 
> com.caucho.xml.XmlParseException: 
> <http://aspectwerkz.codehaus.org/dtd/aspectwerkz_2_0.dtd:1>http://aspectwerkz.codehaus.org/dtd/aspectwerkz_2_0.dtd:1: 
> expected '<' at end of file
>          at com.caucho.xml.XmlParser.error(XmlParser.java:2831)
>          at com.caucho.xml.XmlParser.parseDoctypeDecl(XmlParser.java:573)
>          at com.caucho.xml.XmlParser.parseDoctype(XmlParser.java:496)
>          at com.caucho.xml.XmlParser.parseNode(XmlParser.java:386)
>          at com.caucho.xml.XmlParser.parseInt(XmlParser.java:240)
>          at com.caucho.xml.AbstractParser.parse(AbstractParser.java:633)
>          at org.dom4j.io.SAXReader.read(SAXReader.java:339)
>          at org.dom4j.io.SAXReader.read(SAXReader.java:261)
>          at 
> org.codehaus.aspectwerkz.definition.XmlParser.createDocument(XmlParser.java:229) 
> 
> ...
> 
> For long I believed this was a problem with the XML parser, but I 
> have today discovered that this may rather be a bug within 
> AspectWerkz in combination with online weaving and a dynamic class loader.
> 
> The DTD is located within the AW jar file by a static member in 
> org.codehaus.aspectwerkz.definition.XmlParser, namely DTD_STREAM. 
> This (as the name indicates...) is a stream. I believe the problem 
> occurs because when the stream has been read once, it cannot be read 
> again. When the web application is reloaded, the classes need to be 
> re-weaved by AspectWerkz and AspectWerkz tries to parse aop.xml 
> again. It then uses the same stream, since the AW jar is in the 
> bootclasspath rather than the application classpath, and therefore 
> the DTD cannot be read.
> 
> The obvious solution - which seem to work so far - is NOT to store 
> the stream as a static member. Instead we store the URL and 
> instantiate a new stream for every use. Below you will find a patch 
> for this (I could e-mail this as a file).
> 
> What do you guys think? Is my analysis correct, or is this in fact an 
> XML parser issue?
> 

Hi Mattias. It makes sense to me (even if I cannot test it).

./alex
--
.w( the_mindstorm )p.

> 
> Index: src/main/org/codehaus/aspectwerkz/definition/XmlParser.java
> ===================================================================
> RCS file: 
> /home/projects/aspectwerkz/scm/aspectwerkz4/src/main/org/codehaus/aspectwerkz/definition/XmlParser.java,v
> retrieving revision 1.6
> diff -u -r1.6 XmlParser.java
> --- src/main/org/codehaus/aspectwerkz/definition/XmlParser.java 15 
> Dec 2004 23:09:06 -0000      1.6
> +++ src/main/org/codehaus/aspectwerkz/definition/XmlParser.java 11 
> Nov 2005 10:59:24 -0000
> @@ -47,7 +47,7 @@
>       /**
>        * A handler to the DTD stream so that we are only using one 
> file descriptor
>        */
> -    private final static InputStream DTD_STREAM = 
> XmlParser.class.getResourceAsStream("/aspectwerkz2.dtd");
> +    private final static URL DTD_URL = 
> XmlParser.class.getResource("/aspectwerkz2.dtd");
> 
>       /**
>        * The timestamp, holding the last time that the definition was parsed.
> @@ -267,13 +267,15 @@
>           EntityResolver resolver = new EntityResolver() {
>               public InputSource resolveEntity(String publicId, 
> String systemId) {
>                   if (publicId.equals(DTD_PUBLIC_ID) || 
> publicId.equals(DTD_PUBLIC_ID_ALIAS)) {
> -                    InputStream in = DTD_STREAM;
> -                    if (in == null) {
> -                        System.err.println("AspectWerkz - WARN - 
> could not open DTD");
> -                        return new InputSource();
> -                    } else {
> -                        return new InputSource(in);
> +                    try {
> +                        InputStream in = DTD_URL.openStream();
> +                        if (in != null)
> +                            return new InputSource(in);
>                       }
> +                    catch(IOException ioex ) {
> +                    }
> +                    System.err.println("AspectWerkz - WARN - could 
> not open DTD");
> +                    return new InputSource(); // avoid null pointer exception
>                   } else {
>                       System.err.println(
>                               "AspectWerkz - WARN - deprecated DTD "
> 
> 
> 
> 
>    Mattias Jiderhamn  
> 
> 
> 
> 
> !DSPAM:4382da2188611489211947!
>