From: Shlomy R. <sre...@gm...> - 2009-10-10 15:43:14
|
Hi, Thanks for the patch. I don't have time to check it myself. Can someone else check and apply it? Thanks, Shlomy On Sat, Oct 10, 2009 at 10:27 AM, Eric Le Lay <ker...@us...> wrote: > Hi, > > a patch is available for review at > https://sourceforge.net/tracker/?func=detail&aid=2876132&group_id=588&atid=300588 > > It builds on what Matthieu did, handling the case where the associated > jar is null. > > > Shlomy Reinstein a écrit : >> Hi, >> >> I didn't bother (and prefer not to) go into this level of detail in >> understanding the JARClassLoader. Can you fix it in SVN, or >> alternatively submit a patch? >> >> Thanks, >> Shlomy >> >> On 10/4/09, Eric Le Lay <ker...@us...> wrote: >>> This is my understanding so far : >>> JARClassLoader caches the name of all available classes from all plugins >>> (each plugin jar uses the XXX.jar.summary to build the list, and then >>> returns them via getClasses()). >>> >>> It associates each class name to the JARClassLoader of the PluginJAR >>> containing it (this is classHash). >>> >>> When JARClassLoader.loadClass() method is invoked, it finds the >>> associated JARClassLoader (if any) and invokes its _loadClass() >>> method. >>> >>> in _loadClass(), the corresponding plugin is activated and the wanted >>> class is finally loaded. >>> >>> So one has access to all the classes one wants, from any JARClassLoader. >>> This is brilliant ! >>> >>> JARClassLoader is not used at the begining, so the default class loader >>> in the Beanshell console is the Application class loader. >>> >>> see : >>> Beanshell> Class.forName("xml.XmlPlugin") >>> java.lang.ClassNotFoundException: xml.XmlPlugin >>> at java.net.URLClassLoader$1.run(URLClassLoader.java:200) >>> at java.security.AccessController.doPrivileged(Native Method) >>> at java.net.URLClassLoader.findClass(URLClassLoader.java:188) >>> at java.lang.ClassLoader.loadClass(ClassLoader.java:306) >>> at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268) >>> >>> However, the context class loader for the AWT thread is a JARClassLoader >>> (how comes ? I don't know): >>> BeanShell> Thread.currentThread() >>> Thread[AWT-EventQueue-0,6,main] >>> BeanShell> Thread.currentThread().getContextClassLoader().getClass() >>> class org.gjt.sp.jedit.JARClassLoader >>> BeanShell> >>> Thread.currentThread().getContextClassLoader().loadClass("xml.XmlPlugin") >>> class xml.XmlPlugin >>> >>> >>> Now I have a new problem : When I run the tests for XmlPlugin, I get >>> almost the same error as Alan, but in SAXParserFactory.newInstance(), >>> not DocumentBuilderFactory.newInstance(). >>> >>> The culprit seems to be JARClassLoader.getResourceAsStream() not playing >>> nicely with service providers discovery : >>> >>> SaxParserFactory calls FactoryFinder to find the implementation class. >>> >>> FactoryFinder looks for resources names >>> META-INF/services/javax.xml.parsers.SAXParserFactory, first via the >>> current thread's ClassLoader, then via ClassLoader.getSystemResource(). >>> >>> JARClassLoader.getResourceAsStream() always returns null if the >>> JARClassLoader is not associated with a jar. >>> This is the case of the JARClassLoader in the AWT thread. >>> So FactoryFinder falls back to ClassLoader.getSystemResource(), which >>> finds the resource in xercesImpl.jar. >>> >>> FactoryFinder reads it, finds the name of the class to load, but since >>> the current class loader failed, uses the Bootstrap class loader, which >>> doesn't load from xercesImpl.jar => A ClassNotFoundException is thrown. >>> >>> How to fix it ? Simply allow anonymous JARClassLoaders to tap into the >>> resourceHash, just like they do for classes. Then, the resource is found >>> by the JARClassLoader, which will be able to load the class. >>> >>> Shlomy Reinstein a écrit : >>>> Not completely sure about the first point below. I think >>>> JARClassLoader caches only loaded classes; when a plugin is loaded / >>>> started, the plugin class is loaded first. If it does not directly >>>> make use of other classes (of the plugin itself) at startup, then the >>>> other plugin classes are not loaded and also not cached (yet) in >>>> JARClassLoader. >>>> I guess, if you caused the other XML plugin classes to be loaded >>>> during startup, then we would not have this problem in MarkerSets. >>>> >>>> But again, I am not sure. >>>> Shlomy >>>> >>>> On Thu, Oct 1, 2009 at 9:56 PM, Eric Le Lay >>>> <ker...@us...> wrote: >>>>> Yes, the issue is resolved, but I would be really insterested in >>>>> understanding why there is this failure... >>>>> >>>>> >From what I have gathered : >>>>> - JARClassLoader caches all possible class names, from all the >>>>> plugin jars, at startup (see PluginJAR.init(), JARClassLoader.classHash). >>>>> - this information is used to load a class provided by any given >>>>> plugin, from any given plugin. >>>>> - It is installed everywhere as the class loader >>>>> - In the beanshell console Class.forName("xml.XmlPlugin") fails, >>>>> even if JARClassLoader.classHash.containsKey("xml.XmlPlugin") returns true >>>>> - the DocumentBuilderFactory uses >>>>> Thread.currentThread().getContextClassLoader() to load the class given >>>>> in the system property, and it fails to find the class. >>>>> >>>>> I'm really puzzled, now ! >>>>> >>>>> >>>>> Alan Ezust a écrit : >>>>>> FYI, I just rolled back the change in SVN so that I no longer get this >>>>>> exception, so from my point of view, the issue is resolved (I can >>>>>> start up jEdit and XML works), but it would be nice if we could find >>>>>> out what a better solution to this problem is. >>>>>> >>>>>> I am sending a copy of this to jedit-devel because I think it belongs >>>>>> on the whole list. >>>>>> Please in the future, when discussing JarClassLoader issues and other >>>>>> very technical XML plugin issues such as this, please also include the >>>>>> -devel list. >>>>>> >>>>>> On Wed, Sep 30, 2009 at 11:54 AM, Shlomy Reinstein <sre...@gm... >>>>>> <mailto:sre...@gm...>> wrote: >>>>>> >>>>>> I don't know exactly how it works, but I don't think it's the class >>>>>> hash that matters here. Seems to me like XML starts first, but only >>>>>> some of the classes are loaded (maybe only the plugin class). However, >>>>>> the XML startup registers some XML parser classes to be used later by >>>>>> some java classes (that's what the setting of the system properties >>>>>> does). >>>>>> Later, MarkerSets start, and it tries to read the XML using the java >>>>>> classes. The java classes in turn try to load the necessary classes of >>>>>> the XML plugin, but fails to do so because it's in the context of >>>>>> another plugin JAR. >>>>>> I think Matthieu should be able to provide more details on this, as he >>>>>> made some changes to the PluginJAR or to JARClassLoader some time ago >>>>>> in order to allow plugins to find resources in non-plugin jars they >>>>>> depend on. >>>>>> >>>>>> Matthieu, am I correct? Can you explain this? >>>>>> >>>>>> Thanks, >>>>>> Shlomy >>>>>> >>>>>> On Wed, Sep 30, 2009 at 7:29 PM, Eric Le Lay >>>>>> <ker...@us... >>>>>> <mailto:ker...@us...>> wrote: >>>>>> > Hi Shlomy, >>>>>> > >>>>>> > then how can a plugin find classes from a plugin it depends on (e.g. >>>>>> > XmlPlugin find the Console ErrorSource classes) ? >>>>>> > I don't understand the code in JARClassLoader : isn't the >>>>>> classHash a >>>>>> > static member, which makes it accessible to all instances of >>>>>> > JARClassLoader ? >>>>>> > >>>>>> > >>>>>> > Alan Ezust a écrit : >>>>>> >> >>>>>> >> >>>>>> >> ---------- Forwarded message ---------- >>>>>> >> From: *Shlomy Reinstein* <sre...@gm... >>>>>> <mailto:sre...@gm...> <mailto:sre...@gm... >>>>>> <mailto:sre...@gm...>>> >>>>>> >> Date: Wed, Sep 30, 2009 at 7:17 AM >>>>>> >> Subject: Re: javax.xml.parsers.FactoryConfigurationError: >>>>>> MarkerSets + >>>>>> >> XML plugin >>>>>> >> To: Alan Ezust <ala...@gm... >>>>>> <mailto:ala...@gm...> <mailto:ala...@gm... >>>>>> <mailto:ala...@gm...>>> >>>>>> >> >>>>>> >> >>>>>> >> Well then, now you know where it comes from... The problem is, in >>>>>> >> jEdit each plugin has its own jar class loader, which does not know >>>>>> >> the other jars. Some time ago Matthieu did some work on this, >>>>>> so that >>>>>> >> MyDoggyPlugin could find the resource files of MyDoggy, but in >>>>>> general >>>>>> >> each plugin can only see itself. So if one plugin modifies some >>>>>> system >>>>>> >> properties to cause java internal classes to instantiate classes of >>>>>> >> its own, then another plugin that gets to instantiate them >>>>>> might not >>>>>> >> find them. >>>>>> >> >>>>>> >> Shlomy >>>>>> >> >>>>>> >> On Wed, Sep 30, 2009 at 4:06 PM, Alan Ezust >>>>>> <ala...@gm... <mailto:ala...@gm...> >>>>>> >> <mailto:ala...@gm... <mailto:ala...@gm...>>> wrote: >>>>>> >>> this is the reply eric sent me privately not to the list. >>>>>> >>> >>>>>> >>> >>>>>> >>> ---------- Forwarded message ---------- >>>>>> >>> From: Eric Le Lay <ker...@us... >>>>>> <mailto:ker...@us...> >>>>>> >> <mailto:ker...@us... >>>>>> <mailto:ker...@us...>>> >>>>>> >>> Date: Mon, Sep 28, 2009 at 9:42 AM >>>>>> >>> Subject: Re: javax.xml.parsers.FactoryConfigurationError: >>>>>> MarkerSets + XML >>>>>> >>> plugin >>>>>> >>> To: Alan Ezust <ala...@gm... >>>>>> <mailto:ala...@gm...> <mailto:ala...@gm... >>>>>> <mailto:ala...@gm...>>> >>>>>> >>> >>>>>> >>> >>>>>> >>> Hi Alan, >>>>>> >>> this may have something to do with lines 44-47 of >>>>>> xml/XmlPlugin.java >>>>>> >>> >>>>>> >>> They were commented and I de-commented them to see what happened. >>>>>> >>> Now I see ! >>>>>> >>> >>>>>> >>> Something seems broken with the plugin class loader: >>>>>> >>> org.apache.xerces.jaxp.DocumentBuilderFactoryImpl exists in >>>>>> >>> xercesImpl.jar, so it should be found !!! >>>>>> >>> >>>>>> >>> Alan Ezust a écrit : >>>>>> >>>> Something strange happens on jedit startup when I have the trunk >>>>>> >>>> versions of XML and Markets enabled: >>>>>> >>>> >>>>>> >>>> >>>>>> >>>> javax.xml.parsers.FactoryConfigurationError: Provider >>>>>> >>>> org.apache.xerces.jaxp.DocumentBuilderFactoryImpl not found >>>>>> >>>> at >>>>>> >>>> >>>>>> >>>> >>>>>> >> >>>>>> javax.xml.parsers.DocumentBuilderFactory.newInstance(DocumentBuilderFactory.java:129) >>>>>> >>>> at >>>>>> marker.MarkerSetsPlugin.importXml(MarkerSetsPlugin.java:249) >>>>>> >>>> at >>>>>> marker.MarkerSetsPlugin.loadState(MarkerSetsPlugin.java:93) >>>>>> >>>> at marker.MarkerSetsPlugin.start(MarkerSetsPlugin.java:79) >>>>>> >>>> at >>>>>> org.gjt.sp.jedit.PluginJAR.startPlugin(PluginJAR.java:1391) >>>>>> >>>> at >>>>>> org.gjt.sp.jedit.PluginJAR.activatePlugin(PluginJAR.java:752) >>>>>> >>>> at >>>>>> >>>> >>>>>> org.gjt.sp.jedit.PluginJAR.activatePluginIfNecessary(PluginJAR.java:822) >>>>>> >>>> at org.gjt.sp.jedit.jEdit.main(jEdit.java:482) >>>>>> >>>> >>>>>> >>>> Both plugins fail to start (XML and MarkerSets) but if I >>>>>> unload and >>>>>> >>>> reload them from plugin manager, it seems to be fine again. >>>>>> >>>>>> >>>>>> ------------------------------------------------------------------------ >>>>>> >>>>>> ------------------------------------------------------------------------------ >>>>>> Come build with us! The BlackBerry® Developer Conference in SF, CA >>>>>> is the only developer event you need to attend this year. Jumpstart your >>>>>> developing skills, take BlackBerry mobile applications to market and stay >>>>>> ahead of the curve. Join us from November 9-12, 2009. Register now! >>>>>> http://p.sf.net/sfu/devconf >>>>> ------------------------------------------------------------------------------ >>>>> Come build with us! The BlackBerry® Developer Conference in SF, CA >>>>> is the only developer event you need to attend this year. Jumpstart your >>>>> developing skills, take BlackBerry mobile applications to market and stay >>>>> ahead of the curve. Join us from November 9-12, 2009. Register now! >>>>> http://p.sf.net/sfu/devconf >>>>> -- >>>>> ----------------------------------------------- >>>>> jEdit Developers' List >>>>> jEd...@li... >>>>> https://lists.sourceforge.net/lists/listinfo/jedit-devel >>>>> >>>> >>> >> >> > > |