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

ClassCastException when using XmlAdapter with XmlEnum #256

Open
wbiller opened this issue Nov 19, 2024 · 4 comments
Open

ClassCastException when using XmlAdapter with XmlEnum #256

wbiller opened this issue Nov 19, 2024 · 4 comments

Comments

@wbiller
Copy link

wbiller commented Nov 19, 2024

I wanted to serialize a fairly complex object structure and came across this ClassCastException.
It looks like the XML Adapter is called too early when the type is an enum.

Below snippet demonstrates the error as a JUnit test

import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import org.junit.jupiter.api.Test;

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.*;

import static org.assertj.core.api.Assertions.assertThat;

public class XmlEnumAdapterTest {

  private static final XmlMapper MAPPER =
    XmlMapper.builder()
             .defaultUseWrapper(true)
             .addModule(new JaxbAnnotationModule())
             .build();

  @Test
  void serialize() throws Exception {

    final Document document = new Document(Code.RED);

    String xml = MAPPER.writeValueAsString(document);

    assertThat(xml).isEqualTo("<document><code>RED</code></document>");
  }

  @XmlRootElement(
    name = "document"
  )
  @XmlAccessorType(XmlAccessType.FIELD)
  @XmlType(
    propOrder = {"_code"}
  )
  public static class Document {

    @XmlElement(name = "code")
    private final Code _code;

    public Document(Code code) { _code = code; }

    public Code getCode() {
      return _code;
    }
  }

  @XmlEnum
  @XmlType(
    name = "CodeType"
  )
  @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
  public enum Code {

    @XmlEnumValue("RED")
    RED;
  }
}

The test was executed with jackson-module-jaxb-annotations-2.17.2.jar

@cowtowncoder
Copy link
Member

First of all, thank you for reporting the issue.

Figuring out where to add tests is tricky: JAXB annotations module cannot depend on XML module (so can't be added here).

But looks like jackson-dataformat-xml does actually have test dependency on Jakarta XML bind annotations -- newer version of JAXB annotations. So might be able to add there.

However, the "correct" place would be here:

https://github.com/FasterXML/jackson-integration-tests/

where it is legal to have dependencies to any and all Jackson modules.

@wbiller
Copy link
Author

wbiller commented Nov 20, 2024

Is there anything I could/should do?

@cowtowncoder
Copy link
Member

@wbiller No, I think this is all the information. I am pretty overloaded currently so it may take a while until I get to look into this, unfortunately.

One minor thing could be if you could try to find minimal reproduction (I suspect most JAXB annotations used are not required here).
And perhaps including first couple of stack frames for exception.

But reproduction is the most important thing and you got it :)

cowtowncoder added a commit that referenced this issue Nov 24, 2024
@cowtowncoder
Copy link
Member

Just realized that XML is probably not the problem here: can create JSON reproduction as well.

But looking at what is happening, I am not sure how code is supposed to work.
CollapsedStringAdapter is "converting" between String and String, basically just transforming content a bit.
But when serializing Enums, shouldn't type given (see https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html) be Enum type, not String?
Only on deserialization could we get String (to convert/adapt to Enum type in question).

Does this work with JAXB? (I assume so).

If this is expected to work there's bit of impedance between how Jackson Converters and JAXB XmlAdapters work and it may be tricky to support these annotations with Jackson.

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

No branches or pull requests

2 participants