Hi Donnie,
IIRC, Digester only knows how to call public methods of public classes --
and an anonymous inner class isn't public.
Could you try two things for me?
* Try this under the Sun JDK just to see if the behavior is different
* Try this where the driver class is a regular public class,
rather than an inner class
That will help us narrow down where the difficulty is.
Craig
On Tue, 4 Dec 2001, Donnie Hale wrote:
> Date: Tue, 4 Dec 2001 22:15:20 -0500
> From: Donnie Hale <donnie@haleonline.net>
> Reply-To: Jakarta Commons Developers List <commons-dev@jakarta.apache.org>
> To: commons-dev@jakarta.apache.org
> Subject: Digester yielding IllegalAccessException in CallMethodRule,
> SetNextRule
>
> I searched the list archives and didn't see anything directly on-topic.
> Sorry if I missed it. Also, this is likely a normal Java issue, but I'm not
> getting it. :(
>
> Here's a very pared down example which reproduces my problem exactly:
>
> // Driver.java
> public class Driver
> {
> public static void main(String[] args)
> {
> try
> {
> Driver driver = new Driver();
> driver.parseWebApp(new Reader());
> }
> catch (Exception e)
> {
> e.printStackTrace();
> }
> }
>
> public void Driver()
> {
> }
>
> public void parseWebApp(Reader reader) throws Exception
> {
> reader.digestWebXmlFile(
> new Reader.WebXmlFileDigestion()
> {
> public void parseError(Throwable t) throws Exception
> {
> t.printStackTrace();
> }
>
> public void setServletMapping(
> String servletName, String urlPattern)
> {
> addServletMapping(servletName, urlPattern);
> }
> }
> );
> }
>
> public void addServletMapping(String servletName, String urlPattern)
> {
> System.out.println("Mapping read: " + servletName + " => " +
> urlPattern);
> }
> }
>
> // Reader.java
> import java.io.InputStream;
> import java.io.IOException;
> import java.net.URL;
> import org.xml.sax.Attributes;
> import org.xml.sax.SAXException;
> import org.apache.commons.digester.Digester;
> import org.apache.commons.digester.Rule;
>
> public class Reader
> {
> public static interface WebXmlFileDigestion
> {
> public void parseError(Throwable t) throws Exception;
>
> public void setServletMapping(String servletName, String
> urlPattern);
> }
>
> public void Reader()
> {
> }
>
> public void digestWebXmlFile(WebXmlFileDigestion callback)
> throws Exception
> {
> // Prepare a Digester to scan the web application deployment
> descriptor
> Digester digester = new Digester();
> digester.push(callback);
> digester.setDebug(1);
> digester.setNamespaceAware(true);
> digester.setValidating(false);
>
> // Register our local copy of the DTDs that we can find
> for (int i = 0; i < registrations_.length; i += 2)
> {
> URL url = this.getClass().getResource(registrations_[i+1]);
> if (url != null)
> {
> digester.register(registrations_[i], url.toString());
> }
> }
>
> // Configure the processing rules that we need
> digester.addCallMethod("web-app/servlet-mapping",
> "setServletMapping", 2);
> digester.addCallParam("web-app/servlet-mapping/servlet-name", 0);
> digester.addCallParam("web-app/servlet-mapping/url-pattern", 1);
>
> InputStream input= null;
> try
> {
> input = this.getClass().getResourceAsStream("web.xml");
> digester.parse(input);
> }
> catch (Throwable e)
> {
> callback.parseError(e);
> }
> finally
> {
> if (input != null)
> {
> input.close();
> }
> }
> }
>
> protected static final String registrations_[] =
> {
> "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",
> "/org/apache/struts/resources/web-app_2_2.dtd",
> "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",
> "/org/apache/struts/resources/web-app_2_3.dtd"
> };
> }
>
> The object on which the method call is to be invoked is an instance of an
> anonymous inner class which implements a public (nested) interface. All the
> methods on the interface and its anonymous implementation are public. All
> the methods on Driver and Reader are public. Yet when I run this, I get:
>
> java.lang.IllegalAccessException: Driver$1
> at java.lang.reflect.Method.invoke(Native Method)
> at
> org.apache.commons.digester.CallMethodRule.end(CallMethodRule.java:308)
> at
> org.apache.commons.digester.Digester.endElement(Digester.java:757)
> at
> org.apache.xerces.parsers.SAXParser.endElement(SAXParser.java:1403)
> at
> org.apache.xerces.validators.common.XMLValidator.callEndElement(XMLValidator
> .java:1480)
> at
> org.apache.xerces.framework.XMLDocumentScanner$ContentDispatcher.dispatch(XM
> LDocumentScanner.java:1149)
> at
> org.apache.xerces.framework.XMLDocumentScanner.parseSome(XMLDocumentScanner.
> java:381)
> at org.apache.xerces.framework.XMLParser.parse(XMLParser.java:1081)
> at org.apache.commons.digester.Digester.parse(Digester.java:1206)
> at Reader.digestWebXmlFile(Reader.java:53)
> at Driver.parseWebApp(Driver.java:23)
> at Driver.main(Driver.java:9)
>
> I'm guessing this has something to do with the "Driver$1" being the
> classname. But it sure seems like I've done stuff like this before, just
> possibly not through reflection. Do I have to go to the extreme of making
> the interface implementation non-anonymous to have any hope of getting this
> to work?
>
> BTW, I'm using IBM's JDK 1.3 on Win2K.
>
> Thanks much,
>
> Donnie
>
>
> --
> To unsubscribe, e-mail: <mailto:commons-dev-unsubscribe@jakarta.apache.org>
> For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>
>
>
--
To unsubscribe, e-mail: <mailto:commons-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>
|