< prev index next >
src/java.xml.bind/share/classes/javax/xml/bind/ContextFinder.java
Print this page
*** 66,75 ****
--- 66,78 ----
* <p>
* For this reason, we have to hard-code the class name into the API.
*/
private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.internal.bind.v2.ContextFactory";
+ // previous value of JAXBContext.JAXB_CONTEXT_FACTORY, using also this to ensure backwards compatibility
+ private static final String JAXB_CONTEXT_FACTORY_DEPRECATED = "javax.xml.bind.context.factory";
+
private static final Logger logger;
static {
logger = Logger.getLogger("javax.xml.bind");
try {
*** 90,99 ****
--- 93,110 ----
// just to be extra safe. in particular System.getProperty may throw
// SecurityException.
}
}
+ private static ServiceLoaderUtil.ExceptionHandler<JAXBException> EXCEPTION_HANDLER =
+ new ServiceLoaderUtil.ExceptionHandler<JAXBException>() {
+ @Override
+ public JAXBException createException(Throwable throwable, String message) {
+ return new JAXBException(message, throwable);
+ }
+ };
+
/**
* If the {@link InvocationTargetException} wraps an exception that shouldn't be wrapped,
* throw the wrapped exception.
*/
private static void handleInvocationTargetException(InvocationTargetException x) throws JAXBException {
*** 157,167 ****
// some other type of exception - just wrap it
throw new JAXBException(Messages.format(Messages.COULD_NOT_INSTANTIATE, className, x), x);
}
}
! static JAXBContext newInstance(String contextPath, Class spFactory, ClassLoader classLoader, Map properties) throws JAXBException {
try {
/*
* javax.xml.bind.context.factory points to a class which has a
* static method called 'createContext' that
--- 168,181 ----
// some other type of exception - just wrap it
throw new JAXBException(Messages.format(Messages.COULD_NOT_INSTANTIATE, className, x), x);
}
}
! static JAXBContext newInstance(String contextPath,
! Class spFactory,
! ClassLoader classLoader,
! Map properties) throws JAXBException {
try {
/*
* javax.xml.bind.context.factory points to a class which has a
* static method called 'createContext' that
*** 237,257 ****
static JAXBContext newInstance(Class[] classes,
Map properties,
Class spFactory) throws JAXBException {
try {
Method m = spFactory.getMethod("createContext", Class[].class, Map.class);
Object context = m.invoke(null, classes, properties);
if (!(context instanceof JAXBContext)) {
// the cast would fail, so generate an exception with a nice message
throw handleClassCastException(context.getClass(), JAXBContext.class);
}
return (JAXBContext) context;
! } catch (NoSuchMethodException e) {
! throw new JAXBException(e);
! } catch (IllegalAccessException e) {
throw new JAXBException(e);
} catch (InvocationTargetException e) {
handleInvocationTargetException(e);
Throwable x = e;
if (e.getTargetException() != null)
--- 251,272 ----
static JAXBContext newInstance(Class[] classes,
Map properties,
Class spFactory) throws JAXBException {
try {
+
Method m = spFactory.getMethod("createContext", Class[].class, Map.class);
Object context = m.invoke(null, classes, properties);
if (!(context instanceof JAXBContext)) {
// the cast would fail, so generate an exception with a nice message
throw handleClassCastException(context.getClass(), JAXBContext.class);
}
return (JAXBContext) context;
!
! } catch (NoSuchMethodException | IllegalAccessException e) {
throw new JAXBException(e);
+
} catch (InvocationTargetException e) {
handleInvocationTargetException(e);
Throwable x = e;
if (e.getTargetException() != null)
*** 259,271 ****
throw new JAXBException(x);
}
}
! static JAXBContext find(String factoryId, String contextPath, ClassLoader classLoader, Map properties) throws JAXBException {
!
! // TODO: do we want/need another layer of searching in $java.home/lib/jaxb.properties like JAXP?
StringTokenizer packages = new StringTokenizer(contextPath, ":");
if (!packages.hasMoreTokens()) {
// no context is specified
throw new JAXBException(Messages.format(Messages.NO_PACKAGE_IN_CONTEXTPATH));
--- 274,287 ----
throw new JAXBException(x);
}
}
! static JAXBContext find(String factoryId,
! String contextPath,
! ClassLoader classLoader,
! Map properties) throws JAXBException {
StringTokenizer packages = new StringTokenizer(contextPath, ":");
if (!packages.hasMoreTokens()) {
// no context is specified
throw new JAXBException(Messages.format(Messages.NO_PACKAGE_IN_CONTEXTPATH));
*** 273,382 ****
// search for jaxb.properties in the class loader of each class first
logger.fine("Searching jaxb.properties");
while (packages.hasMoreTokens()) {
// com.acme.foo - > com/acme/foo/jaxb.properties
! String className = classNameFromPackageProperties(factoryId, classLoader, packages.nextToken(":").replace('.', '/'));
! if (className != null) return newInstance(contextPath, className, classLoader, properties);
}
String factoryName = classNameFromSystemProperties();
if (factoryName != null) return newInstance(contextPath, factoryName, classLoader, properties);
! Class ctxFactory = (Class) ServiceLoaderUtil.lookupUsingOSGiServiceLoader("javax.xml.bind.JAXBContext", logger);
! if (ctxFactory != null) {
! return newInstance(contextPath, ctxFactory, classLoader, properties);
! }
! // TODO: SPEC change required! This is supposed to be!
! // JAXBContext obj = firstByServiceLoader(JAXBContext.class, EXCEPTION_HANDLER);
! // if (obj != null) return obj;
! // TODO: Deprecated - SPEC change required!
factoryName = firstByServiceLoaderDeprecated(JAXBContext.class, classLoader);
if (factoryName != null) return newInstance(contextPath, factoryName, classLoader, properties);
// else no provider found
logger.fine("Trying to create the platform default provider");
return newInstance(contextPath, PLATFORM_DEFAULT_FACTORY_CLASS, classLoader, properties);
}
! static JAXBContext find(Class[] classes, Map properties) throws JAXBException {
// search for jaxb.properties in the class loader of each class first
logger.fine("Searching jaxb.properties");
for (final Class c : classes) {
// this classloader is used only to load jaxb.properties, so doing this should be safe.
! if (c.getPackage() == null) continue; // this is possible for primitives, arrays, and classes that are loaded by poorly implemented ClassLoaders
// TODO: do we want to optimize away searching the same package? org.Foo, org.Bar, com.Baz
// classes from the same package might come from different class loades, so it might be a bad idea
// TODO: it's easier to look things up from the class
// c.getResourceAsStream("jaxb.properties");
! String className = classNameFromPackageProperties(JAXBContext.JAXB_CONTEXT_FACTORY, getClassClassLoader(c), c.getPackage().getName().replace('.', '/'));
! if (className != null) return newInstance(classes, properties, className);
}
! String factoryName = classNameFromSystemProperties();
! if (factoryName != null) return newInstance(classes, properties, factoryName);
! Class ctxFactoryClass = (Class) ServiceLoaderUtil.lookupUsingOSGiServiceLoader("javax.xml.bind.JAXBContext", logger);
! if (ctxFactoryClass != null) {
! return newInstance(classes, properties, ctxFactoryClass);
! }
! // TODO: to be removed - deprecated!!! Requires SPEC change!!!
String className = firstByServiceLoaderDeprecated(JAXBContext.class, getContextClassLoader());
if (className != null) return newInstance(classes, properties, className);
! // // TODO: supposed to be:
! // obj = firstByServiceLoader(JAXBContext.class, EXCEPTION_HANDLER);
! // if (obj != null) return obj;
// else no provider found
logger.fine("Trying to create the platform default provider");
return newInstance(classes, properties, PLATFORM_DEFAULT_FACTORY_CLASS);
}
! private static String classNameFromPackageProperties(String factoryId, ClassLoader classLoader, String packageName) throws JAXBException {
String resourceName = packageName + "/jaxb.properties";
logger.log(Level.FINE, "Trying to locate {0}", resourceName);
Properties props = loadJAXBProperties(classLoader, resourceName);
if (props != null) {
if (props.containsKey(factoryId)) {
return props.getProperty(factoryId);
- } else {
- throw new JAXBException(Messages.format(Messages.MISSING_PROPERTY, packageName, factoryId));
}
}
return null;
}
private static String classNameFromSystemProperties() throws JAXBException {
! logger.log(Level.FINE, "Checking system property {0}", JAXBContext.JAXB_CONTEXT_FACTORY);
! // search for a system property second (javax.xml.bind.JAXBContext)
! String factoryClassName = AccessController.doPrivileged(new GetPropertyAction(JAXBContext.JAXB_CONTEXT_FACTORY));
if (factoryClassName != null) {
- logger.log(Level.FINE, " found {0}", factoryClassName);
return factoryClassName;
! } else { // leave this here to assure compatibility
! logger.fine(" not found");
! logger.log(Level.FINE, "Checking system property {0}", JAXBContext.class.getName());
! factoryClassName = AccessController.doPrivileged(new GetPropertyAction(JAXBContext.class.getName()));
if (factoryClassName != null) {
- logger.log(Level.FINE, " found {0}", factoryClassName);
return factoryClassName;
- } else {
- logger.fine(" not found");
}
}
return null;
}
! private static Properties loadJAXBProperties(ClassLoader classLoader, String propFileName) throws JAXBException {
Properties props = null;
try {
URL url;
if (classLoader == null)
--- 289,447 ----
// search for jaxb.properties in the class loader of each class first
logger.fine("Searching jaxb.properties");
while (packages.hasMoreTokens()) {
// com.acme.foo - > com/acme/foo/jaxb.properties
! String factoryClassName =
! classNameFromPackageProperties(
! classLoader,
! packages.nextToken(":").replace('.', '/'),
! factoryId,
! JAXB_CONTEXT_FACTORY_DEPRECATED);
!
! if (factoryClassName != null) {
! return newInstance(contextPath, factoryClassName, classLoader, properties);
! }
}
String factoryName = classNameFromSystemProperties();
if (factoryName != null) return newInstance(contextPath, factoryName, classLoader, properties);
! JAXBContextFactory obj = ServiceLoaderUtil.firstByServiceLoader(
! JAXBContextFactory.class, logger, EXCEPTION_HANDLER);
! if (obj != null) return obj.createContext(contextPath, classLoader, properties);
! // to ensure backwards compatibility
factoryName = firstByServiceLoaderDeprecated(JAXBContext.class, classLoader);
if (factoryName != null) return newInstance(contextPath, factoryName, classLoader, properties);
+ Class ctxFactory = (Class) ServiceLoaderUtil.lookupUsingOSGiServiceLoader(
+ "javax.xml.bind.JAXBContext", logger);
+
+ if (ctxFactory != null) {
+ return newInstance(contextPath, ctxFactory, classLoader, properties);
+ }
+
// else no provider found
logger.fine("Trying to create the platform default provider");
return newInstance(contextPath, PLATFORM_DEFAULT_FACTORY_CLASS, classLoader, properties);
}
! static JAXBContext find(Class<?>[] classes, Map<String, ?> properties) throws JAXBException {
// search for jaxb.properties in the class loader of each class first
logger.fine("Searching jaxb.properties");
for (final Class c : classes) {
// this classloader is used only to load jaxb.properties, so doing this should be safe.
! // this is possible for primitives, arrays, and classes that are
! // loaded by poorly implemented ClassLoaders
! if (c.getPackage() == null) continue;
// TODO: do we want to optimize away searching the same package? org.Foo, org.Bar, com.Baz
// classes from the same package might come from different class loades, so it might be a bad idea
// TODO: it's easier to look things up from the class
// c.getResourceAsStream("jaxb.properties");
! String factoryClassName =
! classNameFromPackageProperties(
! getClassClassLoader(c),
! c.getPackage().getName().replace('.', '/'),
! JAXBContext.JAXB_CONTEXT_FACTORY, JAXB_CONTEXT_FACTORY_DEPRECATED);
!
! if (factoryClassName != null) return newInstance(classes, properties, factoryClassName);
}
! String factoryClassName = classNameFromSystemProperties();
! if (factoryClassName != null) return newInstance(classes, properties, factoryClassName);
! JAXBContextFactory factory =
! ServiceLoaderUtil.firstByServiceLoader(JAXBContextFactory.class, logger, EXCEPTION_HANDLER);
!
! if (factory != null) return factory.createContext(classes, properties);
! // to ensure backwards compatibility
String className = firstByServiceLoaderDeprecated(JAXBContext.class, getContextClassLoader());
if (className != null) return newInstance(classes, properties, className);
! logger.fine("Trying to create the platform default provider");
! Class ctxFactoryClass =
! (Class) ServiceLoaderUtil.lookupUsingOSGiServiceLoader("javax.xml.bind.JAXBContext", logger);
!
! if (ctxFactoryClass != null) {
! return newInstance(classes, properties, ctxFactoryClass);
! }
// else no provider found
logger.fine("Trying to create the platform default provider");
return newInstance(classes, properties, PLATFORM_DEFAULT_FACTORY_CLASS);
}
! /**
! * first factoryId should be the preffered one,
! * more of those can be provided to support backwards compatibility
! */
! private static String classNameFromPackageProperties(ClassLoader classLoader,
! String packageName,
! String ... factoryIds) throws JAXBException {
!
String resourceName = packageName + "/jaxb.properties";
logger.log(Level.FINE, "Trying to locate {0}", resourceName);
Properties props = loadJAXBProperties(classLoader, resourceName);
if (props != null) {
+ for(String factoryId : factoryIds) {
if (props.containsKey(factoryId)) {
return props.getProperty(factoryId);
}
}
+ throw new JAXBException(Messages.format(Messages.MISSING_PROPERTY, packageName, factoryIds[0]));
+ }
return null;
}
private static String classNameFromSystemProperties() throws JAXBException {
!
! String factoryClassName = getSystemProperty(JAXBContext.JAXB_CONTEXT_FACTORY);
if (factoryClassName != null) {
return factoryClassName;
! }
! // leave this here to assure compatibility
! factoryClassName = getDeprecatedSystemProperty(JAXB_CONTEXT_FACTORY_DEPRECATED);
if (factoryClassName != null) {
return factoryClassName;
}
+ // leave this here to assure compatibility
+ factoryClassName = getDeprecatedSystemProperty(JAXBContext.class.getName());
+ if (factoryClassName != null) {
+ return factoryClassName;
}
return null;
}
! private static String getDeprecatedSystemProperty(String property) {
! String value = getSystemProperty(property);
! if (value != null) {
! logger.log(Level.WARNING, "Using non-standard property: {0}. Property {1} should be used instead.",
! new Object[] {property, JAXBContext.JAXB_CONTEXT_FACTORY});
! }
! return value;
! }
!
! private static String getSystemProperty(String property) {
! logger.log(Level.FINE, "Checking system property {0}", property);
! String value = AccessController.doPrivileged(new GetPropertyAction(property));
! if (value != null) {
! logger.log(Level.FINE, " found {0}", value);
! } else {
! logger.log(Level.FINE, " not found");
! }
! return value;
! }
!
! private static Properties loadJAXBProperties(ClassLoader classLoader,
! String propFileName) throws JAXBException {
Properties props = null;
try {
URL url;
if (classLoader == null)
*** 478,498 ****
}
});
}
}
- // TODO: to be removed - SPEC change required
// ServiceLoaderUtil.firstByServiceLoaderDeprecated should be used instead.
@Deprecated
! static String firstByServiceLoaderDeprecated(Class spiClass, ClassLoader classLoader) throws JAXBException {
final String jaxbContextFQCN = spiClass.getName();
logger.fine("Searching META-INF/services");
// search META-INF services next
BufferedReader r = null;
! final String resource = new StringBuilder().append("META-INF/services/").append(jaxbContextFQCN).toString();
try {
final InputStream resourceStream =
(classLoader == null) ?
ClassLoader.getSystemResourceAsStream(resource) :
classLoader.getResourceAsStream(resource);
--- 543,564 ----
}
});
}
}
// ServiceLoaderUtil.firstByServiceLoaderDeprecated should be used instead.
@Deprecated
! static String firstByServiceLoaderDeprecated(Class spiClass,
! ClassLoader classLoader) throws JAXBException {
!
final String jaxbContextFQCN = spiClass.getName();
logger.fine("Searching META-INF/services");
// search META-INF services next
BufferedReader r = null;
! final String resource = "META-INF/services/" + jaxbContextFQCN;
try {
final InputStream resourceStream =
(classLoader == null) ?
ClassLoader.getSystemResourceAsStream(resource) :
classLoader.getResourceAsStream(resource);
*** 508,520 ****
return factoryClassName;
} else {
logger.log(Level.FINE, "Unable to load:{0}", resource);
return null;
}
- } catch (UnsupportedEncodingException e) {
- // should never happen
- throw new JAXBException(e);
} catch (IOException e) {
throw new JAXBException(e);
} finally {
try {
if (r != null) {
--- 574,583 ----
< prev index next >