JAXP default implementation and JDK-8152063

David M. Lloyd david.lloyd at redhat.com
Thu Mar 24 14:29:22 UTC 2016


On 03/23/2016 07:12 AM, David M. Lloyd wrote:
> On 03/22/2016 08:59 AM, Daniel Fuchs wrote:
>> Hi David,
>>
>> On 22/03/16 13:53, David M. Lloyd wrote:
>>>>
>>>> Am I understanding it correctly that you're pointing the system
>>>> property
>>>> to a "proxy" as stated in JDK-8152063, not an actual implementation? So
>>>> it's sort of a provider-locating mechanism outside of jaxp, that
>>>> locates
>>>> the actual implementation, and if it cannot find one, it attempts to
>>>> fall back to and directly instantiate the JDK's default.  Is that why
>>>> "it will fail because we can't access the JDK's default
>>>> implementations"?
>>>
>>> Correct.
>>>
>>>> Was it because the ServiceLoader mechanism was not meeting your
>>>> requirement that you needed a proxy?
>>>
>>> Right.  Most user code using JAXP factories will just call e.g.
>>> XMLInputFactory.newFactory() with no arguments.  So the ServiceLoader
>>> mechanism is fine when we want to allow the user to override the
>>> implementation with one they've bundled in their WAR or whatever.  But
>>> if they do not do so, we are forced to ensure that another
>>> implementation is on the deployment class path.  It's even worse in
>>> contexts where we cannot control what the TCCL is set to when the
>>> factory methods are called.  There's just no practical way to ensure
>>> that our implementation is visible from every class loader.  We can
>>> however "hack" our proxy implementations on to every class loader, and
>>> then later set the default factory class loader to use (which then just
>>> uses the same ServiceLoader-style load again, but from the class loader
>>> we choose).
>>>
>>
>> If I understand well, what you need is to be able to
>> install a service provider that can create an instance
>> of the JDK default implementation in order to wrap it.
>>
>> I assume such a service provider would have to be deployed
>> in the System ClassLoader - so that it could be shadowed
>> by whichever provider is declared in the context class
>> loader.
>>
>> In order to create an instance of the JDK default implementation,
>> have you explored using the factory method that takes a
>> ClassLoader, and passing the extension class loader as
>> parameter?
>
> I can definitely try this out to see if we can use it.  How can I get
> the extension class loader though?  Weird as it sounds, I haven't found
> any idioms which can do so reliably (and it has to work across JVMs as
> well).

Daniel, I have hacked together a way to use the system class loader 
(which should be "good enough", I hope), but there is one further 
problem: org.xml.sax.helpers.XMLReaderFactory does not have a factory 
method which accepts a class loader like the others do.  Any thoughts on 
this one?  It looks like it might be pretty easy to add this method... 
but then, it's also pretty easy to just add setters to set the default 
Class :)

I was thinking of setting TCCL for the duration of the wrapped call 
using my system class loader trick where I construct a "dummy" class 
loader in the event that the system class loader is null.  But to do 
this I cannot rely on setting the system-wide system property for JAXP 
factory, which means I cannot uninstall my proxy at any time (because 
service loader descriptors are not dynamic).

-- 
- DML



More information about the core-libs-dev mailing list