Syntax error in provider-configuration file

Help
Anonymous
2011-10-27
2012-10-08

  • Anonymous
    2011-10-27

    Hello,

    When I try to use the service provider mechanism of Java 6 to locate an
    implementation of

    javax.xml.xpath.XPathFactory
    

    , I get a syntax error (not in my code). Java goes inside the jar saxon9he.jar
    into the

    META-INF/services/javax.xml.xpath.XPathFactory
    

    file and then it finds:
    - on the first line, what it is looking for:

    net.sf.saxon.xpath.XPathFactoryImpl
    
    • on the remaining lines, unexpected lines with a syntax it does not understand. This is what I think. We have

      http\://java.sun.com/jaxp/xpath/dom: net.sf.saxon.xpath.XPathFactoryImpl

    and

    http\://saxon.sf.net/jaxp/xpath/om:     net.sf.saxon.xpath.XPathFactoryImpl
    

    .

    From what I understand of the JAR File specification, those lines are not
    covered by the same spec. What is it then ? And how can I make it work ?
    Of course, I can always instantiate

    net.sf.saxon.xpath.XPathFactoryImpl
    

    manually or tell the

    newInstance
    

    method of

    javax.xml.xpath.XPathFactory
    

    to use that specific class.

    TEST

    mac:services ludo$ java ServicesTest
    CLASSPATH = /Users/ludo/Library/Java/iText-5.0.1.jar, /Users/ludo/Library/Java/iText-5.0.5.jar, /Users/ludo/Library/Java/jackson-all-1.6.0.jar, /Users/ludo/Library/Java/jackson-all-1.6.8.jar, /Users/ludo/Library/Java/jackson-all-1.7.7.jar, /Users/ludo/Library/Java/jackson-all-1.8.2.jar, /Users/ludo/Library/Java/jcip-annotations.jar, /Applications/Mathematica.app/SystemFiles/Links/JLink/JLink.jar, /Users/ludo/Library/Java/joda-time-1.6.2.jar, /Users/ludo/Library/Java/JSAP-2.1.jar, /Users/ludo/Library/Java/odfdom-java-0.8.6.jar, /Users/ludo/Library/Java/ojdbc6.jar, /Users/ludo/Library/Java/saxon9he.jar, /Users/ludo/Documents/cours/xml/tests/services/, /Users/ludo/Documents/cours/xml/tests/services/, /Users/ludo/Library/Java/saxon6-5-5/saxon-jdom.jar, /Users/ludo/Library/Java/saxon6-5-5/saxon.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
    

    PROGRAM 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;
    import javax.xml.xpath.XPathFactoryConfigurationException;
    
    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 < urls.length - 2; i++) {
                classpath.append(urls[i].getFile()).append(", ");
            }
            if (urls.length > 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<XPathFactory> slXPathFactory = ServiceLoader.load(XPathFactory.class);
            System.out.printf("Service XPathFactory: %s\n", slXPathFactory.toString());
            availableProviders(slXPathFactory);        
        }
    }
    

    TIA,

    Ludovic Kuty

     

  • Anonymous
    2011-10-27

    Sorry for the wrong use of code tags with inline code in my message.

     
  • Michael Kay
    Michael Kay
    2011-10-27

    The format of the file was chosen to circumvent a JDK5 bug - see http://markm
    ail.org/message/obgfqbnrkuhzl6wl
    for some of the history. What Java implementation are you using? If there
    are implementations where this workaround doesn't work, then I've got a bit of
    a problem; I would normally go for conforming to the spec even when it means a
    failure to interoperate with products that don't conform to the spec, but in
    this case, changing it to be conformant would inconvenience a lot of my users.

    Actually, I wouldn't recommend using the JAXP search mechanism anyway. It's
    very slow, and it delivers an XPath engine that won't necessarily work with
    your application. You have no way of knowing whether you get an XPath 1.0 or
    2.0 implementation back, and the API is so weakly defined that there's very
    little chance your application will work with a particular provider unless you
    have tested it with that provider first. So even without this bug, I would
    steer clear of it.

     

  • Anonymous
    2011-10-27

    Thanks for your answer.

    I am on OS X Lion 10.7.2 with 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)

    I was using the service API mainly to understand it and I think that your
    remarks make sense and that it is better to choose explicitly the
    implementation. Even if I like the idea of switching implementation while
    keeping the same API.