2

I need to change the default implementation within my project for org.w3c.dom.Document.

I followed this link to change the default implementation for:

javax.xml.parsers.DocumentBuilderFactory
javax.xml.parsers.SAXParserFactory
javax.xml.transform.TransformerFactory

I've created 3 files with the above names with in META-INF/services and put in each the following lines:

In file: javax.xml.parsers.DocumentBuilderFactory I put: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl

In file: javax.xml.parsers.SAXParserFactory I put: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl

In file: javax.xml.transform.TransformerFactory I put: org.apache.xalan.processor.TransformerFactoryImpl

But when I deployed over Oracle Application Server I got that the implementation class of org.w3c.dom.Document is : oracle.xml.parser.v2.XMLDocument instead of com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl that is being printed when development on Jetty.

I am developing on Jetty and deploying on Oracle application server.

halfer
  • 19,824
  • 17
  • 99
  • 186
Muhammad Hewedy
  • 29,102
  • 44
  • 127
  • 219

3 Answers3

1

It sounds like you are doing the right thing. But it might be simpler to use the system properties method ... at least until you can figure out what is going wrong with the "services" method.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    The services mechanism is about components which provide a service announcing that they do so. It's about providing a choice. It is *not* about specifying *which* choice to make, and relying on classpath ordering to use it to do that seems like a kludge to me. The system properties method is a way of making an explicit choice, and so it is the right way to do this here. – Tom Anderson Nov 10 '10 at 12:18
  • @Tom Anderson - in defence of the OP, my reading of the linked document is that the "services" approach ought to work. And I found other search hits that suggest this is true for OAS as well. However, I must admit that the way the document is phrased leaves some room for doubt, and I couldn't find OAS specific documentation. – Stephen C Nov 10 '10 at 12:29
  • yes, you're quite right. The services approach really ought to work everywhere, since it's part of the JRE. I merely think it's better to be explicit. – Tom Anderson Nov 11 '10 at 11:53
1

Possibly the oracle.xml.parser.v2.XMLDocument implementation for org.w3c.dom.Document is found before com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl by the classloader. Check if its possible to exclude the Oracle implementation, look for the file which contains the class. This might be located in a "container wide" folder and your implementation in an "application wide" folder.

Haven't had exactly the same problem, but similar, where the order of jars loaded by the classloader was important. Hope this can give you a push in the right direction at least

Kennet
  • 5,736
  • 2
  • 25
  • 24
  • Ya, I know that it is the problem .... ordering of JARS on the classpath.. but unfrotantely, i am deploying on a prod server that have other app that are running, meaning that i cannot do any change to "container-wdie" configs :) – Muhammad Hewedy Nov 11 '10 at 08:57
0

Two things to note:
1. com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl has a hint for you: it's an Internal implementation (as opposed to Public API). It is prone to change and should not be the top choice for production development.
2. I found that com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl is the best implementation that suited all of my needs and as far as I could tell, it matches the specification.

You can easily see a conflict. I'm hoping one day there will be a platform standard, public API for a Document implementation and for all of its factories and such.

Here's my experience:

playing with META-INF/services and JAR ordering in the classpath felt like a hack, worked even worse and in the end, I moved away from that approach. Here's why it didn't work for me: there were 2+ 3rd party implementations on the classpath, so there was no hope getting .xerces.internal. by default. However, specifying it as high as System Property would override it for everything, which didn't work out for the 3rd party products.

• • • I ended up creating a property and loading the precise factory I wanted explicitly, without relying on the search mechanism through the META-INF/services and system properties.

By the way, different factories use different steps of searching, which is inconsistent and I hope Oracle can find a way to standardize this process and make it more flexible and controllable.