javaapache-flexmxmlmxmlc

Why does Java to throw IllegalAccessError when invoking mxmlc?


I invoke the Flex mxmlc compiler from a Java application. After adding the Xerces parser to the project classpath I get the error below.

java.lang.IllegalAccessError: class org.apache.xerces.util.XMLAttributesMMImpl$AttributeMMImpl cannot access its superclass org.apache.xerces.util.XMLAttributesImpl$Attribute
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerMMImpl.<init>(XMLDocumentFragmentScannerMMImpl.java:254)
    at org.apache.xerces.impl.XMLDocumentScannerMMImpl.<init>(XMLDocumentScannerMMImpl.java:238)
    at org.apache.xerces.impl.XMLNSDocumentScannerMMImpl.<init>(XMLNSDocumentScannerMMImpl.java:75)
    at org.apache.xerces.parsers.XML11ConfigurationMMImpl.<init>(XML11ConfigurationMMImpl.java:562)
    at org.apache.xerces.parsers.XML11ConfigurationMMImpl.<init>(XML11ConfigurationMMImpl.java:409)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at java.lang.Class.newInstance0(Class.java:355)
    at java.lang.Class.newInstance(Class.java:308)
    at org.apache.xerces.parsers.ObjectFactory.newInstance(Unknown Source)
    at org.apache.xerces.parsers.ObjectFactory.findJarServiceProvider(Unknown Source)
    at org.apache.xerces.parsers.ObjectFactory.createObject(Unknown Source)
    at org.apache.xerces.parsers.ObjectFactory.createObject(Unknown Source)
    at org.apache.xerces.parsers.SAXParser.<init>(Unknown Source)
    at org.apache.xerces.parsers.SAXParser.<init>(Unknown Source)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at java.lang.Class.newInstance0(Class.java:355)
    at java.lang.Class.newInstance(Class.java:308)
    at org.xml.sax.helpers.NewInstance.newInstance(NewInstance.java:51)
    at org.xml.sax.helpers.XMLReaderFactory.loadClass(XMLReaderFactory.java:187)
    at org.xml.sax.helpers.XMLReaderFactory.createXMLReader(XMLReaderFactory.java:180)
    at org.jdom.input.SAXBuilder.createParser(SAXBuilder.java:641)
    at org.jdom.input.SAXBuilder.build(SAXBuilder.java:489)
    at org.jdom.input.SAXBuilder.build(SAXBuilder.java:865)

Solution

  • The Flex SDK includes a customized version of the Xerces parser (lib/xercesPatch.jar). The custom classes all end in MM (for Macromedia). AFAICT, the parser was customized to associate line numbers with parsed attributes.

    In my case, the problem was caused by making the the application classloader the parent of the classloader which handled the Flex SDK libraries. I have Xerces in the application classpath; Xerces is also in the Flex SDK classpath. The MM parser classes are loaded by the flexSdkClassLoader because they are uniquely named. However, the parser base classes are being found by the application classloader (parhaps they were already loaded).

    The fix was to use the bootstrap classloader as the parent of the flexSdkClassLoader:

    List<URL> flexSdkJars = ...; 
    URLClassLoader flexSdkClassLoader = new URLClassLoader(flexSdkJars.toArray(new URL[flexSdkJars.size()]), String.class.getClassLoader());
    

    The IllegalAccessError also affects some Ant users running the mxmlc task. The workaround for that case is to run the mxmlc task as a separate process via fork="true".