@@ -375,7 +382,6 @@
javax.xml.bind
jaxb-api
- 2.3.1
provided
true
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/jakarta/JakartaGemGenerator.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/jakarta/JakartaGemGenerator.java
new file mode 100644
index 000000000..93bdebeae
--- /dev/null
+++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/jakarta/JakartaGemGenerator.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.mapstruct.ap.internal.gem.jakarta;
+
+import jakarta.xml.bind.annotation.XmlElementDecl;
+import jakarta.xml.bind.annotation.XmlElementRef;
+import org.mapstruct.tools.gem.GemDefinition;
+
+/**
+ * This class is a temporary solution to an issue in the Gem Tools library.
+ *
+ *
+ * This class can be merged with {@link org.mapstruct.ap.internal.gem.GemGenerator}
+ * after the mentioned issue is resolved.
+ *
+ *
+ * @see Gem Tools issue #10
+ * @author Iaroslav Bogdanchikov
+ */
+@GemDefinition(XmlElementDecl.class)
+@GemDefinition(XmlElementRef.class)
+class JakartaGemGenerator {
+}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMappingMethods.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMappingMethods.java
index 0edae7f10..6cd1605b2 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMappingMethods.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMappingMethods.java
@@ -8,6 +8,7 @@ package org.mapstruct.ap.internal.model.source.builtin;
import java.util.ArrayList;
import java.util.List;
+import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.common.TypeFactory;
import org.mapstruct.ap.internal.util.JaxbConstants;
import org.mapstruct.ap.internal.util.JodaTimeConstants;
@@ -24,7 +25,7 @@ public class BuiltInMappingMethods {
public BuiltInMappingMethods(TypeFactory typeFactory) {
boolean isXmlGregorianCalendarPresent = isXmlGregorianCalendarAvailable( typeFactory );
- builtInMethods = new ArrayList<>( 20 );
+ builtInMethods = new ArrayList<>( 21 );
if ( isXmlGregorianCalendarPresent ) {
builtInMethods.add( new DateToXmlGregorianCalendar( typeFactory ) );
builtInMethods.add( new XmlGregorianCalendarToDate( typeFactory ) );
@@ -39,8 +40,14 @@ public class BuiltInMappingMethods {
builtInMethods.add( new XmlGregorianCalendarToLocalDateTime( typeFactory ) );
}
- if ( isJaxbAvailable( typeFactory ) ) {
- builtInMethods.add( new JaxbElemToValue( typeFactory ) );
+ if ( isJavaxJaxbAvailable( typeFactory ) ) {
+ Type type = typeFactory.getType( JaxbConstants.JAVAX_JAXB_ELEMENT_FQN );
+ builtInMethods.add( new JaxbElemToValue( type ) );
+ }
+
+ if ( isJakartaJaxbAvailable( typeFactory ) ) {
+ Type type = typeFactory.getType( JaxbConstants.JAKARTA_JAXB_ELEMENT_FQN );
+ builtInMethods.add( new JaxbElemToValue( type ) );
}
builtInMethods.add( new ZonedDateTimeToCalendar( typeFactory ) );
@@ -58,8 +65,12 @@ public class BuiltInMappingMethods {
}
}
- private static boolean isJaxbAvailable(TypeFactory typeFactory) {
- return typeFactory.isTypeAvailable( JaxbConstants.JAXB_ELEMENT_FQN );
+ private static boolean isJavaxJaxbAvailable(TypeFactory typeFactory) {
+ return typeFactory.isTypeAvailable( JaxbConstants.JAVAX_JAXB_ELEMENT_FQN );
+ }
+
+ private static boolean isJakartaJaxbAvailable(TypeFactory typeFactory) {
+ return typeFactory.isTypeAvailable( JaxbConstants.JAKARTA_JAXB_ELEMENT_FQN );
}
private static boolean isXmlGregorianCalendarAvailable(TypeFactory typeFactory) {
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JaxbElemToValue.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JaxbElemToValue.java
index 0d3d4c30a..2a5d1639e 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JaxbElemToValue.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JaxbElemToValue.java
@@ -5,26 +5,23 @@
*/
package org.mapstruct.ap.internal.model.source.builtin;
-import static org.mapstruct.ap.internal.util.Collections.asSet;
-
import java.util.Set;
import org.mapstruct.ap.internal.model.common.Parameter;
import org.mapstruct.ap.internal.model.common.Type;
-import org.mapstruct.ap.internal.model.common.TypeFactory;
-import org.mapstruct.ap.internal.util.JaxbConstants;
+
+import static org.mapstruct.ap.internal.util.Collections.asSet;
/**
* @author Sjaak Derksen
*/
-public class JaxbElemToValue extends BuiltInMethod {
+class JaxbElemToValue extends BuiltInMethod {
private final Parameter parameter;
private final Type returnType;
private final Set importTypes;
- public JaxbElemToValue(TypeFactory typeFactory) {
- Type type = typeFactory.getType( JaxbConstants.JAXB_ELEMENT_FQN );
+ JaxbElemToValue(Type type) {
this.parameter = new Parameter( "element", type );
this.returnType = type.getTypeParameters().get( 0 );
this.importTypes = asSet( parameter.getType() );
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/JakartaXmlElementDeclSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/JakartaXmlElementDeclSelector.java
new file mode 100644
index 000000000..df5cd848a
--- /dev/null
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/JakartaXmlElementDeclSelector.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.mapstruct.ap.internal.model.source.selector;
+
+import javax.lang.model.element.Element;
+
+import org.mapstruct.ap.internal.gem.jakarta.XmlElementDeclGem;
+import org.mapstruct.ap.internal.gem.jakarta.XmlElementRefGem;
+import org.mapstruct.ap.internal.util.TypeUtils;
+
+/**
+ * The concrete implementation of the {@link XmlElementDeclSelector} that
+ * works with {@link jakarta.xml.bind.annotation.XmlElementRef} and
+ * {@link jakarta.xml.bind.annotation.XmlElementDecl}.
+ *
+ * @author Iaroslav Bogdanchikov
+ */
+class JakartaXmlElementDeclSelector extends XmlElementDeclSelector {
+
+ JakartaXmlElementDeclSelector(TypeUtils typeUtils) {
+ super( typeUtils );
+ }
+
+ @Override
+ XmlElementDeclInfo getXmlElementDeclInfo(Element element) {
+ XmlElementDeclGem gem = XmlElementDeclGem.instanceOn( element );
+
+ if (gem == null) {
+ return null;
+ }
+
+ return new XmlElementDeclInfo( gem.name().get(), gem.scope().get() );
+ }
+
+ @Override
+ XmlElementRefInfo getXmlElementRefInfo(Element element) {
+ XmlElementRefGem gem = XmlElementRefGem.instanceOn( element );
+
+ if (gem == null) {
+ return null;
+ }
+
+ return new XmlElementRefInfo( gem.name().get(), gem.type().get() );
+ }
+}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/JavaxXmlElementDeclSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/JavaxXmlElementDeclSelector.java
new file mode 100644
index 000000000..1d02e97e9
--- /dev/null
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/JavaxXmlElementDeclSelector.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.mapstruct.ap.internal.model.source.selector;
+
+import javax.lang.model.element.Element;
+
+import org.mapstruct.ap.internal.gem.XmlElementDeclGem;
+import org.mapstruct.ap.internal.gem.XmlElementRefGem;
+import org.mapstruct.ap.internal.util.TypeUtils;
+
+/**
+ * The concrete implementation of the {@link XmlElementDeclSelector} that
+ * works with {@link javax.xml.bind.annotation.XmlElementRef} and
+ * {@link javax.xml.bind.annotation.XmlElementDecl}.
+ *
+ * @author Iaroslav Bogdanchikov
+ */
+class JavaxXmlElementDeclSelector extends XmlElementDeclSelector {
+
+ JavaxXmlElementDeclSelector(TypeUtils typeUtils) {
+ super( typeUtils );
+ }
+
+ @Override
+ XmlElementDeclInfo getXmlElementDeclInfo(Element element) {
+ XmlElementDeclGem gem = XmlElementDeclGem.instanceOn( element );
+
+ if (gem == null) {
+ return null;
+ }
+
+ return new XmlElementDeclInfo( gem.name().get(), gem.scope().get() );
+ }
+
+ @Override
+ XmlElementRefInfo getXmlElementRefInfo(Element element) {
+ XmlElementRefGem gem = XmlElementRefGem.instanceOn( element );
+
+ if (gem == null) {
+ return null;
+ }
+
+ return new XmlElementRefInfo( gem.name().get(), gem.type().get() );
+ }
+}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodSelectors.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodSelectors.java
index de429174d..519e1c3d6 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodSelectors.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodSelectors.java
@@ -32,7 +32,8 @@ public class MethodSelectors {
new TypeSelector( typeFactory, messager ),
new QualifierSelector( typeUtils, elementUtils ),
new TargetTypeSelector( typeUtils ),
- new XmlElementDeclSelector( typeUtils ),
+ new JavaxXmlElementDeclSelector( typeUtils ),
+ new JakartaXmlElementDeclSelector( typeUtils ),
new InheritanceSelector(),
new CreateOrUpdateSelector(),
new SourceRhsSelector(),
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/XmlElementDeclSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/XmlElementDeclSelector.java
index 7bdae0b77..91b4b5ca1 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/XmlElementDeclSelector.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/XmlElementDeclSelector.java
@@ -11,19 +11,17 @@ import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
-import org.mapstruct.ap.internal.util.TypeUtils;
-import org.mapstruct.ap.internal.gem.XmlElementRefGem;
import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.source.Method;
import org.mapstruct.ap.internal.model.source.SourceMethod;
-import org.mapstruct.ap.internal.gem.XmlElementDeclGem;
+import org.mapstruct.ap.internal.util.TypeUtils;
/**
- * Finds the {@link javax.xml.bind.annotation.XmlElementRef} annotation on a field (of the mapping result type or its
+ * Finds the {@code XmlElementRef} annotation on a field (of the mapping result type or its
* super types) matching the
* target property name. Then selects those methods with matching {@code name} and {@code scope} attributes of the
- * {@link javax.xml.bind.annotation.XmlElementDecl} annotation, if that is present. Matching happens in the following
+ * {@code XmlElementDecl} annotation, if that is present. Matching happens in the following
* order:
*
* - Name and Scope matches
@@ -34,12 +32,15 @@ import org.mapstruct.ap.internal.gem.XmlElementDeclGem;
* the given method is not annotated with {@code XmlElementDecl} it will be considered as matching.
*
* @author Sjaak Derksen
+ *
+ * @see JavaxXmlElementDeclSelector
+ * @see JakartaXmlElementDeclSelector
*/
-public class XmlElementDeclSelector implements MethodSelector {
+abstract class XmlElementDeclSelector implements MethodSelector {
private final TypeUtils typeUtils;
- public XmlElementDeclSelector(TypeUtils typeUtils) {
+ XmlElementDeclSelector(TypeUtils typeUtils) {
this.typeUtils = typeUtils;
}
@@ -63,15 +64,14 @@ public class XmlElementDeclSelector implements MethodSelector {
}
SourceMethod candidateMethod = (SourceMethod) candidate.getMethod();
- XmlElementDeclGem xmlElementDecl =
- XmlElementDeclGem.instanceOn( candidateMethod.getExecutable() );
+ XmlElementDeclInfo xmlElementDeclInfo = getXmlElementDeclInfo( candidateMethod.getExecutable() );
- if ( xmlElementDecl == null ) {
+ if ( xmlElementDeclInfo == null ) {
continue;
}
- String name = xmlElementDecl.name().get();
- TypeMirror scope = xmlElementDecl.scope().getValue();
+ String name = xmlElementDeclInfo.nameValue();
+ TypeMirror scope = xmlElementDeclInfo.scopeType();
boolean nameIsSetAndMatches = name != null && name.equals( xmlElementRefInfo.nameValue() );
boolean scopeIsSetAndMatches =
@@ -142,9 +142,9 @@ public class XmlElementDeclSelector implements MethodSelector {
for ( Element enclosed : currentElement.getEnclosedElements() ) {
if ( enclosed.getKind().equals( ElementKind.FIELD )
&& enclosed.getSimpleName().contentEquals( targetPropertyName ) ) {
- XmlElementRefGem xmlElementRef = XmlElementRefGem.instanceOn( enclosed );
- if ( xmlElementRef != null ) {
- return new XmlElementRefInfo( xmlElementRef.name().get(), currentMirror );
+ XmlElementRefInfo xmlElementRefInfo = getXmlElementRefInfo( enclosed );
+ if ( xmlElementRefInfo != null ) {
+ return new XmlElementRefInfo( xmlElementRefInfo.nameValue(), currentMirror );
}
}
}
@@ -154,7 +154,11 @@ public class XmlElementDeclSelector implements MethodSelector {
return defaultInfo;
}
- private static class XmlElementRefInfo {
+ abstract XmlElementDeclInfo getXmlElementDeclInfo(Element element);
+
+ abstract XmlElementRefInfo getXmlElementRefInfo(Element element);
+
+ static class XmlElementRefInfo {
private final String nameValue;
private final TypeMirror sourceType;
@@ -163,12 +167,37 @@ public class XmlElementDeclSelector implements MethodSelector {
this.sourceType = sourceType;
}
- public String nameValue() {
+ String nameValue() {
return nameValue;
}
- public TypeMirror sourceType() {
+ TypeMirror sourceType() {
return sourceType;
}
}
+
+ /**
+ * A class, whose purpose is to combine the use of
+ * {@link org.mapstruct.ap.internal.gem.XmlElementDeclGem}
+ * and
+ * {@link org.mapstruct.ap.internal.gem.jakarta.XmlElementDeclGem}.
+ */
+ static class XmlElementDeclInfo {
+
+ private final String nameValue;
+ private final TypeMirror scopeType;
+
+ XmlElementDeclInfo(String nameValue, TypeMirror scopeType) {
+ this.nameValue = nameValue;
+ this.scopeType = scopeType;
+ }
+
+ String nameValue() {
+ return nameValue;
+ }
+
+ TypeMirror scopeType() {
+ return scopeType;
+ }
+ }
}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/JaxbConstants.java b/processor/src/main/java/org/mapstruct/ap/internal/util/JaxbConstants.java
index db18673ba..c89877062 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/util/JaxbConstants.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/util/JaxbConstants.java
@@ -10,7 +10,8 @@ package org.mapstruct.ap.internal.util;
*/
public final class JaxbConstants {
- public static final String JAXB_ELEMENT_FQN = "javax.xml.bind.JAXBElement";
+ public static final String JAVAX_JAXB_ELEMENT_FQN = "javax.xml.bind.JAXBElement";
+ public static final String JAKARTA_JAXB_ELEMENT_FQN = "jakarta.xml.bind.JAXBElement";
private JaxbConstants() {
}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/BuiltInTest.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/BuiltInTest.java
index 2dc41b822..c8ee922af 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/builtin/BuiltInTest.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/BuiltInTest.java
@@ -29,6 +29,8 @@ import org.mapstruct.ap.test.builtin._target.MapTarget;
import org.mapstruct.ap.test.builtin.bean.BigDecimalProperty;
import org.mapstruct.ap.test.builtin.bean.CalendarProperty;
import org.mapstruct.ap.test.builtin.bean.DateProperty;
+import org.mapstruct.ap.test.builtin.bean.JakartaJaxbElementListProperty;
+import org.mapstruct.ap.test.builtin.bean.JakartaJaxbElementProperty;
import org.mapstruct.ap.test.builtin.bean.JaxbElementListProperty;
import org.mapstruct.ap.test.builtin.bean.JaxbElementProperty;
import org.mapstruct.ap.test.builtin.bean.SomeType;
@@ -45,6 +47,8 @@ import org.mapstruct.ap.test.builtin.mapper.CalendarToXmlGregCalMapper;
import org.mapstruct.ap.test.builtin.mapper.DateToCalendarMapper;
import org.mapstruct.ap.test.builtin.mapper.DateToXmlGregCalMapper;
import org.mapstruct.ap.test.builtin.mapper.IterableSourceTargetMapper;
+import org.mapstruct.ap.test.builtin.mapper.JakartaJaxbListMapper;
+import org.mapstruct.ap.test.builtin.mapper.JakartaJaxbMapper;
import org.mapstruct.ap.test.builtin.mapper.JaxbListMapper;
import org.mapstruct.ap.test.builtin.mapper.JaxbMapper;
import org.mapstruct.ap.test.builtin.mapper.MapSourceTargetMapper;
@@ -58,6 +62,7 @@ import org.mapstruct.ap.test.builtin.source.MapSource;
import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest;
import org.mapstruct.ap.testutil.WithClasses;
+import org.mapstruct.ap.testutil.WithJakartaJaxb;
import org.mapstruct.ap.testutil.WithJavaxJaxb;
import static org.assertj.core.api.Assertions.assertThat;
@@ -101,6 +106,23 @@ public class BuiltInTest {
assertThat( target.publicProp ).isEqualTo( "PUBLIC TEST" );
}
+ @ProcessorTest
+ @WithClasses( {
+ JakartaJaxbMapper.class,
+ JakartaJaxbElementProperty.class,
+ } )
+ @WithJakartaJaxb
+ public void shouldApplyBuiltInOnJakartaJaxbElement() {
+ JakartaJaxbElementProperty source = new JakartaJaxbElementProperty();
+ source.setProp( createJakartaJaxb( "TEST" ) );
+ source.publicProp = createJakartaJaxb( "PUBLIC TEST" );
+
+ StringProperty target = JakartaJaxbMapper.INSTANCE.map( source );
+ assertThat( target ).isNotNull();
+ assertThat( target.getProp() ).isEqualTo( "TEST" );
+ assertThat( target.publicProp ).isEqualTo( "PUBLIC TEST" );
+ }
+
@ProcessorTest
@WithClasses( {
JaxbMapper.class,
@@ -128,6 +150,33 @@ public class BuiltInTest {
assertThat( target2.getProp() ).isNotNull();
}
+ @ProcessorTest
+ @WithClasses( {
+ JakartaJaxbMapper.class,
+ JakartaJaxbElementProperty.class,
+ } )
+ @WithJakartaJaxb
+ @IssueKey( "1698" )
+ public void shouldApplyBuiltInOnJakartaJAXBElementExtra() {
+ JakartaJaxbElementProperty source = new JakartaJaxbElementProperty();
+ source.setProp( createJakartaJaxb( "5" ) );
+ source.publicProp = createJakartaJaxb( "5" );
+
+ BigDecimalProperty target = JakartaJaxbMapper.INSTANCE.mapBD( source );
+ assertThat( target ).isNotNull();
+ assertThat( target.getProp() ).isEqualTo( new BigDecimal( "5" ) );
+ assertThat( target.publicProp ).isEqualTo( new BigDecimal( "5" ) );
+
+ JakartaJaxbElementProperty source2 = new JakartaJaxbElementProperty();
+ source2.setProp( createJakartaJaxb( "5" ) );
+ source2.publicProp = createJakartaJaxb( "5" );
+
+ SomeTypeProperty target2 = JakartaJaxbMapper.INSTANCE.mapSomeType( source2 );
+ assertThat( target2 ).isNotNull();
+ assertThat( target2.publicProp ).isNotNull();
+ assertThat( target2.getProp() ).isNotNull();
+ }
+
@ProcessorTest
@WithClasses( {
JaxbListMapper.class,
@@ -147,6 +196,24 @@ public class BuiltInTest {
assertThat( target.publicProp.get( 0 ) ).isEqualTo( "PUBLIC TEST2" );
}
+ @ProcessorTest
+ @WithClasses( {
+ JakartaJaxbListMapper.class,
+ JakartaJaxbElementListProperty.class,
+ } )
+ @WithJakartaJaxb
+ @IssueKey( "141" )
+ public void shouldApplyBuiltInOnJakartaJAXBElementList() {
+ JakartaJaxbElementListProperty source = new JakartaJaxbElementListProperty();
+ source.setProp( createJakartaJaxbList( "TEST2" ) );
+ source.publicProp = createJakartaJaxbList( "PUBLIC TEST2" );
+
+ StringListProperty target = JakartaJaxbListMapper.INSTANCE.map( source );
+ assertThat( target ).isNotNull();
+ assertThat( target.getProp().get( 0 ) ).isEqualTo( "TEST2" );
+ assertThat( target.publicProp.get( 0 ) ).isEqualTo( "PUBLIC TEST2" );
+ }
+
@ProcessorTest
@WithClasses( DateToXmlGregCalMapper.class )
public void shouldApplyBuiltInOnDateToXmlGregCal() throws ParseException {
@@ -414,12 +481,22 @@ public class BuiltInTest {
return new JAXBElement<>( new QName( "www.mapstruct.org", "test" ), String.class, test );
}
+ private jakarta.xml.bind.JAXBElement createJakartaJaxb(String test) {
+ return new jakarta.xml.bind.JAXBElement<>( new QName( "www.mapstruct.org", "test" ), String.class, test );
+ }
+
private List> createJaxbList(String test) {
List> result = new ArrayList<>();
result.add( createJaxb( test ) );
return result;
}
+ private List> createJakartaJaxbList(String test) {
+ List> result = new ArrayList<>();
+ result.add( createJakartaJaxb( test ) );
+ return result;
+ }
+
private Date createDate(String date) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat( "dd-M-yyyy hh:mm:ss" );
return sdf.parse( date );
diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JakartaJaxbElementListProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JakartaJaxbElementListProperty.java
new file mode 100644
index 000000000..f6ab53725
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JakartaJaxbElementListProperty.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.mapstruct.ap.test.builtin.bean;
+
+import java.util.List;
+
+import jakarta.xml.bind.JAXBElement;
+
+public class JakartaJaxbElementListProperty {
+
+ // CHECKSTYLE:OFF
+ public List> publicProp;
+ // CHECKSTYLE:ON
+
+ private List> prop;
+
+ public List> getProp() {
+ return prop;
+ }
+
+ public void setProp( List> prop ) {
+ this.prop = prop;
+ }
+
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JakartaJaxbElementProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JakartaJaxbElementProperty.java
new file mode 100644
index 000000000..0336afe81
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JakartaJaxbElementProperty.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.mapstruct.ap.test.builtin.bean;
+
+import jakarta.xml.bind.JAXBElement;
+
+public class JakartaJaxbElementProperty {
+
+ // CHECKSTYLE:OFF
+ public JAXBElement publicProp;
+ // CHECKSTYLE:ON
+
+ private JAXBElement prop;
+
+ public JAXBElement getProp() {
+ return prop;
+ }
+
+ public void setProp( JAXBElement prop ) {
+ this.prop = prop;
+ }
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JakartaJaxbListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JakartaJaxbListMapper.java
new file mode 100644
index 000000000..602e2180f
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JakartaJaxbListMapper.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.mapstruct.ap.test.builtin.mapper;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.ap.test.builtin.bean.JakartaJaxbElementListProperty;
+import org.mapstruct.ap.test.builtin.bean.StringListProperty;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface JakartaJaxbListMapper {
+
+ JakartaJaxbListMapper INSTANCE = Mappers.getMapper( JakartaJaxbListMapper.class );
+
+ StringListProperty map(JakartaJaxbElementListProperty source);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JakartaJaxbMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JakartaJaxbMapper.java
new file mode 100644
index 000000000..933479257
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JakartaJaxbMapper.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.mapstruct.ap.test.builtin.mapper;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.ap.test.builtin.bean.BigDecimalProperty;
+import org.mapstruct.ap.test.builtin.bean.JakartaJaxbElementProperty;
+import org.mapstruct.ap.test.builtin.bean.SomeType;
+import org.mapstruct.ap.test.builtin.bean.SomeTypeProperty;
+import org.mapstruct.ap.test.builtin.bean.StringProperty;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface JakartaJaxbMapper {
+
+ JakartaJaxbMapper INSTANCE = Mappers.getMapper( JakartaJaxbMapper.class );
+
+ StringProperty map(JakartaJaxbElementProperty source);
+
+ BigDecimalProperty mapBD(JakartaJaxbElementProperty source);
+
+ SomeTypeProperty mapSomeType(JakartaJaxbElementProperty source);
+
+ @SuppressWarnings( "unused" )
+ default SomeType map( String in ) {
+ return new SomeType();
+ }
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/testutil/WithJakartaJaxb.java b/processor/src/test/java/org/mapstruct/ap/testutil/WithJakartaJaxb.java
new file mode 100644
index 000000000..86c9d83a5
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/testutil/WithJakartaJaxb.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright MapStruct Authors.
+ *
+ * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
+ */
+package org.mapstruct.ap.testutil;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Meta annotation that adds the needed Jakarta XML Binding dependencies.
+ *
+ * @author Iaroslav Bogdanchikov
+ */
+@Target({ ElementType.TYPE, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@WithTestDependency({
+ "jakarta.xml.bind",
+})
+public @interface WithJakartaJaxb {
+
+}