Norris Boyd wrote:
> On Jun 16, 6:16 am, Kieran Topping <[EMAIL PROTECTED]> wrote:
>
>> I thought I would document some recent experience I've have, trying to
>> get E4X to work.
>> Thankfully my efforts ended in success, but I did encounter a few
>> jar-dependency & xml-parser issues, which took a while to fix - in
>> particular because googling the exception messages didn't yield much
>> information. Hopefully this post might address this and save someone
>> else a bit of time!
>>
>> The results below were generated by running the attached java class
>> (E4X.java) from the command line, on a 1.5 JVM. The java class runs a
>> very simple javascript script which generates a small xml fragment and
>> outputs it to the screen.
>> The expected output is:
>> <y>a & b</y>
>>
>> 1. My first attempt to run this was using Rhino-1.6R7.
>> [kieran]$ env CLASSPATH=./js-1.6R7.jar:$CLASSPATH java E4X
>> Exception in thread "main" org.mozilla.javascript.EcmaError: TypeError:
>> error: Unexpected character encountered (lex state 3): 'b' (<cmd>#3)
>> ...
>>
>> I haven't actually worked out what is causing this problem, but I think
>> that it was a bug in the xmlbeans library (which Rhino-1.6R7 uses). In
>> any case, I moved on as follows:
>>
>> 2. I then tried Rhino-1.7R1
>> [kieran]$ env CLASSPATH=./js-1.7R1.jar:$CLASSPATH java E4X
>> Exception in thread "main" java.lang.UnsupportedOperationException:
>> This DocumentBuilder, "org.apache.xerces.jaxp.DocumentBuilderImpl", does
>> not support the reset functionality. Specification "null" version "null"
>> ...
>>
>> This problem seems to be caused by the my Xerces version not being
>> sufficiently up to date.
>> I haven't tried all versions, but what I /can/ say is that 2.0.1 & 2.6.2
>> both generate this exception.
>>
>> 3. So, I installed the most recent xerces library
>> [kieran]$ env CLASSPATH=./js-1.7R1.jar:./xercesImpl-2.9.0.jar:$CLASSPATH
>> java E4X
>> <parent/>
>>
>> This was the weirdest problem that I encountered. Whatever the contents
>> of my javascript XML object, "<parent/>" was the only output that was
>> ever generated!
>>
>> 4. As I suspected that some other jar was interfering somehow, I
>> systematically removed jars from my CLASSPATH, and re-tested. It turned
>> out that as soon as I removed saxon-6.5.4.jar from my CLASSPATH, the
>> java worked as expected:
>>
>> [kieran]$ NOSAXONCLASSPATH=$(echo $CLASSPATH | perl -np -e
>> 's/saxon-6.5.4.jar//')
>> [kieran]$ env
>> CLASSPATH=./js-1.7R1.jar:./xercesImpl-2.9.0.jar:$NOSAXONCLASSPATH java E4X
>> <y>a & b</y>
>>
>> So, I had got Rhino/E4X to work as required by:
>> 1. Upgrading to Rhino1.7R1.
>> 2. Upgrading to Xerces 2.9.0.
>> 3. Uninstalling Saxon 6.5.4.
>>
>> However, Saxon 6.5.4 is an is integral part of our application (hey, it
>> works fine for us, and upgrading would be very non-trivial), so I had to
>> find a solution that didn't involve uninstalling Saxon.
>>
>> Saxon uses the "Services API" to inform
>> javax.xml.transform.TransformerFactory which TransformerFactory
>> implementation it should return when the static newInstance() method is
>> called. Saxon tells it to use "com.icl.saxon.TransformerFactoryImpl".
>>
>> For some reason (probably too difficult/time-consuming to investigate)
>> the Rhino/E4X library doesn't interact correctly with transformers
>> generated by the Saxon factory: "com.icl.saxon.TransformerFactoryImpl".
>>
>> If you're interested, my "solution" was to amend the Saxon jar such that
>> it doesn't specify which TransformerFactory to use (by deleting the
>> files in META-INF/services); the bits of my application that need a
>> "com.icl.saxon.TransformerFactoryImpl", I've explicitly amended to
>> request one.
>>
>> I hope this helps someone!
>>
>> Kieran
>>
>> [E4X.java]import org.mozilla.javascript.*;
>>
>> public class E4X {
>> public static void main(String args[])
>> throws Exception
>> {
>> Context cx = Context.enter();
>> try {
>> Scriptable scope = cx.initStandardObjects();
>> Object result = cx.evaluateString(
>> scope,
>> "var x = <example>a & b</example>; \n"+
>> "var y = <y/>; \n"+
>> "y.appendChild(x.text()); \n"+
>> "y.toXMLString(); ",
>> "<cmd>", 1, null
>> );
>> System.out.println(Context.toString(result));
>> } finally {
>> Context.exit();
>> }
>> }
>>
>> }
>>
>
> Bizarre-- the E4X implementation in Rhino 1.7R1 just uses the XML
> parser from javax.xml. Your example program worked just fine for me
> with only the Rhino jar in the classpath.
>
Hmm, I'm realizing I should have been a bit more explicit in terms of
exactly what was in my classpath.
The example that you're referring to would be better expressed as follows:
[kieran]$ env CLASSPATH=.:./js-1.7R1.jar:./xercesImpl-2.6.2.jar java E4X
Exception in thread "main" java.lang.UnsupportedOperationException:
This DocumentBuilder, "org.apache.xerces.jaxp.DocumentBuilderImpl", does
not support the reset functionality. Specification "null" version "null"
The point being that xerces is in my classpath.
So, when XmlProcessor.java executes (line 85):
this.dom = javax.xml.parsers.DocumentBuilderFactory.newInstance();
the DocumentBuilderFactory implementation that will be returned will be
an org.apache.xerces.jaxp.DocumentBuilderFactoryImpl.
This is on account of the contents of
META-INF/services/org.apache.xerces.jaxp.DocumentBuilderFactoryImpl in
xercesImpl-2.6.2.jar.
Presumably, in the absence of the xerces jar, some JVM default
DocumentBuilderFactory will be used. (yep, I've just tested this, and it
returns a
"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl";
presumably a more up-to-date implementation).
One aim of my post (apart from the cathartic process of brain-dumping)
was to highlight the fact that an older version of Xerces (and - I
expect - other xml libs) in your classpath can cause unwanted
side-effects and exceptions.
This might not sound like a common occurrence but it'll include, for
instance, anyone who is using Tomcat 5.0, 5.5 or 6.0.
Kieran
_______________________________________________
dev-tech-js-engine-rhino mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino