JDK-6353829 : REGRESSION: ClassCastException with DTMManager when using custom Xalan
  • Type: Bug
  • Component: xml
  • Sub-Component: javax.xml.transform
  • Affected Version: 6
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2005-11-21
  • Updated: 2012-04-25
  • Resolved: 2005-11-30
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b62Fixed
Description
FULL PRODUCT VERSION :
java version "1.6.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-beta-b59)
Java HotSpot(TM) Client VM (build 1.6.0-beta-b59, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
When trying to use a custom version of Apache Xalan and manually specifying the TransformerFactory to use, creation fails with a ClassCastException referring to DTMManager.

The underlying problem is that JDK 1.6 contains the file 'org.apache.xml.dtm.DTMManager' in the META-INF/services directory of resources.jar.  This service file refers to the class 'com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault'.  Unfortunately, all the Xalan classes in the JDK have had their packages mapped from org.apache.... to com.sun.org.apache... which means that when my custom version of Xalan reads this service file it assumes it implements the interface org.apache.xml.dtm.DTMManager when really because of the package mappings it implements com.sun.org.apache.xml.dtm.DTMManager.

I have had no problems using custom versions of Xalan or Xerces with JDK 1.5, in fact I think this is the problem what the package mapping was meant to solve.

A solution would be to rename the service file from
/META-INF/services/org.apache.xml.dtm.DTMManager
to
/META-INF/services/com.sun.org.apache.xml.dtm.DTMManager
and change the code of Xalan that the JDK uses in its distribution to read this service file instead of the default one.  This would ensure that users could use custom versions of Xalan without any problems.



ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.ClassCastException: com.sun.org.apache.xml.
internal.dtm.ref.DTMManagerDefault cannot be cast to org.apache.xml.dtm.DTMManag
er
        at org.apache.xml.dtm.DTMManager.newInstance(DTMManager.java:135)
        at org.apache.xpath.XPathContext.<init>(XPathContext.java:100)
        at org.apache.xalan.transformer.TransformerImpl.<init>(TransformerImpl.j
ava:397)
        at org.apache.xalan.templates.StylesheetRoot.newTransformer(StylesheetRo
ot.java:196)
        at org.apache.xalan.processor.TransformerFactoryImpl.newTransformer(Tran
sformerFactoryImpl.java:782)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.IOException;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.xalan.processor.TransformerFactoryImpl;

public class TestTransform
{
    public static void main(String[] args)
    throws TransformerConfigurationException,
        TransformerException,
        IOException
    {
        //Directly instantiate our own Xalan transformer version
        TransformerFactoryImpl tf = new org.apache.xalan.processor.TransformerFactoryImpl();
		
        Transformer xform = tf.newTransformer(new StreamSource(new File("bin/test.xsl")));
        Source source = new StreamSource(new File("bin/test.xml"));
        Result result = new StreamResult(System.out);
        xform.transform(source, result);
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Set the 'org.apache.xml.dtm.DTMManager' system property to the actual DTMManager implementation class name for the version of Xalan you want to use.

e.g.
System.setProperty("org.apache.xml.dtm.DTMManager", "org.apache.xml.dtm.ref.DTMManagerDefault");

However, setting system properties is not always a good thing to do, e.g. in webapps.

Release Regression From : 5.0
The above release value was the last known release where this 
bug was known to work. Since then there has been a regression.

Comments
EVALUATION the META-INF/services entries were incorrectly added and have been removed.
30-11-2005