Issue Details (XML | Word | Printable)

Key: GROOVY-2126
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Paul King
Reporter: Matt Kennedy
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
groovy

ClassCastException when using java.util.prefs package

Created: 18/Sep/07 06:07 PM   Updated: 29/Sep/07 05:41 PM   Resolved: 29/Sep/07 05:41 PM
Return to search
Component/s: XML Processing
Affects Version/s: 1.0
Fix Version/s: 1.1-rc-1

Time Tracking:
Not Specified

Environment: tested on Mac OS X 10.4.10 with java version 1.5.0_07 and Fedora Core 5 (2.6.20-1.2320.fc5smp) with java version: 1.5.0_11

Testcase included: yes


 Description  « Hide

The following code throws a java.lang.ClassCastException when run as a Groovy script, the same code compiled with groovyc and executed with java runs correctly.

#prefsTest.groovy
import java.util.prefs.*;
def prefs = Preferences.userNodeForPackage(this.getClass());
prefs.exportSubtree(System.out);
#end prefsTest.groovy

Test using the following:
$ groovy prefsTest.groovy
Caught: java.lang.ClassCastException: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
at prefsTest.run(prefsTest.groovy:4)
at prefsTest.main(prefsTest.groovy)
$groovyc prefsTest.groovy
$java -cp .:$GROOVY_HOME/embeddable/groovy-all-1.0.jar prefsTest
WARNING: Prefs file removed in background /home/mkennedy/.java/.userPrefs/<unnamed>/prefs.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd">
<preferences EXTERNAL_XML_VERSION="1.0"><root type="user"><map/><node name="<unnamed>"><map/></node></root></preferences>

I'm not sure what causes this, I discovered it when converting some java code to Groovy that imports an xml preferences file and I reduced the case to this to reproduce the behavior in a clean environment.

I apologize for the trouble if this is some stupid error on my part that I'm just not seeing my way around.



Jochen Theodorou added a comment - 18/Sep/07 08:09 PM

could you please try to remove the xerxes and xalan jars from the lib directory of groovy and then run it again? I think that will solve your problem


Matt Kennedy added a comment - 19/Sep/07 10:00 AM

Thanks for the guidance on this, for others that might read this, here is what eventually solved the issue:

As per Jochen's suggestion, I removed xerces, though there was no obvious xalan jar in the groovy/lib directory I had, but I also had a file called 'groovysoap-all-1.0-0.3-snapshot_jdk1.5.0.jar' that doesn't seem to be in the current groovy-1.0 distribution so it must have been something I added. At any rate, it has xalan in it, so removing it solved the problem.


Matt Kennedy made changes - 19/Sep/07 12:28 PM
Field Original Value New Value
Status Open [ 1 ] Resolved [ 5 ]
Resolution Fixed [ 1 ]
Fix Version/s 1.1-beta-2 [ 10436 ]
Matt Kennedy added a comment - 20/Sep/07 05:08 PM

I'm reopening this issue in hopes of finding a workaround that will let me continue using Groovy 1.0. Below is a quick addition to the script I posted originally that seems to show that the workaround provided (removing xerces and xalan) will allow java.util.Preferences objects to work with XML, but seems to break other xml functionality.

#prefsTest.groovy
import java.util.prefs.*;
import javax.xml.parsers.DocumentBuilderFactory;

def prefs = Preferences.userNodeForPackage(this.getClass());
prefs.exportSubtree(System.out);
println '';
println DocumentBuilderFactory.newInstance().getClass()

$groovy prefsTest.groovy
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd">
<preferences EXTERNAL_XML_VERSION="1.0"><root type="user"><map/><node name="<unnamed>"><map/></node></root></preferences>
Caught: javax.xml.parsers.FactoryConfigurationError: Provider for javax.xml.parsers.DocumentBuilderFactory cannot be found
at prefsTest.run(prefsTest.groovy:7)
at prefsTest.main(prefsTest.groovy)

Is there a way to set a Provider for the DocumentBuilderFactory that won't cause the original ClassCastException when using the xml methods in a prefs object?


Matt Kennedy made changes - 20/Sep/07 05:08 PM
Resolution Fixed [ 1 ]
Status Resolved [ 5 ] Reopened [ 4 ]
Jochen Theodorou added a comment - 20/Sep/07 06:46 PM

sorry, I have a small problem in understanding... you did not remove the jars and want to get it working somehow? The flaw is, that java system itself has a parser and does normally load it from there, groovy comes with a parser and prefers that one over the parser from java system. But since loading the parser will use a class from the java system part and a class from the jars of groovy, that duplicates this class. The result is the ClassCastException. That's why suggested removing the jar, because there is no conflict then. removing the jar from RootLoader would work too, but I think there is no method to do something like that.... and in the end it would be the same. The cause for the duplication is the way RootLoader works... it is fine for all things but the xml parser. I am not sure about that, but I guess there is no usable way.


Guillaume Laforge made changes - 21/Sep/07 04:41 AM
Fix Version/s 1.1-beta-2 [ 10436 ]
Fix Version/s 1.1-rc-1 [ 13165 ]
Matt Kennedy added a comment - 22/Sep/07 01:13 PM

I'm sorry, I should have been more clear, I did remove the jars as suggested, which fixes the call to prefs.exportSubtree(System.out) - but if I then try to call DocumentBuilderFactory.newInstance(), it will fail with the following exception:

Caught: javax.xml.parsers.FactoryConfigurationError: Provider for javax.xml.parsers.DocumentBuilderFactory cannot be found
at prefsTest.run(prefsTest.groovy:7)
at prefsTest.main(prefsTest.groovy)

...which happens because the jars have been removed. Setting the system property for javax.xml.parsers.DocumentBuilderFactory to anything other than the included xerces parser seems to cause a ClassCastException.

I did manage to find a workaround though that allows me to continue working with Groovy 1.0 that only requires a small code workaround, which is as follows:

1. Do not remove any of the files from the groovy-1.0/lib directory.
2. Before calling any of the methods of the Preferences class that deal with xml (Preferences.exportSubtree() or Preferences.importPreferences for example... This may also apply to other standard Java API classes that use xml) use:
System.setProperty('javax.xml.parsers.DocumentBuilderFactory','com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl');

...to bypass the xml parser included in Groovy. Once finished with the offending calls, use:
System.setProperty('javax.xml.parsers.DocumentBuilderFactory','org.apache.xerces.jaxp.DocumentBuilderFactoryImpl');

...to reset the parser factory back to its original setting.

This workaround allows me to continue to use Groovy 1.0 (and hence the eclipse plugin) so as far as I'm concerned the issue is closed, but I will leave it open in the issue tracker in case you have further comments on it. Feel free to close it if you don't. I did notice that Guillaume Laforge changed the fixed version from 1.1-beta2 to rc1, I just thought I should mention that I have tested it under beta 2 and my code did work, but I haven't tested it under rc1 at all.

Thank you for your input in helping me solve this problem.


Matt Kennedy added a comment - 22/Sep/07 01:17 PM

Here is the original test case script with the fix implemented:

import java.util.prefs.*;
import javax.xml.parsers.DocumentBuilderFactory;

System.setProperty('javax.xml.parsers.DocumentBuilderFactory','com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl');

def prefs = Preferences.userNodeForPackage(this.getClass());
prefs.exportSubtree(System.out);
System.setProperty('javax.xml.parsers.DocumentBuilderFactory','org.apache.xerces.jaxp.DocumentBuilderFactoryImpl');
println '';
println DocumentBuilderFactory.newInstance().getClass()


Paul King added a comment - 29/Sep/07 05:41 PM

Added a Troubleshooting section to the Processing XML page on the wiki to document this workaround.


Paul King made changes - 29/Sep/07 05:41 PM
Resolution Fixed [ 1 ]
Assignee Paul King [ paulk ]
Status Reopened [ 4 ] Closed [ 6 ]