< prev index next >
jaxws/src/java.xml.bind/share/classes/javax/xml/bind/ContextFinder.java
Print this page
@@ -148,17 +148,18 @@
/**
* Create an instance of a class using the specified ClassLoader
*/
static JAXBContext newInstance(String contextPath,
+ Class[] contextPathClasses,
String className,
ClassLoader classLoader,
Map properties) throws JAXBException {
try {
Class spFactory = ServiceLoaderUtil.safeLoadClass(className, PLATFORM_DEFAULT_FACTORY_CLASS, classLoader);
- return newInstance(contextPath, spFactory, classLoader, properties);
+ return newInstance(contextPath, contextPathClasses, spFactory, classLoader, properties);
} catch (ClassNotFoundException x) {
throw new JAXBException(Messages.format(Messages.DEFAULT_PROVIDER_NOT_FOUND), x);
} catch (RuntimeException | JAXBException x) {
// avoid wrapping RuntimeException to JAXBException,
@@ -173,10 +174,11 @@
throw new JAXBException(Messages.format(Messages.COULD_NOT_INSTANTIATE, className, x), x);
}
}
static JAXBContext newInstance(String contextPath,
+ Class[] contextPathClasses,
Class spFactory,
ClassLoader classLoader,
Map properties) throws JAXBException {
try {
@@ -210,10 +212,13 @@
if (!(context instanceof JAXBContext)) {
// the cast would fail, so generate an exception with a nice message
throw handleClassCastException(context.getClass(), JAXBContext.class);
}
+
+ ModuleUtil.delegateAddOpensToImplModule(contextPathClasses, spFactory);
+
return (JAXBContext) context;
} catch (InvocationTargetException x) {
// throw if it is exception not to be wrapped
// otherwise, wrap with a JAXBException
Throwable e = handleInvocationTargetException(x);
@@ -275,10 +280,11 @@
Object context = m.invoke(obj, classes, properties);
if (!(context instanceof JAXBContext)) {
// the cast would fail, so generate an exception with a nice message
throw handleClassCastException(context.getClass(), JAXBContext.class);
}
+ ModuleUtil.delegateAddOpensToImplModule(classes, spFactory);
return (JAXBContext) context;
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new JAXBException(e);
} catch (InvocationTargetException e) {
@@ -293,54 +299,56 @@
static JAXBContext find(String factoryId,
String contextPath,
ClassLoader classLoader,
Map properties) throws JAXBException {
- StringTokenizer packages = new StringTokenizer(contextPath, ":");
- if (!packages.hasMoreTokens()) {
+ if (contextPath == null || contextPath.isEmpty()) {
// no context is specified
throw new JAXBException(Messages.format(Messages.NO_PACKAGE_IN_CONTEXTPATH));
}
- // 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);
+ //ModuleUtil is mr-jar class, scans context path for jaxb classes on jdk9 and higher
+ Class[] contextPathClasses = ModuleUtil.getClassesFromContextPath(contextPath, classLoader);
- if (factoryClassName != null) {
- return newInstance(contextPath, factoryClassName, classLoader, properties);
+ //first try with classloader#getResource
+ String factoryClassName = jaxbProperties(contextPath, classLoader, factoryId);
+ if (factoryClassName == null && contextPathClasses != null) {
+ //try with class#getResource
+ factoryClassName = jaxbProperties(contextPathClasses, factoryId);
}
+
+ if (factoryClassName != null) {
+ return newInstance(contextPath, contextPathClasses, factoryClassName, classLoader, properties);
}
+
String factoryName = classNameFromSystemProperties();
- if (factoryName != null) return newInstance(contextPath, factoryName, classLoader, properties);
+ if (factoryName != null) return newInstance(contextPath, contextPathClasses, factoryName, classLoader, properties);
JAXBContextFactory obj = ServiceLoaderUtil.firstByServiceLoader(
JAXBContextFactory.class, logger, EXCEPTION_HANDLER);
- if (obj != null) return obj.createContext(contextPath, classLoader, properties);
+ if (obj != null) {
+ JAXBContext context = obj.createContext(contextPath, classLoader, properties);
+ ModuleUtil.delegateAddOpensToImplModule(contextPathClasses, obj.getClass());
+ return context;
+ }
// to ensure backwards compatibility
factoryName = firstByServiceLoaderDeprecated(JAXBContext.class, classLoader);
- if (factoryName != null) return newInstance(contextPath, factoryName, classLoader, properties);
+ if (factoryName != null) return newInstance(contextPath, contextPathClasses, factoryName, classLoader, properties);
Class ctxFactory = (Class) ServiceLoaderUtil.lookupUsingOSGiServiceLoader(
"javax.xml.bind.JAXBContext", logger);
if (ctxFactory != null) {
- return newInstance(contextPath, ctxFactory, classLoader, properties);
+ return newInstance(contextPath, contextPathClasses, 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);
+ return newInstance(contextPath, contextPathClasses, 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
@@ -354,26 +362,35 @@
// 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");
+ URL jaxbPropertiesUrl = getResourceUrl(c, "jaxb.properties");
+
+ if (jaxbPropertiesUrl != null) {
+
String factoryClassName =
classNameFromPackageProperties(
- getClassClassLoader(c),
- c.getPackage().getName().replace('.', '/'),
+ jaxbPropertiesUrl,
JAXBContext.JAXB_CONTEXT_FACTORY, JAXB_CONTEXT_FACTORY_DEPRECATED);
- if (factoryClassName != null) return newInstance(classes, properties, factoryClassName);
+ 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);
+ if (factory != null) {
+ JAXBContext context = factory.createContext(classes, properties);
+ ModuleUtil.delegateAddOpensToImplModule(classes, factory.getClass());
+ return context;
+ }
// to ensure backwards compatibility
String className = firstByServiceLoaderDeprecated(JAXBContext.class, getContextClassLoader());
if (className != null) return newInstance(classes, properties, className);
@@ -393,27 +410,25 @@
/**
* first factoryId should be the preferred one,
* more of those can be provided to support backwards compatibility
*/
- private static String classNameFromPackageProperties(ClassLoader classLoader,
- String packageName,
+ private static String classNameFromPackageProperties(URL packagePropertiesUrl,
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) {
+ logger.log(Level.FINE, "Trying to locate {0}", packagePropertiesUrl.toString());
+ Properties props = loadJAXBProperties(packagePropertiesUrl);
for(String factoryId : factoryIds) {
if (props.containsKey(factoryId)) {
return props.getProperty(factoryId);
}
}
+ //Factory key not found
+ String propertiesUrl = packagePropertiesUrl.toExternalForm();
+ String packageName = propertiesUrl.substring(0, propertiesUrl.indexOf("/jaxb.properties"));
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) {
@@ -450,34 +465,44 @@
logger.log(Level.FINE, " not found");
}
return value;
}
- private static Properties loadJAXBProperties(ClassLoader classLoader,
- String propFileName) throws JAXBException {
+ private static Properties loadJAXBProperties(URL url) throws JAXBException {
- Properties props = null;
try {
- URL url;
- if (classLoader == null)
- url = ClassLoader.getSystemResource(propFileName);
- else
- url = classLoader.getResource(propFileName);
-
- if (url != null) {
+ Properties props;
logger.log(Level.FINE, "loading props from {0}", url);
props = new Properties();
InputStream is = url.openStream();
props.load(is);
is.close();
- }
+ return props;
} catch (IOException ioe) {
- logger.log(Level.FINE, "Unable to load " + propFileName, ioe);
+ logger.log(Level.FINE, "Unable to load " + url.toString(), ioe);
throw new JAXBException(ioe.toString(), ioe);
}
+ }
- return props;
+ /**
+ * If run on JPMS package containing resource must be open unconditionally.
+ *
+ * @param classLoader classloader to load resource with
+ * @param resourceName qualified name of the resource
+ * @return resource url if found
+ */
+ private static URL getResourceUrl(ClassLoader classLoader, String resourceName) {
+ URL url;
+ if (classLoader == null)
+ url = ClassLoader.getSystemResource(resourceName);
+ else
+ url = classLoader.getResource(resourceName);
+ return url;
+ }
+
+ private static URL getResourceUrl(Class<?> clazz, String resourceName) {
+ return clazz.getResource(resourceName);
}
/**
* Search the given ClassLoader for an instance of the specified class and
@@ -604,6 +629,30 @@
logger.log(Level.SEVERE, "Unable to close resource: " + resource, ex);
}
}
}
+ private static String jaxbProperties(String contextPath, ClassLoader classLoader, String factoryId) throws JAXBException {
+ String[] packages = contextPath.split(":");
+
+ for (String pkg : packages) {
+ String pkgUrl = pkg.replace('.', '/');
+ URL jaxbPropertiesUrl = getResourceUrl(classLoader, pkgUrl + "/jaxb.properties");
+ if (jaxbPropertiesUrl != null) {
+ return classNameFromPackageProperties(jaxbPropertiesUrl,
+ factoryId, JAXB_CONTEXT_FACTORY_DEPRECATED);
+ }
+ }
+ return null;
+ }
+
+ private static String jaxbProperties(Class[] classesFromContextPath, String factoryId) throws JAXBException {
+ for (Class c : classesFromContextPath) {
+ URL jaxbPropertiesUrl = getResourceUrl(c, "jaxb.properties");
+ if (jaxbPropertiesUrl != null) {
+ return classNameFromPackageProperties(jaxbPropertiesUrl, factoryId, JAXB_CONTEXT_FACTORY_DEPRECATED);
+ }
+ }
+ return null;
+ }
+
}
< prev index next >