mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 09:34:38 +02:00
8152912: SAX XMLReaderFactory needs to be ServiceLoader compliant
Reviewed-by: dfuchs
This commit is contained in:
parent
dd927b90d5
commit
56be49516c
8 changed files with 170 additions and 158 deletions
|
@ -86,5 +86,6 @@ module java.xml {
|
||||||
uses javax.xml.transform.TransformerFactory;
|
uses javax.xml.transform.TransformerFactory;
|
||||||
uses javax.xml.validation.SchemaFactory;
|
uses javax.xml.validation.SchemaFactory;
|
||||||
uses javax.xml.xpath.XPathFactory;
|
uses javax.xml.xpath.XPathFactory;
|
||||||
|
uses org.xml.sax.XMLReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,7 @@ package org.xml.sax;
|
||||||
* @see org.xml.sax.DocumentHandler#startElement startElement
|
* @see org.xml.sax.DocumentHandler#startElement startElement
|
||||||
* @see org.xml.sax.helpers.AttributeListImpl AttributeListImpl
|
* @see org.xml.sax.helpers.AttributeListImpl AttributeListImpl
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since="5")
|
||||||
public interface AttributeList {
|
public interface AttributeList {
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ package org.xml.sax;
|
||||||
* @see org.xml.sax.Locator
|
* @see org.xml.sax.Locator
|
||||||
* @see org.xml.sax.HandlerBase
|
* @see org.xml.sax.HandlerBase
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since="5")
|
||||||
public interface DocumentHandler {
|
public interface DocumentHandler {
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@ import java.util.Locale;
|
||||||
* @see org.xml.sax.HandlerBase
|
* @see org.xml.sax.HandlerBase
|
||||||
* @see org.xml.sax.InputSource
|
* @see org.xml.sax.InputSource
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since="5")
|
||||||
public interface Parser
|
public interface Parser
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -32,8 +32,7 @@
|
||||||
|
|
||||||
package org.xml.sax.helpers;
|
package org.xml.sax.helpers;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.util.Objects;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of a class by name.
|
* Create a new instance of a class by name.
|
||||||
|
@ -57,31 +56,26 @@ import java.lang.reflect.InvocationTargetException;
|
||||||
* @version 2.0.1 (sax2r2)
|
* @version 2.0.1 (sax2r2)
|
||||||
*/
|
*/
|
||||||
class NewInstance {
|
class NewInstance {
|
||||||
|
|
||||||
private static final String DEFAULT_PACKAGE = "com.sun.org.apache.xerces.internal";
|
private static final String DEFAULT_PACKAGE = "com.sun.org.apache.xerces.internal";
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of the specified class name
|
* Creates a new instance of the specified class name
|
||||||
*
|
*
|
||||||
* Package private so this code is not exposed at the API level.
|
* Package private so this code is not exposed at the API level.
|
||||||
*/
|
*/
|
||||||
static Object newInstance (ClassLoader classLoader, String className)
|
static <T> T newInstance (Class<T> type, ClassLoader loader, String clsName)
|
||||||
throws ClassNotFoundException, IllegalAccessException,
|
throws ClassNotFoundException, IllegalAccessException,
|
||||||
InstantiationException
|
InstantiationException
|
||||||
{
|
{
|
||||||
// make sure we have access to restricted packages
|
ClassLoader classLoader = Objects.requireNonNull(loader);
|
||||||
boolean internal = false;
|
String className = Objects.requireNonNull(clsName);
|
||||||
if (System.getSecurityManager() != null) {
|
|
||||||
if (className != null && className.startsWith(DEFAULT_PACKAGE)) {
|
if (className.startsWith(DEFAULT_PACKAGE)) {
|
||||||
internal = true;
|
return type.cast(new com.sun.org.apache.xerces.internal.parsers.SAXParser());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Class driverClass;
|
Class<?> driverClass = classLoader.loadClass(className);
|
||||||
if (classLoader == null || internal) {
|
return type.cast(driverClass.newInstance());
|
||||||
driverClass = Class.forName(className);
|
|
||||||
} else {
|
|
||||||
driverClass = classLoader.loadClass(className);
|
|
||||||
}
|
|
||||||
return driverClass.newInstance();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,6 @@
|
||||||
|
|
||||||
package org.xml.sax.helpers;
|
package org.xml.sax.helpers;
|
||||||
|
|
||||||
import org.xml.sax.Parser;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Java-specific class for dynamically loading SAX parsers.
|
* Java-specific class for dynamically loading SAX parsers.
|
||||||
|
@ -65,6 +63,8 @@ import org.xml.sax.Parser;
|
||||||
* @author David Megginson
|
* @author David Megginson
|
||||||
* @version 2.0.1 (sax2r2)
|
* @version 2.0.1 (sax2r2)
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings( "deprecation" )
|
||||||
|
@Deprecated(since="5")
|
||||||
public class ParserFactory {
|
public class ParserFactory {
|
||||||
private static SecuritySupport ss = new SecuritySupport();
|
private static SecuritySupport ss = new SecuritySupport();
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ public class ParserFactory {
|
||||||
* @see #makeParser(java.lang.String)
|
* @see #makeParser(java.lang.String)
|
||||||
* @see org.xml.sax.Parser
|
* @see org.xml.sax.Parser
|
||||||
*/
|
*/
|
||||||
public static Parser makeParser ()
|
public static org.xml.sax.Parser makeParser ()
|
||||||
throws ClassNotFoundException,
|
throws ClassNotFoundException,
|
||||||
IllegalAccessException,
|
IllegalAccessException,
|
||||||
InstantiationException,
|
InstantiationException,
|
||||||
|
@ -134,14 +134,13 @@ public class ParserFactory {
|
||||||
* @see #makeParser()
|
* @see #makeParser()
|
||||||
* @see org.xml.sax.Parser
|
* @see org.xml.sax.Parser
|
||||||
*/
|
*/
|
||||||
public static Parser makeParser (String className)
|
public static org.xml.sax.Parser makeParser (String className)
|
||||||
throws ClassNotFoundException,
|
throws ClassNotFoundException,
|
||||||
IllegalAccessException,
|
IllegalAccessException,
|
||||||
InstantiationException,
|
InstantiationException,
|
||||||
ClassCastException
|
ClassCastException
|
||||||
{
|
{
|
||||||
return (Parser) NewInstance.newInstance (
|
return NewInstance.newInstance (org.xml.sax.Parser.class, ss.getClassLoader(), className);
|
||||||
ss.getContextClassLoader(), className);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -37,54 +37,43 @@ import java.security.*;
|
||||||
*/
|
*/
|
||||||
class SecuritySupport {
|
class SecuritySupport {
|
||||||
|
|
||||||
|
/**
|
||||||
ClassLoader getContextClassLoader() throws SecurityException{
|
* Returns the current thread's context class loader, or the system class loader
|
||||||
return (ClassLoader)
|
* if the context class loader is null.
|
||||||
AccessController.doPrivileged(new PrivilegedAction() {
|
* @return the current thread's context class loader, or the system class loader
|
||||||
public Object run() {
|
* @throws SecurityException
|
||||||
ClassLoader cl = null;
|
*/
|
||||||
//try {
|
ClassLoader getClassLoader() throws SecurityException{
|
||||||
cl = Thread.currentThread().getContextClassLoader();
|
return AccessController.doPrivileged((PrivilegedAction<ClassLoader>)() -> {
|
||||||
//} catch (SecurityException ex) { }
|
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||||
|
if (cl == null) {
|
||||||
if (cl == null)
|
|
||||||
cl = ClassLoader.getSystemClassLoader();
|
cl = ClassLoader.getSystemClassLoader();
|
||||||
|
}
|
||||||
|
|
||||||
return cl;
|
return cl;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
String getSystemProperty(final String propName) {
|
String getSystemProperty(final String propName) {
|
||||||
return (String)
|
return AccessController.doPrivileged((PrivilegedAction<String>)()
|
||||||
AccessController.doPrivileged(new PrivilegedAction() {
|
-> System.getProperty(propName));
|
||||||
public Object run() {
|
|
||||||
return System.getProperty(propName);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInputStream getFileInputStream(final File file)
|
FileInputStream getFileInputStream(final File file)
|
||||||
throws FileNotFoundException
|
throws FileNotFoundException
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return (FileInputStream)
|
return AccessController.doPrivileged((PrivilegedExceptionAction<FileInputStream>)() ->
|
||||||
AccessController.doPrivileged(new PrivilegedExceptionAction() {
|
new FileInputStream(file));
|
||||||
public Object run() throws FileNotFoundException {
|
|
||||||
return new FileInputStream(file);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (PrivilegedActionException e) {
|
} catch (PrivilegedActionException e) {
|
||||||
throw (FileNotFoundException)e.getException();
|
throw (FileNotFoundException)e.getException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InputStream getResourceAsStream(final ClassLoader cl,
|
|
||||||
final String name)
|
InputStream getResourceAsStream(final ClassLoader cl, final String name)
|
||||||
{
|
{
|
||||||
return (InputStream)
|
return AccessController.doPrivileged((PrivilegedAction<InputStream>) () -> {
|
||||||
AccessController.doPrivileged(new PrivilegedAction() {
|
|
||||||
public Object run() {
|
|
||||||
InputStream ris;
|
InputStream ris;
|
||||||
if (cl == null) {
|
if (cl == null) {
|
||||||
ris = SecuritySupport.class.getResourceAsStream(name);
|
ris = SecuritySupport.class.getResourceAsStream(name);
|
||||||
|
@ -92,17 +81,12 @@ class SecuritySupport {
|
||||||
ris = cl.getResourceAsStream(name);
|
ris = cl.getResourceAsStream(name);
|
||||||
}
|
}
|
||||||
return ris;
|
return ris;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean doesFileExist(final File f) {
|
boolean doesFileExist(final File f) {
|
||||||
return ((Boolean)
|
return (AccessController.doPrivileged((PrivilegedAction<Boolean>)() ->
|
||||||
AccessController.doPrivileged(new PrivilegedAction() {
|
new Boolean(f.exists())));
|
||||||
public Object run() {
|
|
||||||
return new Boolean(f.exists());
|
|
||||||
}
|
|
||||||
})).booleanValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -32,10 +32,17 @@
|
||||||
|
|
||||||
package org.xml.sax.helpers;
|
package org.xml.sax.helpers;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import org.xml.sax.XMLReader;
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.ServiceConfigurationError;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.XMLReader;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,7 +77,11 @@ import org.xml.sax.SAXException;
|
||||||
* @since 1.4, SAX 2.0
|
* @since 1.4, SAX 2.0
|
||||||
* @author David Megginson, David Brownell
|
* @author David Megginson, David Brownell
|
||||||
* @version 2.0.1 (sax2r2)
|
* @version 2.0.1 (sax2r2)
|
||||||
|
*
|
||||||
|
* @deprecated It is recommended to use {@link javax.xml.parsers.SAXParserFactory}
|
||||||
|
* instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since="9")
|
||||||
final public class XMLReaderFactory
|
final public class XMLReaderFactory
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -83,47 +94,43 @@ final public class XMLReaderFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String property = "org.xml.sax.driver";
|
private static final String property = "org.xml.sax.driver";
|
||||||
private static SecuritySupport ss = new SecuritySupport();
|
private static final SecuritySupport ss = new SecuritySupport();
|
||||||
|
|
||||||
private static String _clsFromJar = null;
|
|
||||||
private static boolean _jarread = false;
|
|
||||||
/**
|
/**
|
||||||
* Attempt to create an XMLReader from system defaults.
|
* Obtains a new instance of a {@link org.xml.sax.XMLReader}.
|
||||||
* In environments which can support it, the name of the XMLReader
|
* This method uses the following ordered lookup procedure to find and load
|
||||||
* class is determined by trying each these options in order, and
|
* the {@link org.xml.sax.XMLReader} implementation class:
|
||||||
* using the first one which succeeds:
|
* <p>
|
||||||
* <ul>
|
* <ol>
|
||||||
*
|
|
||||||
* <li>If the system property {@code org.xml.sax.driver}
|
* <li>If the system property {@code org.xml.sax.driver}
|
||||||
* has a value, that is used as an XMLReader class name. </li>
|
* has a value, that is used as an XMLReader class name. </li>
|
||||||
|
* <li>
|
||||||
|
* Use the service-provider loading facility, defined by the
|
||||||
|
* {@link java.util.ServiceLoader} class, to attempt to locate and load an
|
||||||
|
* implementation of the service {@link org.xml.sax.XMLReader} by using the
|
||||||
|
* {@linkplain java.lang.Thread#getContextClassLoader() current thread's context class loader}.
|
||||||
|
* If the context class loader is null, the
|
||||||
|
* {@linkplain ClassLoader#getSystemClassLoader() system class loader} will
|
||||||
|
* be used.
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* Deprecated. Look for a class name in the {@code META-INF/services/org.xml.sax.driver}
|
||||||
|
* file in a jar file available to the runtime.</li>
|
||||||
|
* <li>
|
||||||
|
* <p>
|
||||||
|
* Otherwise, the system-default implementation is returned.
|
||||||
|
* </li>
|
||||||
|
* </ol>
|
||||||
*
|
*
|
||||||
* <li>The JAR "Services API" is used to look for a class name
|
* @apiNote
|
||||||
* in the <em>META-INF/services/org.xml.sax.driver</em> file in
|
* The process that looks for a class name in the
|
||||||
* jarfiles available to the runtime.</li>
|
* {@code META-INF/services/org.xml.sax.driver} file in a jar file does not
|
||||||
|
* conform to the specification of the service-provider loading facility
|
||||||
|
* as defined in {@link java.util.ServiceLoader} and therefore does not
|
||||||
|
* support modularization. It is deprecated as of Java SE 9 and subject to
|
||||||
|
* removal in a future release.
|
||||||
*
|
*
|
||||||
* <li> SAX parser distributions are strongly encouraged to provide
|
* @return a new XMLReader.
|
||||||
* a default XMLReader class name that will take effect only when
|
|
||||||
* previous options (on this list) are not successful.</li>
|
|
||||||
*
|
|
||||||
* <li>Finally, if {@link ParserFactory#makeParser()} can
|
|
||||||
* return a system default SAX1 parser, that parser is wrapped in
|
|
||||||
* a {@link ParserAdapter}. (This is a migration aid for SAX1
|
|
||||||
* environments, where the {@code org.xml.sax.parser} system
|
|
||||||
* property will often be usable.) </li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* <p> In environments such as small embedded systems, which can not
|
|
||||||
* support that flexibility, other mechanisms to determine the default
|
|
||||||
* may be used.
|
|
||||||
*
|
|
||||||
* <p>Note that many Java environments allow system properties to be
|
|
||||||
* initialized on a command line. This means that <em>in most cases</em>
|
|
||||||
* setting a good value for that property ensures that calls to this
|
|
||||||
* method will succeed, except when security policies intervene.
|
|
||||||
* This will also maximize application portability to older SAX
|
|
||||||
* environments, with less robust implementations of this method.
|
|
||||||
*
|
|
||||||
* @return A new XMLReader.
|
|
||||||
* @exception org.xml.sax.SAXException If no default XMLReader class
|
* @exception org.xml.sax.SAXException If no default XMLReader class
|
||||||
* can be identified and instantiated.
|
* can be identified and instantiated.
|
||||||
* @see #createXMLReader(java.lang.String)
|
* @see #createXMLReader(java.lang.String)
|
||||||
|
@ -132,7 +139,7 @@ final public class XMLReaderFactory
|
||||||
throws SAXException
|
throws SAXException
|
||||||
{
|
{
|
||||||
String className = null;
|
String className = null;
|
||||||
ClassLoader cl = ss.getContextClassLoader();
|
ClassLoader cl = ss.getClassLoader();
|
||||||
|
|
||||||
// 1. try the JVM-instance-wide system property
|
// 1. try the JVM-instance-wide system property
|
||||||
try {
|
try {
|
||||||
|
@ -140,62 +147,26 @@ final public class XMLReaderFactory
|
||||||
}
|
}
|
||||||
catch (RuntimeException e) { /* continue searching */ }
|
catch (RuntimeException e) { /* continue searching */ }
|
||||||
|
|
||||||
// 2. if that fails, try META-INF/services/
|
// 2. try the ServiceLoader
|
||||||
if (className == null) {
|
if (className == null) {
|
||||||
if (!_jarread) {
|
final XMLReader provider = findServiceProvider(XMLReader.class, cl);
|
||||||
_jarread = true;
|
if (provider != null) {
|
||||||
String service = "META-INF/services/" + property;
|
return provider;
|
||||||
InputStream in;
|
|
||||||
BufferedReader reader;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (cl != null) {
|
|
||||||
in = ss.getResourceAsStream(cl, service);
|
|
||||||
|
|
||||||
// If no provider found then try the current ClassLoader
|
|
||||||
if (in == null) {
|
|
||||||
cl = null;
|
|
||||||
in = ss.getResourceAsStream(cl, service);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// No Context ClassLoader, try the current ClassLoader
|
|
||||||
in = ss.getResourceAsStream(cl, service);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in != null) {
|
// 3. try META-INF/services/org.xml.sax.driver. This old process allows
|
||||||
reader = new BufferedReader (new InputStreamReader (in, "UTF8"));
|
// legacy providers to be found
|
||||||
_clsFromJar = reader.readLine ();
|
|
||||||
in.close ();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
className = _clsFromJar;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Distro-specific fallback
|
|
||||||
if (className == null) {
|
if (className == null) {
|
||||||
// BEGIN DISTRIBUTION-SPECIFIC
|
className = jarLookup(cl);
|
||||||
|
}
|
||||||
// EXAMPLE:
|
|
||||||
// className = "com.example.sax.XmlReader";
|
// 4. Distro-specific fallback
|
||||||
// or a $JAVA_HOME/jre/lib/*properties setting...
|
if (className == null) {
|
||||||
className = "com.sun.org.apache.xerces.internal.parsers.SAXParser";
|
return new com.sun.org.apache.xerces.internal.parsers.SAXParser();
|
||||||
|
|
||||||
// END DISTRIBUTION-SPECIFIC
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// do we know the XMLReader implementation class yet?
|
|
||||||
if (className != null)
|
|
||||||
return loadClass (cl, className);
|
return loadClass (cl, className);
|
||||||
|
|
||||||
// 4. panic -- adapt any SAX1 parser
|
|
||||||
try {
|
|
||||||
return new ParserAdapter (ParserFactory.makeParser ());
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new SAXException ("Can't create default XMLReader; "
|
|
||||||
+ "is system property org.xml.sax.driver set?");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -217,14 +188,14 @@ final public class XMLReaderFactory
|
||||||
public static XMLReader createXMLReader (String className)
|
public static XMLReader createXMLReader (String className)
|
||||||
throws SAXException
|
throws SAXException
|
||||||
{
|
{
|
||||||
return loadClass (ss.getContextClassLoader(), className);
|
return loadClass (ss.getClassLoader(), className);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static XMLReader loadClass (ClassLoader loader, String className)
|
private static XMLReader loadClass (ClassLoader loader, String className)
|
||||||
throws SAXException
|
throws SAXException
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return (XMLReader) NewInstance.newInstance (loader, className);
|
return NewInstance.newInstance (XMLReader.class, loader, className);
|
||||||
} catch (ClassNotFoundException e1) {
|
} catch (ClassNotFoundException e1) {
|
||||||
throw new SAXException("SAX2 driver class " + className +
|
throw new SAXException("SAX2 driver class " + className +
|
||||||
" not found", e1);
|
" not found", e1);
|
||||||
|
@ -240,4 +211,64 @@ final public class XMLReaderFactory
|
||||||
" does not implement XMLReader", e4);
|
" does not implement XMLReader", e4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Locates a provider by directly reading the jar service file.
|
||||||
|
* @param loader the ClassLoader to be used to read the service file
|
||||||
|
* @return the name of the provider, or null if nothing is found
|
||||||
|
*/
|
||||||
|
private static String jarLookup(final ClassLoader loader) {
|
||||||
|
final ClassLoader cl = Objects.requireNonNull(loader);
|
||||||
|
String clsFromJar = null;
|
||||||
|
String service = "META-INF/services/" + property;
|
||||||
|
InputStream in;
|
||||||
|
BufferedReader reader;
|
||||||
|
|
||||||
|
try {
|
||||||
|
in = ss.getResourceAsStream(cl, service);
|
||||||
|
|
||||||
|
// If no provider found then try the current ClassLoader
|
||||||
|
if (in == null) {
|
||||||
|
in = ss.getResourceAsStream(null, service);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in != null) {
|
||||||
|
reader = new BufferedReader (new InputStreamReader (in, "UTF8"));
|
||||||
|
clsFromJar = reader.readLine ();
|
||||||
|
in.close ();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
return clsFromJar;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to find provider using the ServiceLoader API
|
||||||
|
*
|
||||||
|
* @param type Base class / Service interface of the factory to find.
|
||||||
|
*
|
||||||
|
* @return instance of provider class if found or null
|
||||||
|
*/
|
||||||
|
private static <T> T findServiceProvider(final Class<T> type, final ClassLoader loader)
|
||||||
|
throws SAXException {
|
||||||
|
ClassLoader cl = Objects.requireNonNull(loader);
|
||||||
|
try {
|
||||||
|
return AccessController.doPrivileged((PrivilegedAction<T>) () -> {
|
||||||
|
final ServiceLoader<T> serviceLoader;
|
||||||
|
serviceLoader = ServiceLoader.load(type, cl);
|
||||||
|
final Iterator<T> iterator = serviceLoader.iterator();
|
||||||
|
if (iterator.hasNext()) {
|
||||||
|
return iterator.next();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch(ServiceConfigurationError e) {
|
||||||
|
final RuntimeException x = new RuntimeException(
|
||||||
|
"Provider for " + type + " cannot be created", e);
|
||||||
|
throw new SAXException("Provider for " + type + " cannot be created", x);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue