This appears to be a bug in the Schematron task. The way the Ant task loads the Saxon XSLT processor would require Saxon to be on the system classpath even if the task itself is on a subsidiary classloader.
At first glance this code in ValidatorFactory looks sensible enough:
private TransformerFactory _factory = TransformerFactoryImpl.newInstance();
(where TransformerFactoryImpl
is Saxon's implementation of TransformerFactory
), but in fact TransformerFactoryImpl
doesn't define a newInstance()
method of its own so this is the inherited newInstance
from TransformerFactory
, which will look up an appropriate factory based on the value of the javax.xml.transform.TransformerFactory
system property. The Ant task does set this system property:
System.setProperty("javax.xml.transform.TransformerFactory",
"net.sf.saxon.TransformerFactoryImpl");
but TransformerFactory.newInstance()
will look for this class on the system classloader, not necessarily on the classloader that loaded the schematron task.
The fix would be to change ValidatorFactory
line 120 to simply
private TransformerFactory _factory = new TransformerFactoryImpl();
which would bypass all the dynamic lookup and instantiate the correct class directly. With this fix in place
<taskdef name="schematron"
classname="com.schematron.ant.SchematronTask"
classpath="lib/ant-schematron.jar:lib/saxon9he.jar"/>
would work correctly.
I'd suggest you report the bug to the developers, but the project doesn't look particularly active so you may just have to build your own local fork instead...