Skip to content

Commit

Permalink
fix jakartaee#243 upgrading JAXBContext and ContextFinder. Possible b…
Browse files Browse the repository at this point in the history
…reaking backward-compatibility

Signed-off-by: Antonio Santos Izaguirre <[email protected]>
  • Loading branch information
antoniosanct committed Feb 17, 2024
1 parent 2156e6a commit 4577cc2
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 20 deletions.
23 changes: 10 additions & 13 deletions api/src/main/java/jakarta/xml/bind/ContextFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,6 @@ public Object run() throws Exception {
}
}

/**
* Create an instance of a class using the thread context ClassLoader
*/
private static JAXBContext newInstance(Class<?>[] classes, Map<String, ?> properties, String className) throws JAXBException {
return newInstance(classes, properties, className, getContextClassLoader());
}

/**
* Create an instance of a class using passed in ClassLoader
*/
Expand Down Expand Up @@ -315,7 +308,7 @@ static JAXBContext find(String factoryId,
}

JAXBContextFactory obj = ServiceLoaderUtil.firstByServiceLoader(
JAXBContextFactory.class, logger, EXCEPTION_HANDLER);
JAXBContextFactory.class, logger, EXCEPTION_HANDLER, classLoader);

if (obj != null) {
ModuleUtil.delegateAddOpensToImplModule(contextPathClasses, obj.getClass());
Expand All @@ -341,8 +334,12 @@ static JAXBContext find(String factoryId,
}

static JAXBContext find(Class<?>[] classes, Map<String, ?> properties) throws JAXBException {
return find(classes, getContextClassLoader(), properties);
}

static JAXBContext find(Class<?>[] classes, ClassLoader classLoader, Map<String, ?> properties) throws JAXBException {
String factoryClassName = classNameFromSystemProperties();
if (factoryClassName != null) return newInstance(classes, properties, factoryClassName);
if (factoryClassName != null) return newInstance(classes, properties, factoryClassName, classLoader);

if (properties != null) {
Object ctxFactory = properties.get(JAXBContext.JAXB_CONTEXT_FACTORY);
Expand All @@ -361,12 +358,12 @@ static JAXBContext find(Class<?>[] classes, Map<String, ?> properties) throws JA
.stream()
.filter(Predicate.not(e -> JAXBContext.JAXB_CONTEXT_FACTORY.equals(e.getKey())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return newInstance(classes, props, factoryClassName);
return newInstance(classes, props, factoryClassName, classLoader);
}
}

JAXBContextFactory factory =
ServiceLoaderUtil.firstByServiceLoader(JAXBContextFactory.class, logger, EXCEPTION_HANDLER);
ServiceLoaderUtil.firstByServiceLoader(JAXBContextFactory.class, logger, EXCEPTION_HANDLER, classLoader);

if (factory != null) {
ModuleUtil.delegateAddOpensToImplModule(classes, factory.getClass());
Expand All @@ -378,12 +375,12 @@ static JAXBContext find(Class<?>[] classes, Map<String, ?> properties) throws JA
ServiceLoaderUtil.lookupUsingOSGiServiceLoader(JAXBContext.JAXB_CONTEXT_FACTORY, logger);

if (ctxFactoryClass != null) {
return newInstance(classes, properties, ctxFactoryClass);
return newInstance(classes, properties, ctxFactoryClass.toString(), classLoader);
}

// else no provider found
logger.fine("Trying to create the platform default provider");
return newInstance(classes, properties, DEFAULT_FACTORY_CLASS);
return newInstance(classes, properties, DEFAULT_FACTORY_CLASS, classLoader);
}

private static String classNameFromSystemProperties() throws JAXBException {
Expand Down
13 changes: 9 additions & 4 deletions api/src/main/java/jakarta/xml/bind/JAXBContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
* factory class. This phase of the look up enables per-JVM override of the Jakarta XML Binding implementation.
*
* <li>
* If the property {@link #JAXB_CONTEXT_FACTORY} exists in the {@code Map<String, ?>} passed to {@link #newInstance(Class[], Map)}
* If the property {@link #JAXB_CONTEXT_FACTORY} exists in the {@code Map<String, ?>} passed to {@link #newInstance(Class[], ClassLoader, Map)}
* or to {@link #newInstance(String, ClassLoader, Map)}, then its value is assumed to be the fully qualified provider factory class name.
* This phase of the look up enables context sensitive selection of the Jakarta XML Binding implementation.
*
Expand Down Expand Up @@ -543,7 +543,12 @@ public static JAXBContext newInstance( String contextPath,
public static JAXBContext newInstance( Class<?> ... classesToBeBound )
throws JAXBException {

return newInstance(classesToBeBound,Collections.<String,Object>emptyMap());
return newInstance(classesToBeBound, getContextClassLoader(), Collections.<String,Object>emptyMap());
}

public static JAXBContext newInstance( Class<?>[] classesToBeBound, ClassLoader classLoader)
throws JAXBException {
return newInstance(classesToBeBound, classLoader, Collections.<String,Object>emptyMap());
}

/**
Expand Down Expand Up @@ -588,7 +593,7 @@ public static JAXBContext newInstance( Class<?> ... classesToBeBound )
*
* @since 1.6, JAXB 2.0
*/
public static JAXBContext newInstance( Class<?>[] classesToBeBound, Map<String,?> properties )
public static JAXBContext newInstance( Class<?>[] classesToBeBound, ClassLoader classLoader, Map<String,?> properties )
throws JAXBException {

if (classesToBeBound == null) {
Expand All @@ -602,7 +607,7 @@ public static JAXBContext newInstance( Class<?>[] classesToBeBound, Map<String,?
}
}

return ContextFinder.find(classesToBeBound,properties);
return ContextFinder.find(classesToBeBound, classLoader, properties);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/java/jakarta/xml/bind/JAXBContextFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public interface JAXBContextFactory {
* Create a new instance of a {@code JAXBContext} class.
*
* <p>
* For semantics see {@link jakarta.xml.bind.JAXBContext#newInstance(Class[], java.util.Map)}
* For semantics see {@link jakarta.xml.bind.JAXBContext#newInstance(Class[], ClassLoader, java.util.Map)}
*
* @param classesToBeBound
* List of java classes to be recognized by the new {@link JAXBContext}.
Expand Down
18 changes: 16 additions & 2 deletions api/src/main/java/jakarta/xml/bind/ServiceLoaderUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ class ServiceLoaderUtil {

static <P, T extends Exception> P firstByServiceLoader(Class<P> spiClass,
Logger logger,
ExceptionHandler<T> handler) throws T {
ExceptionHandler<T> handler,
ClassLoader classLoader) throws T {
// service discovery
try {
ServiceLoader<P> serviceLoader = ServiceLoader.load(spiClass);
ServiceLoader<P> serviceLoader = ServiceLoader.load(spiClass, classLoader);

for (P impl : serviceLoader) {
logger.log(Level.FINE, "ServiceProvider loading Facility used; returning object [{0}]",
Expand Down Expand Up @@ -129,6 +130,19 @@ static <T extends Exception> Object newInstance(String className,
}
}

static <T extends Exception> Object newInstance(String className,
String defaultImplClassName,
ClassLoader classLoader,
final ExceptionHandler<T> handler) throws T {
try {
return safeLoadClass(className, defaultImplClassName, classLoader).getConstructor().newInstance();
} catch (ClassNotFoundException x) {
throw handler.createException(x, "Provider " + className + " not found");
} catch (Exception x) {
throw handler.createException(x, "Provider " + className + " could not be instantiated: " + x);
}
}

static Class<?> safeLoadClass(String className,
String defaultImplClassName,
ClassLoader classLoader) throws ClassNotFoundException {
Expand Down

0 comments on commit 4577cc2

Please sign in to comment.