You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Dan Gravell <el...@googlemail.com> on 2012/07/11 13:29:44 UTC

"No XPathFactory implementation found for the object model" when using XPath

I'm a little puzzled about this. I have the following piece of code:

XPathFactory xpathFactory = XPathFactory.newInstance();

I have the following import in the manifest for the bundle containing the
above code:

Import-Package: javax.xml.xpath

When I run, I get:

java.lang.RuntimeException: XPathFactory#newInstance() failed to create an
XPathFactory for the default object model:
http://java.sun.com/jaxp/xpath/dom with the
XPathFactoryConfigurationException:
javax.xml.xpath.XPathFactoryConfigurationException: No XPathFactory
implementation found for the object model:
http://java.sun.com/jaxp/xpath/dom
at javax.xml.xpath.XPathFactory.newInstance(XPathFactory.java:98)

It looks like XPath tries to load the class
"com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl".

Shouldn't this work? I only need to import the package for the API I use,
not the impl too right?

Do I need to add com.sun.org.apache.xpath.internal.jaxp to the
Export-Packages on my system bundle fragment? If so, why? I thought this
was only required if I was directly
accessing com.sun.org.apache.xpath.internal.jaxp (with a requisite
Import-Package) from my bundle.

Dan

Re: "No XPathFactory implementation found for the object model" when using XPath

Posted by Dan Gravell <el...@googlemail.com>.
Thanks Jeremias. I considered that although initially discounted it because
I didn't want to change my own code too much to cater for different
environments (being in an OSGi container versus just running in a 'vanilla'
class loading context). I didn't go back to it, but it's definitely another
option.

Dan

Re: "No XPathFactory implementation found for the object model" when using XPath

Posted by Jeremias Maerki <de...@jeremias-maerki.ch>.
I've had the same problem last year. I was able to work around it by
removing the context class loader that was active:

    private XPathFactory createXPathFactory() {
        Thread t = Thread.currentThread();
        ClassLoader cl = t.getContextClassLoader();
        t.setContextClassLoader(getClass().getClassLoader());
        try {
            return XPathFactory.newInstance();
        } finally {
            t.setContextClassLoader(cl);
        }
    }


Please note that I have my own versions of the JAXP API (1.4.01), Xerces,
Xalan and Serializer in the bootclasspath, since the JRE's usually ship
with buggy Xerces/Xalan forks.

HTH
Jeremias Maerki


On 11.07.2012 18:59:19 Dan Gravell wrote:
> Long story short: I just used org.osgi.framework.bootdelegation.
> 
> I tried using the XPath API for specifying the classloader. My initial
> attempt was this:
> 
> XPathFactory xpathFactory =
> XPathFactory.newInstance(XPathFactory.DEFAULT_OBJECT_MODEL_URI,
> "com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl",
> XPathFactory.class.getClassLoader());
> 
> Which is horrible because I have to specify the impl as I said in my
> previous email.
> 
> Anyway, this didn't work because XPathFactory.class.getClassLoader()
> resolves to null, I guess because XPathFactory is loaded by the boot
> classpath class loader. I'm not sure on the best way to get the boot
> classpath class loader in an OSGi environment.
> 
> Because the class loader is null, XPathFactory falls back to using the
> context class loader again.
> 
> I decided that the improvement gleaned from using the specific ClassLoader
> API was reduced significantly by having to specify the XPathFactoryImpl
> name anyway, and so I am just going to use bootdelegation.
> 
> Dan


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: "No XPathFactory implementation found for the object model" when using XPath

Posted by Dan Gravell <el...@googlemail.com>.
Long story short: I just used org.osgi.framework.bootdelegation.

I tried using the XPath API for specifying the classloader. My initial
attempt was this:

XPathFactory xpathFactory =
XPathFactory.newInstance(XPathFactory.DEFAULT_OBJECT_MODEL_URI,
"com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl",
XPathFactory.class.getClassLoader());

Which is horrible because I have to specify the impl as I said in my
previous email.

Anyway, this didn't work because XPathFactory.class.getClassLoader()
resolves to null, I guess because XPathFactory is loaded by the boot
classpath class loader. I'm not sure on the best way to get the boot
classpath class loader in an OSGi environment.

Because the class loader is null, XPathFactory falls back to using the
context class loader again.

I decided that the improvement gleaned from using the specific ClassLoader
API was reduced significantly by having to specify the XPathFactoryImpl
name anyway, and so I am just going to use bootdelegation.

Dan

Re: "No XPathFactory implementation found for the object model" when using XPath

Posted by Dan Gravell <el...@googlemail.com>.
Apologies, I was just abbreviating. And to be honest, I didn't actually
trace it in a debugger. I'll do that later... unfortunately the webservice
I was accessing has gone down so integration tests cannot be run just now.

What's annoying in this case is that the XPathFactoryFinder is package
private which means it cannot be reused by code looking to specify *just*
the classloader. The XPathFactory forces you to specify a stringified class
name.

Dan

Re: "No XPathFactory implementation found for the object model" when using XPath

Posted by Neil Bartlett <nj...@gmail.com>.
There seems to be more to the code than that. After working out the
classloader it then creates an "XPathFactoryFinder" and calls
"newFactory()" on it. The real logic (if you can call it logic...)
seems to happen in "XPathFactoryFinder._newFactory(String)" which does
all kinds of stuff like looking for system properties, trying to find
a file calles jaxp.properties in the Java installation directory, and
so on. It's probably not worth trying to work out in advance how that
code works, I would just debug it.

Note that I've run into bugs in this area in the OpenJDK where it
actually differed in functionality from the Sun/Oracle JDK. In that
case it was the XMLInputFactory class from StAX, but the factory
loading code looked very similar to this. Even though I provided it
with the correct classloader, it didn't actually *use* the classloader
I provided.

Like I said... batshit crazy stuff in the JRE! (sigh)


On Wed, Jul 11, 2012 at 12:49 PM, Dan Gravell
<el...@googlemail.com> wrote:
> Looking at the OpenJDK (I'm not sure on whether impls are shared by
> different JREs... anyway...) it appears to prefer the thread context
> classloader, if it is not null. Otherwise. it uses the XPathFactory class's
> classloader (which should work, but I suspect the context class loader is
> non-null).
>
> To be fair, I missed before that there is a way of doing this by specifying
> the class loader. I assume setting this to the XPathFactory's class's class
> loader is correct, rather than my bundle class's classloader.
>
> For boot delegation, "com.sun.*" can be used rather than all package names
> right? I have no idea what classes might be loaded in the depths of the 3rd
> party libraries I use. This could blow up at any time.
>
> Dan
>
> On Wed, Jul 11, 2012 at 12:34 PM, Neil Bartlett <nj...@gmail.com>wrote:
>
>> Well... it depends what the XPathFactory.newInstance() method actually
>> does in order to load the class. For example it may try to walk up the
>> stack and load from the calling classloader. This is the JRE we're
>> talking about, so you have to expect it to be batshit crazy and as
>> complicated as possible!
>>
>> I think in this scenario you should probably add the package
>> "com.sun.org.apache.xpath.internal.jaxp" to bootdelegation, since it
>> isn't a real dependency of your bundle, and the JRE is assuming that
>> it's always visible. I'd like to hear the opinion of others on this
>> though.
>>
>> Neil
>>
>> On Wed, Jul 11, 2012 at 12:29 PM, Dan Gravell
>> <el...@googlemail.com> wrote:
>> > I'm a little puzzled about this. I have the following piece of code:
>> >
>> > XPathFactory xpathFactory = XPathFactory.newInstance();
>> >
>> > I have the following import in the manifest for the bundle containing the
>> > above code:
>> >
>> > Import-Package: javax.xml.xpath
>> >
>> > When I run, I get:
>> >
>> > java.lang.RuntimeException: XPathFactory#newInstance() failed to create
>> an
>> > XPathFactory for the default object model:
>> > http://java.sun.com/jaxp/xpath/dom with the
>> > XPathFactoryConfigurationException:
>> > javax.xml.xpath.XPathFactoryConfigurationException: No XPathFactory
>> > implementation found for the object model:
>> > http://java.sun.com/jaxp/xpath/dom
>> > at javax.xml.xpath.XPathFactory.newInstance(XPathFactory.java:98)
>> >
>> > It looks like XPath tries to load the class
>> > "com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl".
>> >
>> > Shouldn't this work? I only need to import the package for the API I use,
>> > not the impl too right?
>> >
>> > Do I need to add com.sun.org.apache.xpath.internal.jaxp to the
>> > Export-Packages on my system bundle fragment? If so, why? I thought this
>> > was only required if I was directly
>> > accessing com.sun.org.apache.xpath.internal.jaxp (with a requisite
>> > Import-Package) from my bundle.
>> >
>> > Dan
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: "No XPathFactory implementation found for the object model" when using XPath

Posted by Dan Gravell <el...@googlemail.com>.
Looking at the OpenJDK (I'm not sure on whether impls are shared by
different JREs... anyway...) it appears to prefer the thread context
classloader, if it is not null. Otherwise. it uses the XPathFactory class's
classloader (which should work, but I suspect the context class loader is
non-null).

To be fair, I missed before that there is a way of doing this by specifying
the class loader. I assume setting this to the XPathFactory's class's class
loader is correct, rather than my bundle class's classloader.

For boot delegation, "com.sun.*" can be used rather than all package names
right? I have no idea what classes might be loaded in the depths of the 3rd
party libraries I use. This could blow up at any time.

Dan

On Wed, Jul 11, 2012 at 12:34 PM, Neil Bartlett <nj...@gmail.com>wrote:

> Well... it depends what the XPathFactory.newInstance() method actually
> does in order to load the class. For example it may try to walk up the
> stack and load from the calling classloader. This is the JRE we're
> talking about, so you have to expect it to be batshit crazy and as
> complicated as possible!
>
> I think in this scenario you should probably add the package
> "com.sun.org.apache.xpath.internal.jaxp" to bootdelegation, since it
> isn't a real dependency of your bundle, and the JRE is assuming that
> it's always visible. I'd like to hear the opinion of others on this
> though.
>
> Neil
>
> On Wed, Jul 11, 2012 at 12:29 PM, Dan Gravell
> <el...@googlemail.com> wrote:
> > I'm a little puzzled about this. I have the following piece of code:
> >
> > XPathFactory xpathFactory = XPathFactory.newInstance();
> >
> > I have the following import in the manifest for the bundle containing the
> > above code:
> >
> > Import-Package: javax.xml.xpath
> >
> > When I run, I get:
> >
> > java.lang.RuntimeException: XPathFactory#newInstance() failed to create
> an
> > XPathFactory for the default object model:
> > http://java.sun.com/jaxp/xpath/dom with the
> > XPathFactoryConfigurationException:
> > javax.xml.xpath.XPathFactoryConfigurationException: No XPathFactory
> > implementation found for the object model:
> > http://java.sun.com/jaxp/xpath/dom
> > at javax.xml.xpath.XPathFactory.newInstance(XPathFactory.java:98)
> >
> > It looks like XPath tries to load the class
> > "com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl".
> >
> > Shouldn't this work? I only need to import the package for the API I use,
> > not the impl too right?
> >
> > Do I need to add com.sun.org.apache.xpath.internal.jaxp to the
> > Export-Packages on my system bundle fragment? If so, why? I thought this
> > was only required if I was directly
> > accessing com.sun.org.apache.xpath.internal.jaxp (with a requisite
> > Import-Package) from my bundle.
> >
> > Dan
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: "No XPathFactory implementation found for the object model" when using XPath

Posted by Neil Bartlett <nj...@gmail.com>.
Well... it depends what the XPathFactory.newInstance() method actually
does in order to load the class. For example it may try to walk up the
stack and load from the calling classloader. This is the JRE we're
talking about, so you have to expect it to be batshit crazy and as
complicated as possible!

I think in this scenario you should probably add the package
"com.sun.org.apache.xpath.internal.jaxp" to bootdelegation, since it
isn't a real dependency of your bundle, and the JRE is assuming that
it's always visible. I'd like to hear the opinion of others on this
though.

Neil

On Wed, Jul 11, 2012 at 12:29 PM, Dan Gravell
<el...@googlemail.com> wrote:
> I'm a little puzzled about this. I have the following piece of code:
>
> XPathFactory xpathFactory = XPathFactory.newInstance();
>
> I have the following import in the manifest for the bundle containing the
> above code:
>
> Import-Package: javax.xml.xpath
>
> When I run, I get:
>
> java.lang.RuntimeException: XPathFactory#newInstance() failed to create an
> XPathFactory for the default object model:
> http://java.sun.com/jaxp/xpath/dom with the
> XPathFactoryConfigurationException:
> javax.xml.xpath.XPathFactoryConfigurationException: No XPathFactory
> implementation found for the object model:
> http://java.sun.com/jaxp/xpath/dom
> at javax.xml.xpath.XPathFactory.newInstance(XPathFactory.java:98)
>
> It looks like XPath tries to load the class
> "com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl".
>
> Shouldn't this work? I only need to import the package for the API I use,
> not the impl too right?
>
> Do I need to add com.sun.org.apache.xpath.internal.jaxp to the
> Export-Packages on my system bundle fragment? If so, why? I thought this
> was only required if I was directly
> accessing com.sun.org.apache.xpath.internal.jaxp (with a requisite
> Import-Package) from my bundle.
>
> Dan

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org