0

I have created Java objects from XSD using IntelliJ Tools > JAXB > Generate Java Code From XML Schema using JAXB...

I am basically trying to generate Java objects from the XSD and then read a XML which would be compliant with this XSD into Java objects.

For my exercise, I am using the XSD from the six group website related to Credit Transfer Version 1.10.

However, when I try to run following code I see an exception : Java.lang.ClassCastException: javax.xml.bind.JAXBElement cannot be cast

public class Pain001Tester {

    public static void main(String[] args) throws IOException {

        String fileName = "pain_001_Beispiel_1.xml";
        ClassLoader classLoader = new Pain001Tester().getClass().getClassLoader();

        File file = new File(classLoader.getResource(fileName).getFile());

        //File is found
        System.out.println("File Found : " + file.exists());

        //Read File Content
        String content = new String(Files.readAllBytes(file.toPath()));
        System.out.println(content);


        JAXBContext jaxbContext;
        try
        {
            jaxbContext = JAXBContext.newInstance(ObjectFactory.class);

            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

            ObjectFactory xmlMessage = (ObjectFactory) jaxbUnmarshaller.unmarshal(new StringReader(content));
            //ObjectFactory xmlMessage = (ObjectFactory) JAXBIntrospector.getValue(jaxbUnmarshaller.unmarshal(new StringReader(content)));

            //JAXBElement<ObjectFactory> userElement = (JAXBElement<ObjectFactory>) jaxbUnmarshaller.unmarshal(new StringReader(content));
            //ObjectFactory user = userElement.getValue();

            System.out.println(xmlMessage);
        }
        catch (JAXBException e)
        {
            e.printStackTrace();
        }

    }
}

I think my issue is related to XMLRootElement but not sure if this is the issue. I understand the following stackoverflow question comes close to my problem but was not able to resolve my problem using couple of solutions highlighted in the stackoverflow case : No @XmlRootElement generated by JAXB

JavaMan
  • 465
  • 1
  • 6
  • 21

2 Answers2

0

I assume the error occurs in

ObjectFactory xmlMessage = (ObjectFactory) jaxbUnmarshaller.unmarshal(new StringReader(content));

jaxbUnmarshaller.unmarshal() does not return a ObjectFactoryt type, so you cannot cast the result to ObjectFactory. It returns a instance of the generated class which corresponds to the root element of the xml file.

Heri
  • 4,368
  • 1
  • 31
  • 51
  • Thanks Heri. You are correct. I found the issue and was about to post my solution but as you came first yours should be the answer. – JavaMan Feb 29 '20 at 17:55
  • Quick one Heri - do you know why annotating ObjectFactory with @XmlRootElement(name = "RootElement") did not work? – JavaMan Feb 29 '20 at 17:56
  • What do you mean by 'annotating ObjectFactory'? This is a generated class, do not touch it, just use it. Basically, you rarly have to care about ObjectFactory. Just use the classes which model your xml elements, and the marshaller/unmarschaller. – Heri Feb 29 '20 at 18:00
  • I initially thought this is some sort of a container class for the XSD and I can map the XML content response to this class. To be honest, when I initially looked at the code of this class my initial assumption did not make sense. Wondering whats the use and why would JAXB generate this class? – JavaMan Feb 29 '20 at 18:04
  • Step through it in debug mode and you will see how it works. – Heri Feb 29 '20 at 18:06
0

I think I have found the issue (Heri pushed the button first, so he gets the cookies)

I changed the following :

ObjectFactory xmlMessage = (ObjectFactory) JAXBIntrospector.getValue(jaxbUnmarshaller.unmarshal(new StringReader(content)));

to

JAXBElement xmlMessage = (JAXBElement) jaxbUnmarshaller.unmarshal(new StringReader(content));

Then, instead of retrieving response to an ObjectFactory class I used the root element class generated by JAXB and it worked.

I am not sure why annotating ObjectFactory with @XmlRootElement(name = "RootElement") did not work but I now have a working solution.

JavaMan
  • 465
  • 1
  • 6
  • 21