^^^^^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!
