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

Mattias Jiderhamn <mattias.jiderhamn-An/[email protected]> Mon, 21 Nov 2005 13:52:36 +0100
Newsgroups gmane.comp.java.aspectwerkz.devel
Message-ID <[email protected]>
Did anybody have time to look at this patch?

At 2005-11-11 12:04, you wrote:
>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?
>
>
>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