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
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();
}
}
}
_______________________________________________
dev-tech-js-engine-rhino mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino