diff options
Diffstat (limited to 'src/main/java/at/gv/egiz/moazs/util')
-rw-r--r-- | src/main/java/at/gv/egiz/moazs/util/JAXBClassNotFoundFix.java | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/main/java/at/gv/egiz/moazs/util/JAXBClassNotFoundFix.java b/src/main/java/at/gv/egiz/moazs/util/JAXBClassNotFoundFix.java new file mode 100644 index 0000000..9e72286 --- /dev/null +++ b/src/main/java/at/gv/egiz/moazs/util/JAXBClassNotFoundFix.java @@ -0,0 +1,55 @@ +package at.gv.egiz.moazs.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.function.Supplier; + +import static at.gv.egiz.moazs.MoaZSException.moaZSException; + +@Component +public class JAXBClassNotFoundFix { + + private static final Logger log = LoggerFactory.getLogger(JAXBClassNotFoundFix.class); + + /** + * Solves JAXB's "ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory" in Java >= 9 + * by running func in a dedicated thread which has its context classloader replaced with a classloader that finds + * the ContextFactory. + * + * See https://sjhannah.com/blog/2018/11/21/jaxb-hell-on-jdk-9/ + * Note: "runInTheadWithClassClassLoader" is not a typo. + * @param func function that is called in a dedicated thread. + * @param <A> return value of func. + * @return + */ + public static <A> A runInTheadWithClassClassLoader(Supplier<A> func) { + + final Object[] result = new Object[1]; + final Exception[] error = new Exception[1]; + + Thread t = new Thread(() -> { + try { + result[0] = func.get(); + } catch (Exception ex) { + error[0] = ex; + } + }); + + t.setContextClassLoader(JAXBClassNotFoundFix.class.getClassLoader()); + t.start(); + + try { + t.join(); + } catch (InterruptedException ex) { + log.error("Interrupted. ", ex); + } + + if (error[0] != null) { + throw moaZSException("Could not run function.", error[0]); + } + + return (A)result[0]; + } +} |