Christine Li wrote:
Plugin runtime environment. When I tested CompiledApplet sample, I got
java.lang.IllegalAccessError: class
org.apache.xalan.xsltc.dom.SAXImpl$TypedNamespaceIterator cannot access its
^^^^^
XSLTC has not covered by Generalized ClassLoading patch because it has own tricks with classloading which I doesn't yet understand enough...


But in your case it seems that you just have incompatible classes, i.e. new xsltc classes (which is not in JVM's rt.jar) with old Xalan classes (which is in rt.jar).

superclass org.apache.xml.dtm.ref.DTMDefaultBaseIterators$NamespaceIterator
Cause of an old version of Xalan is bundled with Sun JDK 1.4.*. Using the
"Endorsed Standards Override Mechanism", I copied a newer version of
Xalan.jar in the /lib/endorsed directory. The story starts from here,

This should solve java.lang.IllegalAccessError problem... Isn't it?


Referring back to previous discussions about  Xalan generalized
ClassLoading Mechanism.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16675
I modified the code and use the ObjectFactory class to load the translet
class in org.apache.xalan.xsltc.trax.TransformerFactoryImpl .

The very first time, I access my applet from IE. According to the Applet
lifecycle, its init() and start() methods are invoked by the JVM. The
getContextClassLoader() returns sun.plugin.security.PluginClassLoader and
the getSystemClassLoader() returns sun.misc.Launcher$AppClassLoader. The
ObjectFactory.findClassLoader() method will return
sun.plugin.security.PluginClassLoader as the class loader to load the
translet class. The translet class is in a jar file which specified in the
applet archive attribute. I get the right result.

As expected!


Subsequently, I click "Run" in the menu.html which uses Javascript to call
the transform() method of my applet. It is where I get
javax.xml.transform.TransformerConfigurationException: Cannot find class
****

This time, the getContextClassLoader() returns null, cause the applet
lifecycle methods (init, start, stop, destroy) and the transform() method
are running in different threads. The contextclassloader for transform()
method has no knowledge about the classes were loaded from the codebase or
archive. In this case, ObjectFactory.class.getClassLoader() in
ObjectFactory.findClassLoader() returns null too, cause of the xalan.jar in
the endorsed directory is loaded by the bootstrap class loader. So the
systemClassLoader ( sun.misc.Launcher$AppClassLoader) is returned. Of
cause, it has no information about my translet class. Then the
ObjectFactory.findProviderClass() method uses the fallback and tries to
load translet class by using Class.forName(classname) . It tries to load
the translet class from the current loader which is null.

As expected too!!! In any point of time you have access only to three classloaders: current, context and system. If no one points to your classes then you can't load it at all!


Now, you can tell why I got Cannot find class error. My questions are:
1. Did I use the right way to replace the bundled xalan ?

yes


2. Is there any way that I can get the right ContextClassLoader from
Applets. (without using setContextClassLoader)

in short - no


You can only ask SUN to fix their Java Plugin so it would set correct context classloader when applet is called from javascript...

I could recommend you to cache context classloader init init() call and then set it when applet is called from javascript. Or run another utility thread from init() (context classloader inherited by children threads) and use technique used in SwingUtil.invokeLater() and SwingUtil.invokeAndWait()...

3. Is ObjectFactory sophisticated enough?

It tries to do its best from information it could get from JVM... If you know the way it could do its job even better please tell us!



Reply via email to