See below... Donnie
> -----Original Message----- > From: craigmcc@localhost [mailto:craigmcc@localhost]On Behalf Of Craig > R. McClanahan > Sent: Wednesday, December 05, 2001 1:41 AM > To: Jakarta Commons Developers List > Subject: RE: Digester yielding IllegalAccessException in CallMethodRule, > SetNextRule > > > > > On Tue, 4 Dec 2001, Donnie Hale wrote: > > > Date: Tue, 4 Dec 2001 22:44:09 -0500 > > From: Donnie Hale <[EMAIL PROTECTED]> > > Reply-To: Jakarta Commons Developers List > <[EMAIL PROTECTED]> > > To: Jakarta Commons Developers List <[EMAIL PROTECTED]> > > Subject: RE: Digester yielding IllegalAccessException in CallMethodRule, > > SetNextRule > > > > Craig, > > > > Thanks for the prompt response. If I understand your second > case, I tried > > it, and it worked as I wanted: > > > > // Callback.java > > public class Callback implements Reader.WebXmlFileDigestion > > { > > public Callback(Driver d) > > { > > driver_ = d; > > } > > > > public void parseError(Throwable t) throws Exception > > { > > t.printStackTrace(); > > } > > > > public void setServletMapping( > > String servletName, String urlPattern) > > { > > driver_.addServletMapping(servletName, urlPattern); > > } > > > > Driver driver_; > > } > > > > Then, in Driver.java, I used > > > > reader.digestWebXmlFile(new Callback(this)); > > > > instead of passing the anonymous implementing class. > > > > OK, so we know it definitely has something to do with visibility of the > called class. > > > I'll have to see if I have Sun's 1.3 JDK around to try. If not, > it could be > > a while, as I only have IDSL access. :) > > > > One more, related, thing, since you're in the know. > > I better be, since I wrote Digester :-). > > > Is it possible to > > implement an interface with methods which have package scope though the > > interface methods are public? I don't care that some unknown > future entity > > implements the interface; but I don't want the methods in the > implementation > > of it that I care about to be publicly accessible. My copy of > the language > > spec is at work... > > > > I'm sure it's feasible to implement access via reflection (which is what > Digester uses) to methods defined public through an interface - we ran > into a similar case in BeanUtils and solved it be looking up an > appropriate java.lang.reflect.Method object correctly. I'm not sure what > happens when you shadow a package-private method with a public one -- will > have to check on that. However, AFAIK, the class itself has to be public > for any of this to work. Is the requirement of the class being public an artifact of doing this through reflection. If not, I don't understand. As an example, I've got this code in an app: File dir = new File(dirName); String[] fileList = dir.list( new FilenameFilter() { public boolean accept(java.io.File file, java.lang.String name) { return name.toLowerCase().endsWith(fileSuffix); } }); Clearly, the File.list method needs an impl of FilenameFilter on which to make callbacks. I'm providing it one, anonymously. I'm sure, though, that the callback is direct - not via reflection. This works find for me. I guess that's my main source of confusion about the whole thing. > > > Thanks much, > > > > Donnie > > > > Craig > > > > > > -----Original Message----- > > From: craigmcc@localhost [mailto:craigmcc@localhost]On Behalf Of Craig > > R. McClanahan > > Sent: Tuesday, December 04, 2001 10:08 PM > > To: Jakarta Commons Developers List > > Subject: Re: Digester yielding IllegalAccessException in CallMethodRule, > > SetNextRule > > > > > > 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 <[EMAIL PROTECTED]> > > > Reply-To: Jakarta Commons Developers List > <[EMAIL PROTECTED]> > > > To: [EMAIL PROTECTED] > > > 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(XM > LValidator > > > .java:1480) > > > at > > > > > > org.apache.xerces.framework.XMLDocumentScanner$ContentDispatcher.d > ispatch(XM > > > LDocumentScanner.java:1149) > > > at > > > > > > org.apache.xerces.framework.XMLDocumentScanner.parseSome(XMLDocume > ntScanner. > > > 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:[EMAIL PROTECTED]> > > > For additional commands, e-mail: > > <mailto:[EMAIL PROTECTED]> > > > > > > > > > > > > -- > > To unsubscribe, e-mail: > > <mailto:[EMAIL PROTECTED]> > > For additional commands, e-mail: > > <mailto:[EMAIL PROTECTED]> > > > > > > > > -- > > To unsubscribe, e-mail: > <mailto:[EMAIL PROTECTED]> > > For additional commands, e-mail: > <mailto:[EMAIL PROTECTED]> > > > > > > > -- > To unsubscribe, e-mail: > <mailto:[EMAIL PROTECTED]> > For additional commands, e-mail: > <mailto:[EMAIL PROTECTED]> > > -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
