title: Syntax error in javax.xml.xpath.XPathFactory provider-configuration file of Saxon-HE 9.3
body: <p>I am using Java SE 6 on Mac OS X and Saxon-HE 9.3.0.5. The ServiceLoader is not able to find the Saxon implementation of <code>javax.xml.xpath.XPathFactory</code>.</p>
  
  <pre><code>mac:test2 ludo$ java -version
  java version "1.6.0_26"
  Java(TM) SE Runtime Environment (build 1.6.0_26-b03-383-11A511)
  Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02-383, mixed mode)
  </code></pre>
  
  <p>The javadoc of the <code>newInstance</code> method of <code>javax.xml.xpath.XPathFactory</code> states in point 3 of the lookup procedure to localize an implementation that:</p>
  
  <blockquote>
    <p>The class loader is asked for service provider provider-configuration files matching javax.xml.xpath.XPathFactory in the resource directory META-INF/services. See the JAR File Specification for file format and parsing rules.</p>
  </blockquote>
  
  <p>The <a href="http://download.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider" rel="noreferrer">Service Provider section</a> of the JAR File Specification states that:</p>
  
  <blockquote>
    <p>The file should contain a newline-separated list of unique concrete provider-class names.</p>
  </blockquote>
  
  <p>But if I extract the saxon9he.jar file and look into the META-INF directory, I see:</p>
  
  <pre><code>mac:Java ludo$ mkdir test
  mac:Java ludo$ cd test
  mac:test ludo$ jar fx ../saxon9he.jar 
  mac:test ludo$ cat META-INF/services/javax.xml.xpath.XPathFactory 
  net.sf.saxon.xpath.XPathFactoryImpl
  http\://java.sun.com/jaxp/xpath/dom:    net.sf.saxon.xpath.XPathFactoryImpl
  http\://saxon.sf.net/jaxp/xpath/om:     net.sf.saxon.xpath.XPathFactoryImpl
  </code></pre>
  
  <p>The first line is correct but I can't see why there are two extra lines and it looks like those lines are causing trouble to ServiceLoader. I saw the problem with a test example that I wrote the understand the mecanism used to find a provider. We can see that saxon9he.jar is in the CLASSPATH.</p>
  
  <pre><code>mac:services ludo$ java ServicesTest
  CLASSPATH = ..., /Users/ludo/Library/Java/saxon9he.jar, ...
  Service XPathFactory: java.util.ServiceLoader[javax.xml.xpath.XPathFactory]
  ServiceConfigurationError: javax.xml.xpath.XPathFactory: jar:file:/Users/ludo/Library/Java/saxon9he.jar!/META-INF/services/javax.xml.xpath.XPathFactory:2: Illegal configuration-file syntax
  </code></pre>
  
  <p>The line of interest is:</p>
  
  <pre><code>jar:file:/Users/ludo/Library/Java/saxon9he.jar!/META-INF/services/javax.xml.xpath.XPathFactory:2: Illegal configuration-file syntax
  </code></pre>
  
  <p>Is it a bug of Saxon or an extended syntax not supported by my system ? What could i do to solve the issue ?</p>
  
  <p>Note that if I explicitly choose the class for the implementation, I can get a factory. But I want to use the Services mechanism. The following code works:</p>
  
  <pre><code>XPathFactory xpf = XPathFactory.newInstance(
    XPathFactory.DEFAULT_OBJECT_MODEL_URI,
    "net.sf.saxon.xpath.XPathFactoryImpl",
    ClassLoader.getSystemClassLoader());
  </code></pre>
  
  <p>I have added the whole Java test program below.</p>
  
  <pre><code>import java.net.URL;
  import java.net.URLClassLoader;
  import java.util.Iterator;
  import java.util.ServiceConfigurationError;
  import java.util.ServiceLoader;
  import javax.xml.xpath.XPathFactory;
  
  public class ServicesTest {
      public static String getClasspathString() {
          StringBuilder classpath = new StringBuilder();
          ClassLoader classLoader = ClassLoader.getSystemClassLoader();
          URL[] urls = ((URLClassLoader) classLoader).getURLs();
          for (int i = 0; i &lt; urls.length - 1; i++) {
              classpath.append(urls[i].getFile()).append(", ");
          }
          if (urls.length &gt; 0) {
              classpath.append(urls[urls.length - 1].getFile());
          }
  
          return classpath.toString();
      }
  
      public static void availableProviders(ServiceLoader sl) {
          Iterator it = sl.iterator();
          int index = 0;
          for (;;) {
              try {
                  if (!it.hasNext()) {
                      break;
                  }
                  index++;
                  Object o = it.next();
                  System.out.printf("%03d Concrete class name: %s\n", index, o.getClass().getName());
              } catch (ServiceConfigurationError e) {
                  System.err.printf("ServiceConfigurationError: %s\n", e.getMessage());
              }
          }
      }
  
      public static void main(String[] args) {
          System.out.printf("CLASSPATH = %s\n", getClasspathString());
          System.out.println();
  
          ServiceLoader&lt;XPathFactory&gt; slXPathFactory = ServiceLoader.load(XPathFactory.class);
          System.out.printf("Service XPathFactory: %s\n", slXPathFactory.toString());
          availableProviders(slXPathFactory);
      }
  }
  </code></pre>