diff --git a/extensions/jaxb/deployment/pom.xml b/extensions/jaxb/deployment/pom.xml
index 30e68d12c9c46..fc665ddc3fe65 100644
--- a/extensions/jaxb/deployment/pom.xml
+++ b/extensions/jaxb/deployment/pom.xml
@@ -28,7 +28,12 @@
io.quarkus
- quarkus-junit5
+ quarkus-junit5-internal
+ test
+
+
+ org.assertj
+ assertj-core
test
diff --git a/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/FilteredJaxbClassesToBeBoundBuildItem.java b/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/FilteredJaxbClassesToBeBoundBuildItem.java
new file mode 100644
index 0000000000000..347e3cf661c6b
--- /dev/null
+++ b/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/FilteredJaxbClassesToBeBoundBuildItem.java
@@ -0,0 +1,70 @@
+package io.quarkus.jaxb.deployment;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import io.quarkus.builder.item.SimpleBuildItem;
+import io.quarkus.jaxb.deployment.utils.JaxbType;
+
+/**
+ * List of classes to be bound in the JAXB context. Aggregates all classes passed via
+ * {@link JaxbClassesToBeBoundBuildItem}. All class names excluded via {@code quarkus.jaxb.exclude-classes} are not
+ * present in this list.
+ */
+public final class FilteredJaxbClassesToBeBoundBuildItem extends SimpleBuildItem {
+
+ private final List> classes;
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ private FilteredJaxbClassesToBeBoundBuildItem(List> classes) {
+ this.classes = classes;
+ }
+
+ public List> getClasses() {
+ return new ArrayList<>(classes);
+ }
+
+ public static class Builder {
+ private final Set classNames = new LinkedHashSet<>();
+ private final Set classNameExcludes = new LinkedHashSet<>();
+
+ public Builder classNameExcludes(Collection classNameExcludes) {
+ for (String className : classNameExcludes) {
+ this.classNameExcludes.add(className);
+ }
+ return this;
+ }
+
+ public Builder classNames(Collection classNames) {
+ for (String className : classNames) {
+ this.classNames.add(className);
+ }
+ return this;
+ }
+
+ public FilteredJaxbClassesToBeBoundBuildItem build() {
+ final List> classes = classNames.stream()
+ .filter(className -> !this.classNameExcludes.contains(className))
+ .map(FilteredJaxbClassesToBeBoundBuildItem::getClassByName)
+ .filter(JaxbType::isValidType)
+ .collect(Collectors.toList());
+
+ return new FilteredJaxbClassesToBeBoundBuildItem(classes);
+ }
+ }
+
+ private static Class> getClassByName(String name) {
+ try {
+ return Class.forName(name, false, Thread.currentThread().getContextClassLoader());
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbClassesToBeBoundBuildItem.java b/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbClassesToBeBoundBuildItem.java
index 199842f0b7586..dd76cb8f5844f 100644
--- a/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbClassesToBeBoundBuildItem.java
+++ b/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbClassesToBeBoundBuildItem.java
@@ -1,19 +1,24 @@
package io.quarkus.jaxb.deployment;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import io.quarkus.builder.item.MultiBuildItem;
/**
- * List of classes to be bound in the JAXB context.
+ * List of class names to be bound in the JAXB context. Note that some of the class names can be removed via
+ * {@code quarkus.jaxb.exclude-classes}.
+ *
+ * @see FilteredJaxbClassesToBeBoundBuildItem
*/
public final class JaxbClassesToBeBoundBuildItem extends MultiBuildItem {
private final List classes;
public JaxbClassesToBeBoundBuildItem(List classes) {
- this.classes = Objects.requireNonNull(classes);
+ this.classes = Objects.requireNonNull(Collections.unmodifiableList(new ArrayList<>(classes)));
}
public List getClasses() {
diff --git a/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java b/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java
index 4ab8f71950f88..aa6fd86771366 100644
--- a/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java
+++ b/extensions/jaxb/deployment/src/main/java/io/quarkus/jaxb/deployment/JaxbProcessor.java
@@ -1,19 +1,16 @@
package io.quarkus.jaxb.deployment;
-import static io.quarkus.jaxb.deployment.utils.JaxbType.isValidType;
-
import java.io.IOError;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
+import jakarta.enterprise.inject.spi.DeploymentException;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.annotation.XmlAccessOrder;
@@ -58,6 +55,9 @@
import org.jboss.logging.Logger;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
+import io.quarkus.arc.deployment.SynthesisFinishedBuildItem;
+import io.quarkus.arc.processor.BeanInfo;
+import io.quarkus.arc.processor.BeanResolver;
import io.quarkus.deployment.ApplicationArchive;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
@@ -297,29 +297,62 @@ void registerClasses(
}
@BuildStep
- @Record(ExecutionTime.STATIC_INIT)
- void setupJaxbContextConfig(JaxbConfig config,
- List classesToBeBoundBuildItems,
- JaxbContextConfigRecorder jaxbContextConfig) {
- Set classNamesToBeBound = new HashSet<>();
- for (JaxbClassesToBeBoundBuildItem classesToBeBoundBuildItem : classesToBeBoundBuildItems) {
- classNamesToBeBound.addAll(classesToBeBoundBuildItem.getClasses());
- }
+ FilteredJaxbClassesToBeBoundBuildItem filterBoundClasses(
+ JaxbConfig config,
+ List classesToBeBoundBuildItems) {
+
+ FilteredJaxbClassesToBeBoundBuildItem.Builder builder = FilteredJaxbClassesToBeBoundBuildItem.builder();
+ classesToBeBoundBuildItems.stream()
+ .map(JaxbClassesToBeBoundBuildItem::getClasses)
+ .forEach(builder::classNames);
// remove classes that have been excluded by users
if (config.excludeClasses.isPresent()) {
- classNamesToBeBound.removeAll(config.excludeClasses.get());
+ builder.classNameExcludes(config.excludeClasses.get());
}
+ return builder.build();
+ }
+
+ @BuildStep
+ @Record(ExecutionTime.STATIC_INIT)
+ void setupJaxbContextConfig(
+ FilteredJaxbClassesToBeBoundBuildItem filteredClassesToBeBound,
+ JaxbContextConfigRecorder jaxbContextConfig) {
+ jaxbContextConfig.addClassesToBeBound(filteredClassesToBeBound.getClasses());
+ }
+
+ @BuildStep
+ @Record(ExecutionTime.STATIC_INIT)
+ void validateDefaultJaxbContext(
+ JaxbConfig config,
+ FilteredJaxbClassesToBeBoundBuildItem filteredClassesToBeBound,
+ SynthesisFinishedBuildItem beanContainerState,
+ JaxbContextConfigRecorder jaxbContextConfig /* Force the build time container to invoke this method */) {
- // parse class names to class
- Set> classes = getAllClassesFromClassNames(classNamesToBeBound);
if (config.validateJaxbContext) {
- // validate the context to fail at build time if it's not valid
- validateContext(classes);
+ final BeanResolver beanResolver = beanContainerState.getBeanResolver();
+ final Set beans = beanResolver
+ .resolveBeans(Type.create(DotName.createSimple(JAXBContext.class), org.jboss.jandex.Type.Kind.CLASS));
+ if (!beans.isEmpty()) {
+ final BeanInfo bean = beanResolver.resolveAmbiguity(beans);
+ if (bean.isDefaultBean()) {
+ /*
+ * Validate the default JAXB context at build time and fail early.
+ * Do this only if the user application actually requires the default JAXBContext bean
+ */
+ try {
+ JAXBContext.newInstance(filteredClassesToBeBound.getClasses().toArray(new Class[0]));
+ } catch (JAXBException e) {
+ /*
+ * Producing a ValidationErrorBuildItem would perhaps be more natural here,
+ * but doing so causes a cycle between this and reactive JAXB extension
+ * Throwing from here works well too
+ */
+ throw new DeploymentException("Failed to create or validate the default JAXBContext", e);
+ }
+ }
+ }
}
-
- // register the classes to be used at runtime
- jaxbContextConfig.addClassesToBeBound(classes);
}
@BuildStep
@@ -388,31 +421,4 @@ private void addResourceBundle(BuildProducer
resourceBundle.produce(new NativeImageResourceBundleBuildItem(bundle));
}
- private void validateContext(Set> classes) {
- try {
- JAXBContext.newInstance(classes.toArray(new Class[0]));
- } catch (JAXBException e) {
- throw new IllegalStateException("Failed to configure JAXB context", e);
- }
- }
-
- private Set> getAllClassesFromClassNames(Collection classNames) {
- Set> classes = new HashSet<>();
- for (String className : classNames) {
- Class> clazz = getClassByName(className);
- if (isValidType(clazz)) {
- classes.add(clazz);
- }
- }
-
- return classes;
- }
-
- private Class> getClassByName(String name) {
- try {
- return Class.forName(name, false, Thread.currentThread().getContextClassLoader());
- } catch (ClassNotFoundException e) {
- throw new RuntimeException(e);
- }
- }
}
diff --git a/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/ConflictingModelClassesMarshalerOnlyTest.java b/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/ConflictingModelClassesMarshalerOnlyTest.java
new file mode 100644
index 0000000000000..14badfff6285f
--- /dev/null
+++ b/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/ConflictingModelClassesMarshalerOnlyTest.java
@@ -0,0 +1,54 @@
+package io.quarkus.jaxb.deployment;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.List;
+
+import jakarta.enterprise.context.control.ActivateRequestContext;
+import jakarta.enterprise.inject.spi.DeploymentException;
+import jakarta.inject.Inject;
+import jakarta.xml.bind.JAXBContext;
+import jakarta.xml.bind.Marshaller;
+
+import org.assertj.core.api.Assertions;
+import org.glassfish.jaxb.core.v2.runtime.IllegalAnnotationException;
+import org.glassfish.jaxb.runtime.v2.runtime.IllegalAnnotationsException;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import io.quarkus.test.QuarkusUnitTest;
+
+/**
+ * Make sure that the validation of the default JAXB context fails if there conflicting model classes and there is only
+ * a {@link Marshaller} injection point (which actually requires a {@link JAXBContext} bean to be available too).
+ */
+public class ConflictingModelClassesMarshalerOnlyTest {
+
+ @RegisterExtension
+ static final QuarkusUnitTest config = new QuarkusUnitTest()
+ .withApplicationRoot((jar) -> jar
+ .addClasses(
+ io.quarkus.jaxb.deployment.one.Model.class,
+ io.quarkus.jaxb.deployment.two.Model.class))
+ .assertException(e -> {
+ assertThat(e).isInstanceOf(DeploymentException.class);
+ assertThat(e.getMessage()).isEqualTo("Failed to create or validate the default JAXBContext");
+ Throwable cause = e.getCause();
+ assertThat(cause).isInstanceOf(IllegalAnnotationsException.class);
+ assertThat(cause.getMessage()).isEqualTo("1 counts of IllegalAnnotationExceptions");
+ List errors = ((IllegalAnnotationsException) cause).getErrors();
+ assertThat(errors.size()).isEqualTo(1);
+ assertThat(errors.get(0).getMessage()).contains("Two classes have the same XML type name \"model\"");
+
+ });
+
+ @Inject
+ Marshaller marshaller;
+
+ @Test
+ @ActivateRequestContext
+ public void shouldFail() {
+ Assertions.fail("The application should fail at boot");
+ }
+
+}
diff --git a/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/ConflictingModelClassesTest.java b/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/ConflictingModelClassesTest.java
new file mode 100644
index 0000000000000..bcded32283401
--- /dev/null
+++ b/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/ConflictingModelClassesTest.java
@@ -0,0 +1,53 @@
+package io.quarkus.jaxb.deployment;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.List;
+
+import jakarta.enterprise.context.control.ActivateRequestContext;
+import jakarta.enterprise.inject.spi.DeploymentException;
+import jakarta.inject.Inject;
+import jakarta.xml.bind.JAXBContext;
+
+import org.assertj.core.api.Assertions;
+import org.glassfish.jaxb.core.v2.runtime.IllegalAnnotationException;
+import org.glassfish.jaxb.runtime.v2.runtime.IllegalAnnotationsException;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import io.quarkus.test.QuarkusUnitTest;
+
+/**
+ * Make sure that the validation of the default JAXB context fails if there conflicting model classes and there actually
+ * is a {@link JAXBContext} injection point.
+ */
+public class ConflictingModelClassesTest {
+
+ @RegisterExtension
+ static final QuarkusUnitTest config = new QuarkusUnitTest()
+ .withApplicationRoot((jar) -> jar
+ .addClasses(
+ io.quarkus.jaxb.deployment.one.Model.class,
+ io.quarkus.jaxb.deployment.two.Model.class))
+ .assertException(e -> {
+ assertThat(e).isInstanceOf(DeploymentException.class);
+ assertThat(e.getMessage()).isEqualTo("Failed to create or validate the default JAXBContext");
+ Throwable cause = e.getCause();
+ assertThat(cause).isInstanceOf(IllegalAnnotationsException.class);
+ assertThat(cause.getMessage()).isEqualTo("1 counts of IllegalAnnotationExceptions");
+ List errors = ((IllegalAnnotationsException) cause).getErrors();
+ assertThat(errors.size()).isEqualTo(1);
+ assertThat(errors.get(0).getMessage()).contains("Two classes have the same XML type name \"model\"");
+
+ });
+
+ @Inject
+ JAXBContext jaxbContext;
+
+ @Test
+ @ActivateRequestContext
+ public void shouldFail() {
+ Assertions.fail("The application should fail at boot");
+ }
+
+}
diff --git a/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/InjectJaxbContextTest.java b/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/InjectJaxbContextTest.java
index 44041e1533fef..be1f1e5b39b83 100644
--- a/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/InjectJaxbContextTest.java
+++ b/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/InjectJaxbContextTest.java
@@ -1,10 +1,10 @@
package io.quarkus.jaxb.deployment;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.assertj.core.api.Assertions.assertThat;
import java.io.StringWriter;
+import jakarta.enterprise.context.control.ActivateRequestContext;
import jakarta.inject.Inject;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
@@ -12,12 +12,28 @@
import jakarta.xml.bind.Unmarshaller;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
-import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.QuarkusUnitTest;
-@QuarkusTest
+/**
+ * Make sure that the default JAXBContext passes the validation thanks to
+ * {@code quarkus.jaxb.exclude-classes=io.quarkus.jaxb.deployment.two.Model} even though there are conflicting classes
+ * in the application.
+ */
public class InjectJaxbContextTest {
+ @RegisterExtension
+ static final QuarkusUnitTest config = new QuarkusUnitTest()
+ .withApplicationRoot((jar) -> jar
+ .addClasses(
+ io.quarkus.jaxb.deployment.one.Model.class,
+ io.quarkus.jaxb.deployment.two.Model.class,
+ Person.class,
+ CustomJaxbContextCustomizer.class)
+ .addPackage("io.quarkus.jaxb.deployment.info"))
+ .overrideConfigKey("quarkus.jaxb.exclude-classes", "io.quarkus.jaxb.deployment.two.Model");
+
@Inject
JAXBContext jaxbContext;
@@ -28,13 +44,23 @@ public class InjectJaxbContextTest {
Unmarshaller unmarshaller;
@Test
+ @ActivateRequestContext
public void shouldInjectJaxbBeans() {
- assertNotNull(jaxbContext);
- assertNotNull(marshaller);
- assertNotNull(unmarshaller);
+ assertThat(jaxbContext).isNotNull();
+ assertThat(marshaller).isNotNull();
+ assertThat(unmarshaller).isNotNull();
+ }
+
+ @Test
+ @ActivateRequestContext
+ public void packageInfoLoaded() {
+ /* make sure the package-info.class is present in the test archive */
+ assertThat(io.quarkus.jaxb.deployment.info.Foo.class.getPackage()
+ .getAnnotation(jakarta.xml.bind.annotation.XmlSchema.class)).isNotNull();
}
@Test
+ @ActivateRequestContext
public void shouldPersonBeInTheJaxbContext() throws JAXBException {
Person person = new Person();
person.setFirst("first");
@@ -43,11 +69,11 @@ public void shouldPersonBeInTheJaxbContext() throws JAXBException {
StringWriter sw = new StringWriter();
marshaller.marshal(person, sw);
- assertEquals("\n"
+ assertThat(sw.toString()).isEqualTo("\n"
+ "\n"
+ " first\n"
+ " last\n"
- + "\n", sw.toString());
+ + "\n");
}
}
diff --git a/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/NoJaxbContextBeanTest.java b/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/NoJaxbContextBeanTest.java
new file mode 100644
index 0000000000000..a86d158c0c6d7
--- /dev/null
+++ b/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/NoJaxbContextBeanTest.java
@@ -0,0 +1,34 @@
+package io.quarkus.jaxb.deployment;
+
+import jakarta.enterprise.context.control.ActivateRequestContext;
+import jakarta.xml.bind.JAXBContext;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import io.quarkus.arc.Arc;
+import io.quarkus.arc.InstanceHandle;
+import io.quarkus.test.QuarkusUnitTest;
+
+/**
+ * Make sure that the default JAXB context is not validated at build time as long as there is no injection point for it.
+ * Conflicting model classes thus won't make the application fail.
+ */
+public class NoJaxbContextBeanTest {
+
+ @RegisterExtension
+ static final QuarkusUnitTest config = new QuarkusUnitTest()
+ .withApplicationRoot((jar) -> jar
+ .addClasses(
+ io.quarkus.jaxb.deployment.one.Model.class,
+ io.quarkus.jaxb.deployment.two.Model.class));
+
+ @Test
+ @ActivateRequestContext
+ public void noJaxbContext() {
+ InstanceHandle contextHandle = Arc.container().instance(JAXBContext.class);
+ Assertions.assertFalse(contextHandle.isAvailable());
+ }
+
+}
diff --git a/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/UserProvidedJaxbContextTest.java b/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/UserProvidedJaxbContextTest.java
new file mode 100644
index 0000000000000..b40507bc70911
--- /dev/null
+++ b/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/UserProvidedJaxbContextTest.java
@@ -0,0 +1,91 @@
+package io.quarkus.jaxb.deployment;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.StringWriter;
+
+import jakarta.enterprise.context.control.ActivateRequestContext;
+import jakarta.enterprise.inject.Produces;
+import jakarta.inject.Inject;
+import jakarta.inject.Singleton;
+import jakarta.xml.bind.JAXBContext;
+import jakarta.xml.bind.JAXBException;
+import jakarta.xml.bind.Marshaller;
+import jakarta.xml.bind.Unmarshaller;
+
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import io.quarkus.test.QuarkusUnitTest;
+
+/**
+ * If the user provides his own {@link JAXBContext} bean then the validation of the default context should not happen
+ * and the presence of conflicting classes, such as {@link io.quarkus.jaxb.deployment.one.Model} and
+ * {@link io.quarkus.jaxb.deployment.two.Model} should not matter.
+ */
+public class UserProvidedJaxbContextTest {
+
+ @RegisterExtension
+ static final QuarkusUnitTest config = new QuarkusUnitTest()
+ .withApplicationRoot((jar) -> jar
+ .addClasses(
+ io.quarkus.jaxb.deployment.one.Model.class,
+ io.quarkus.jaxb.deployment.two.Model.class,
+ UserProvidedJaxbContextTest.JaxbContextProducer.class));
+
+ @Inject
+ JAXBContext jaxbContext;
+
+ @Inject
+ Marshaller marshaller;
+
+ @Inject
+ Unmarshaller unmarshaller;
+
+ @Test
+ @ActivateRequestContext
+ public void shouldInjectJaxbBeans() {
+ assertThat(jaxbContext).isNotNull();
+ assertThat(marshaller).isNotNull();
+ assertThat(unmarshaller).isNotNull();
+ }
+
+ @Test
+ @ActivateRequestContext
+ public void marshalModelOne() throws JAXBException {
+ io.quarkus.jaxb.deployment.one.Model model = new io.quarkus.jaxb.deployment.one.Model();
+ model.setName1("name1");
+
+ StringWriter sw = new StringWriter();
+ marshaller.marshal(model, sw);
+
+ assertThat(sw.toString()).isEqualTo(""
+ + "name1");
+ }
+
+ @Test
+ @ActivateRequestContext
+ public void marshalModelTwo() throws JAXBException {
+ io.quarkus.jaxb.deployment.two.Model model = new io.quarkus.jaxb.deployment.two.Model();
+ model.setName2("name2");
+ Assertions.assertThatExceptionOfType(JAXBException.class)
+ .isThrownBy(() -> marshaller.marshal(model, new StringWriter()))
+ .withMessage("class io.quarkus.jaxb.deployment.two.Model nor any of its super class is known to this context.");
+ }
+
+ public static class JaxbContextProducer {
+
+ @Produces
+ @Singleton
+ JAXBContext produceJaxbContext() {
+ try {
+ return JAXBContext.newInstance(new Class[] { io.quarkus.jaxb.deployment.one.Model.class });
+ } catch (JAXBException e) {
+ throw new RuntimeException("Could not create new JAXBContext", e);
+ }
+ }
+
+ }
+
+}
diff --git a/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/info/Foo.java b/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/info/Foo.java
new file mode 100644
index 0000000000000..3e9a2b5dd5078
--- /dev/null
+++ b/extensions/jaxb/deployment/src/test/java/io/quarkus/jaxb/deployment/info/Foo.java
@@ -0,0 +1,4 @@
+package io.quarkus.jaxb.deployment.info;
+
+public class Foo {
+}
diff --git a/extensions/jaxb/deployment/src/test/resources/application.properties b/extensions/jaxb/deployment/src/test/resources/application.properties
deleted file mode 100644
index d5f361123c8c7..0000000000000
--- a/extensions/jaxb/deployment/src/test/resources/application.properties
+++ /dev/null
@@ -1 +0,0 @@
-quarkus.jaxb.exclude-classes=io.quarkus.jaxb.deployment.two.Model
\ No newline at end of file