Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JAXB @XmlJavaTypeAdapter not working in conjunction with Optional #588

Open
toellrich opened this issue Mar 27, 2023 · 0 comments
Open

JAXB @XmlJavaTypeAdapter not working in conjunction with Optional #588

toellrich opened this issue Mar 27, 2023 · 0 comments

Comments

@toellrich
Copy link

toellrich commented Mar 27, 2023

@XmlJavaTypeAdapter doesn't seem to work in conjunction with JDK's Optional class. I have written a unit test in order to replicate this issue:

package org.example;

import static org.example.OptionalWithTypeAdapterTest.TestEnum.A;
import static org.junit.jupiter.api.Assertions.assertEquals;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationModule;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class OptionalWithTypeAdapterTest {

  public enum TestEnum {
    A
  }

  public static class TestEnumAdapter extends XmlAdapter<String, TestEnum> {

    @Override
    public TestEnum unmarshal(String aString) {
      return TestEnum.valueOf(aString.toUpperCase());
    }

    @Override
    public String marshal(TestEnum testEnum) {
      return testEnum.name().toLowerCase();
    }
  }

  public record TestObject1(
      @XmlElement @XmlJavaTypeAdapter(TestEnumAdapter.class) TestEnum testEnum) {
  }

  public record TestObject2(
      @XmlElement Optional<TestEnum> testEnum) {
  }

  public record TestObject3(
      @XmlElement @XmlJavaTypeAdapter(TestEnumAdapter.class) Optional<TestEnum> testEnum) {
  }

  private XmlMapper xmlMapper;

  @BeforeEach
  public void setUp() {
    xmlMapper = new XmlMapper();
    xmlMapper.registerModule(new JakartaXmlBindAnnotationModule());
    xmlMapper.registerModule(new Jdk8Module());
  }

  @Test
  public void writeValueAsStringWithTypeAdapter() throws JsonProcessingException {
    TestObject1 testObject = new TestObject1(A);
    String actual = xmlMapper.writeValueAsString(testObject);
    String expected = "<TestObject1><testEnum>a</testEnum></TestObject1>";
    assertEquals(expected, actual);
  }

  @Test
  public void writeValueAsStringWithOptional() throws JsonProcessingException {
    TestObject2 testObject = new TestObject2(Optional.of(A));
    String actual = xmlMapper.writeValueAsString(testObject);
    String expected = "<TestObject2><testEnum>A</testEnum></TestObject2>";
    assertEquals(expected, actual);
  }

  /**
   * This test fails
   */
  @Disabled
  @Test
  public void writeValueAsStringWithTypeAdapterAndOptional() throws JsonProcessingException {
    TestObject3 testObject = new TestObject3(Optional.of(A));
    String actual = xmlMapper.writeValueAsString(testObject);
    String expected = "<TestObject3><testEnum>a</testEnum></TestObject3>";
    assertEquals(expected, actual);
  }
}

This doesn't seem to have anything to do with the fact that I'm using records. I tried the same test with plain classes and the third test still fails. I'm using java 17 and jackson 2.15.0-rc1.

test.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant