From 8197c65fbb5ab0e3ce5b5ee07598cff96173dde0 Mon Sep 17 00:00:00 2001 From: lukaseder Date: Tue, 20 Nov 2018 10:25:01 +0100 Subject: [PATCH] [#7579] [#8044] Code generation fails on JDK9+ with javax.xml.bind.UnmarshalException: unexpected element when using external --- .../java/org/jooq/codegen/GenerationTool.java | 5 ++++ .../java/org/jooq/meta/xml/XMLDatabase.java | 14 +++-------- .../src/main/java/org/jooq/conf/MiniJAXB.java | 23 +++++++++++++++++++ 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/GenerationTool.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/GenerationTool.java index 78723b842d..5b8bef2e50 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/GenerationTool.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/GenerationTool.java @@ -90,6 +90,7 @@ import org.jooq.meta.jaxb.Target; import org.jooq.tools.JooqLogger; import org.jooq.tools.StringUtils; import org.jooq.tools.jdbc.JDBCUtils; +import org.jooq.util.xml.jaxb.InformationSchema; /** @@ -925,6 +926,10 @@ public class GenerationTool { return true; } }); + + // [#7579] [#8044] Workaround for obscure JAXB bug on JDK 9+ + xml = MiniJAXB.jaxbNamespaceBugWorkaround(xml, new InformationSchema()); + return (Configuration) unmarshaller.unmarshal(new StringReader(xml)); } catch (Throwable t) { diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/xml/XMLDatabase.java b/jOOQ-meta/src/main/java/org/jooq/meta/xml/XMLDatabase.java index 1fc5396bdf..57a390b63b 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/xml/XMLDatabase.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/xml/XMLDatabase.java @@ -243,18 +243,10 @@ public class XMLDatabase extends AbstractDatabase { "", ""); - // [#7579] On JDK 9, 10, depending on how JAXB is loaded onto the classpath / module path, - // the xmlns seems to be considered for (un)marshalling, or not. This seems to be - // a bug in JAXB, with no known tracking ID as of yet. - // The following quick fix tests the presence of the xmlns when marshalling, and if absent - // removes it prior to unmarshalling. - StringWriter test = new StringWriter(); + // [#7579] [#8044] Workaround for obscure JAXB bug on JDK 9+ + content = MiniJAXB.jaxbNamespaceBugWorkaround(content, new InformationSchema()); + try { - JAXB.marshal(new InformationSchema(), test); - - if (!test.toString().contains("xmlns")) - content = content.replaceAll("xmlns=\"[^\"]*\"", ""); - info = JAXB.unmarshal(new StringReader(content), InformationSchema.class); } catch (Throwable t) { diff --git a/jOOQ/src/main/java/org/jooq/conf/MiniJAXB.java b/jOOQ/src/main/java/org/jooq/conf/MiniJAXB.java index f00262450c..be62cf3be2 100644 --- a/jOOQ/src/main/java/org/jooq/conf/MiniJAXB.java +++ b/jOOQ/src/main/java/org/jooq/conf/MiniJAXB.java @@ -43,6 +43,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.StringReader; +import java.io.StringWriter; import java.io.Writer; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -314,4 +315,26 @@ public class MiniJAXB { throw new RuntimeException(e); } } + + /** + * This method is used internally by jOOQ to patch XML content in order to + * work around a bug in JAXB. + *

+ * [#7579] [#8044] On JDK 9, 10, depending on how JAXB is loaded onto the + * classpath / module path, the xmlns seems to be considered for + * (un)marshalling, or not. This seems to be a bug in JAXB, with no known + * tracking ID as of yet. + *

+ * The following quick fix tests the presence of the xmlns when marshalling, + * and if absent removes it prior to unmarshalling. + */ + public static String jaxbNamespaceBugWorkaround(String xml, Object annotated) { + StringWriter test = new StringWriter(); + JAXB.marshal(annotated, test); + + if (!test.toString().contains("xmlns")) + xml = xml.replaceAll("xmlns=\"[^\"]*\"", ""); + + return xml; + } }