views:

2146

answers:

5

I've written a java application that utilizes JAXB for XSL transforms. I've included the saxon9.jar in my classpath so that I can use XSLT 2.0 rather than XSLT 1.0 on the command line.

java -classpath ./lib/saxon9.jar:./ -jar myApp.jar

I've included code in my XSL to report the XSLT used.

<xsl:comment><xsl:text >
</xsl:text>XSLT Version: <xsl:value-of select="system-property('xsl:version')" /> <xsl:text >
</xsl:text>XSLT Vendor: <xsl:value-of select="system-property('xsl:vendor')" /> <xsl:text >
</xsl:text>XSLT Vendor URL: <xsl:value-of select="system-property('xsl:vendor-url')" /> <xsl:text >
</xsl:text></xsl:comment>

It reports.

XSLT Version: 1.0
XSLT Vendor: Apache Software Foundation (Xalan XSLTC)
XSLT Vendor URL: http://xml.apache.org/xalan-j

This is the default implementation that is part of the JVM.

How do I get it to use the Saxon that I specified?


Follow up:

So none of these methods worked (except placing the saxon jar in the endorsed directory), but they all should have worked. It seems the combination of my using the "-jar myApp.jar" and wanting an alternative XSLT implementation were incompatible. In other words...

java -Djavax.xml.transform.TransformerFactory=net.sf.saxon.TransformerFactoryImpl -classpath ./lib/saxon9.jar:./ -jar myApp.jar

...does not work, but this does...

java -Djavax.xml.transform.TransformerFactory=net.sf.saxon.TransformerFactoryImpl -classpath ./lib/saxon9.jar:./myApp.jar org.dacracot.myApp

...interestingly, I don't even have to specify the factory and I get the saxon version...

java -classpath ./lib/saxon9.jar:./myApp.jar org.dacracot.myApp

+1  A: 

Have you tried placing your jar in the endorsed directory?

If you don't want the effect to be global, use the following option:

-Djava.endorsed.dirs=my_dir

in the command line.

kgiannakakis
This worked, but I sure don't like it. Changing my entire JVM seems counter to the purpose of the classpath.
dacracot
I know. However this is the only way to replace a JVM class and it is best avoided. Even with your own ClassLoaders you can't load a class from the java or javax packages.
kgiannakakis
This broke other applications... namely eclipse.
dacracot
A: 

How about

java -Xbootclasspath:lib/saxon9.jar -classpath . -jar myApp.jar
Paul Tomblin
Resulted in: Error occurred during initialization of VMjava/lang/NoClassDefFoundError: java/lang/ObjectAbort trap
dacracot
Oh, I guess you need to add rt.jar to the bootclasspath in that case.
Paul Tomblin
+1  A: 

This system property should set the replacement TransformerFactory:

java -Djavax.xml.transform.TransformerFactory=com.foobar.AcmeTransformer MyApp

I believe the factory class you want is net.sf.saxon.TransformerFactoryImpl

McDowell
Still getting... Exception in thread "Thread-1" javax.xml.transform.TransformerFactoryConfigurationError: Provider net.sf.saxon.TransformerFactoryImpl not found at javax.xml.transform.TransformerFactory.newInstance(TransformerFactory.java:109)
dacracot
Using... java -Djavax.xml.transform.TransformerFactory=net.sf.saxon.TransformerFactoryImpl -classpath ./lib/saxon9.jar:./ -jar myApp.jar
dacracot
+1  A: 

Check out the javadoc for TransformerFactory.newInstance() for all the possible ways to configure the factory.

  1. System Property
  2. lib/jaxp.properties
  3. Services config file (may be in the saxon JAR, /META-INF/services/javax.xml.transform.TransformerFactory)
nbeyer
+1  A: 

The last example you posted(w/o -Djavax...) works because the META-INF/services directory contains a file named

java.xml.transform.TransformerFactory

with the content

net.sf.saxon.TransformerFactoryImpl

The reason using

java -cp lib/saxon9.jar;myjar.jar

works and

java -cp lib/saxon9.jar -jar myjar.jar

doesn't is that using the -jar option tells java(w).exe to ignore the rest of the command line and pull everything (classpath included) from the jar's manifest file. If you put saxon9.jar in your jar manifest's classpath it should work.

Manifest-Version: 1.0
Main-Class: net.my.MainClass
Class-Path: lib/saxon9.jar
KitsuneYMG