[xmlc] any BCEL (or otherwise bytecode) experts out there? Can't figure something out...
Jacob Kjome <[email protected]> Sun, 24 Jul 2005 00:58:04 -0500
| Newsgroups | gmane.comp.java.enhydra.xmlc |
|---|---|
| Message-ID | <[email protected]> |
Turns out that since I turned on URL Rewriting to test my
OutputOptions.set/getURLRewiteAttributes() addition, I have only been using
the DynamicMLCreatorASM2Impl class which seems to work in all
cases. However, I'm now testing fallback to DynamicMLCreatorBCELImpl and
it doesn't seem to work properly (this means when using dynamic loading,
which is the case in which the DynamicMLCreator implementations are
used). When URL Rewriting is on, the BaseDOMFormatter checks whether the
current attribute is a URL rewrite attribute. If this has not been
specified in OutputOptions, it asks the XMLObject implementation for the
information. This, in turn, asks the dom factory implementation if the
current attribute is a URL rewrite attribute. The getDomFactory() method
is used to get the dom factory. It returns a static reference to the dom
factory which is set up something like this...
private static final org.enhydra.xml.xmlc.dom.XMLCDomFactory fDOMFactory =
org.enhydra.xml.xmlc.dom.XMLCDomFactoryCache.getFactory(org.enhydra.xml.xhtml.XHTMLDomFactory.class);
Now, to the point. When using the ASM2 impl of DynamicMLCreator,
XMLCDomFactoryCache.getFactory() gets called when the XMLObject
implementation is loaded. However, when using the BCEL version, the
getFactory() method is never called (I added some debugging code to see
when it was getting called). Therefore, the "fDOMFactory" static variable
is null and XMLObjectImpl.getDomFactory(), therefore, returns null causing
a NullPointerException. The thing is, the getFactory() call seems to be
defined in both the ASM2 and BCEL DynamicMLCreator implementations. Its
just that only the ASM2 one creates a class that makes a successful call to
getFactory(). Here's the stack trace I get (slightly modified version of
the Preview servlet, so don't let the line number there throw you for a
loop. Everything else should be the same as what you'd get in your own
testing)...
java.lang.NullPointerException
at org.enhydra.xml.xmlc.XMLObjectImpl.isURLAttribute(XMLObjectImpl.java:797)
at
org.enhydra.xml.io.BaseDOMFormatter.isURLRewriteAttribute(BaseDOMFormatter.java:699)
at
org.enhydra.xml.io.BaseDOMFormatter.writeAttributeValue(BaseDOMFormatter.java:638)
at org.enhydra.xml.io.XMLFormatter.handleAttr(XMLFormatter.java:232)
at org.enhydra.xml.dom.DOMTraversal.processAttr(DOMTraversal.java:410)
at org.enhydra.xml.dom.DOMTraversal.processNode(DOMTraversal.java:367)
at
org.enhydra.xml.dom.DOMTraversal.processAttrsUnsorted(DOMTraversal.java:333)
at org.enhydra.xml.dom.DOMTraversal.processAttributes(DOMTraversal.java:284)
at org.enhydra.xml.io.XMLFormatter.writeOpenTag(XMLFormatter.java:262)
at org.enhydra.xml.io.XMLFormatter.handleElement(XMLFormatter.java:296)
at org.enhydra.xml.dom.DOMTraversal.processNode(DOMTraversal.java:370)
at org.enhydra.xml.dom.DOMTraversal.processChildren(DOMTraversal.java:268)
at org.enhydra.xml.io.XMLFormatter.handleDocument(XMLFormatter.java:166)
at org.enhydra.xml.dom.DOMTraversal.processNode(DOMTraversal.java:358)
at org.enhydra.xml.dom.DOMTraversal.traverse(DOMTraversal.java:243)
at org.enhydra.xml.io.BaseDOMFormatter.write(BaseDOMFormatter.java:746)
at org.enhydra.xml.io.DOMFormatter.write(DOMFormatter.java:205)
at org.enhydra.xml.io.DOMFormatter.toBytes(DOMFormatter.java:184)
at
org.enhydra.xml.xmlc.servlet.XMLCContext.outputDocument(XMLCContext.java:412)
at org.enhydra.xml.xmlc.servlet.XMLCContext.writeDOM(XMLCContext.java:503)
at xmlc.demo.Preview.service(Preview.java:38)
Both of these DynamicMLCreator implementations were generated based off
existing XMLC compiled classes and then modified to do exactly what we
wanted. My overall knowledge of this bytecode stuff is minimal. So, is
there anyone out there that can interpret the DynamicMLCreatorBCELImpl and
tell me why the getFactory() call is not being made at runtime? If you
can, a patch to fix the issue would be very helpful. This is the last
thing I need to do before the 2.2.7 release. I think we need fallback to
BCEL for environments that can't use ASM2 because it conflicts with
ASM1.x.x which a number of applications still use.
To test, just turn on URL Rewriting, set the following context param in
web.xml (make sure to also set up reparse resource dirs and other such
context params. For an example, see the Tomcat example app. In fact, the
Tomcat app can be used for testing since it is mostly pretty much set to go)...
<context-param>
<param-name>xmlcSessionURLEncoding</param-name>
<param-value>always</param-value>
<description> </description>
</context-param>
...And then in your servlet, use the XMLCContext to load up the XMLCFactory...
XMLCContext context = XMLCContext.getContext(this);
XMLCFactory factory = context.getXMLCFactory();
//cast to a deferred parsing factory...
XMLCDeferredParsingFactory dpFactory = null;
if (factory instanceof XMLCDeferredParsingFactory) {
dpFactory = (XMLCDeferredParsingFactory)factory;
}
//dynamically load up the file
XMLObject xmlObj = dpFactory.createFromFile(path);
//write to the response. Within this call is where the
NulPointerException is being thrown
//when using the BCEL DynamicMLCreator implementation
context.writeDOM(req, resp, xmlObj);
I've committed a preliminary change to DynamicClassLoader to allow for
fallback to BCEL when ASM2 is not found in the classpath. So, when you
test this, make sure to remove ASM2 from the classpath. ASM2 is used in
preference to BCEL if both exist in the classpath. If anyone can help me
out here, it would be much appreciated!
thanks,
Jake
message-footer.txt
(text/plain, 269 B)
-- You receive this message as a subscriber of the [email protected] mailing list. To unsubscribe: mailto:[email protected] For general help: mailto:[email protected]?subject=help ObjectWeb mailing lists service home page: http://www.objectweb.org/wws