Java's default JAXB implementation is chosen over my classpath
Solution 1
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.
Solution 2
Check out the javadoc for TransformerFactory.newInstance() for all the possible ways to configure the factory.
- System Property
- lib/jaxp.properties
- Services config file (may be in the saxon JAR, /META-INF/services/javax.xml.transform.TransformerFactory)
Solution 3
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
Solution 4
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
Comments
-
dacracot almost 2 years
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
-
dacracot about 15 yearsThis worked, but I sure don't like it. Changing my entire JVM seems counter to the purpose of the classpath.
-
NikolaDjokic about 15 yearsI 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.
-
dacracot about 15 yearsResulted in: Error occurred during initialization of VM java/lang/NoClassDefFoundError: java/lang/Object Abort trap
-
dacracot about 15 yearsThis broke other applications... namely eclipse.
-
dacracot about 15 yearsStill 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 about 15 yearsUsing... java -Djavax.xml.transform.TransformerFactory=net.sf.saxon.TransformerFactoryImpl -classpath ./lib/saxon9.jar:./ -jar myApp.jar