From 0f3f979d16c9203c5440cd9a1dd87a19312279a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Fri, 12 Jul 2024 12:00:07 +0200 Subject: [PATCH] Align classloader used to create the JAXBContext This commit makes sure that JAXBContext.newInstance consistently use the target class classloader to detect the necessary resources. Previously, the current thread's context classloader was used, which could lead to not finding the required JAXB components. Closes gh-33158 --- .../http/codec/xml/JaxbContextContainer.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/JaxbContextContainer.java b/spring-web/src/main/java/org/springframework/http/codec/xml/JaxbContextContainer.java index f5eee44d743..ef76e6a0711 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/JaxbContextContainer.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/JaxbContextContainer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,7 +51,7 @@ final class JaxbContextContainer { private JAXBContext getJaxbContext(Class clazz) throws CodecException { return this.jaxbContexts.computeIfAbsent(clazz, key -> { try { - return JAXBContext.newInstance(clazz); + return createJaxbContext(clazz); } catch (JAXBException ex) { throw new CodecException( @@ -60,4 +60,20 @@ final class JaxbContextContainer { }); } + /** + * Create a {@link JAXBContext} for the given type, exposing the class + * ClassLoader as current thread context ClassLoader for the time of + * creating the context. + */ + private JAXBContext createJaxbContext(Class clazz) throws JAXBException { + ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(clazz.getClassLoader()); + return JAXBContext.newInstance(clazz); + } + finally { + Thread.currentThread().setContextClassLoader(currentClassLoader); + } + } + }