문제

Problem

I'm getting some strange behavior where the Spring Jaxb2Marshaller doesn't scan my package-info.java. Could anyone take a look?

I have a Spring MVC/Camel application that accepts multiple objects that are wrapped with a generic wrapper, where the XML MUST look like:

<mlf:message id="22" product="great.event" xmlns:mlf="special mlf URI">
    <mlf:header>
        <mlf:action value="notify-published"/>
    </mlf:header>
    <mlf:payload status="partial">
        <can be any element at all>
    </mlf:payload>
</mlf:message>

My setup follows the Error.

Error

-00:00 [localhost-startStop-1] ERROR o.s.web.context.ContextLoader Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jaxb2Marshaller' defined in class path resource [com/company/CamelConfig.class]: Invocation of init method failed; nested exception is

...

Exception [EclipseLink-25016] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.XMLMarshalException Exception Description: A namespace for the prefix mlf:header was not found in the namespace resolver.

  • with linked exception: [Exception [EclipseLink-0] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.IntegrityException

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553) ~[spring-beans-4.0.1.RELEASE.jar:4.0.1.RELEASE]

Setup

My package-info.java and Wrapper classes look like this:

package-info.java

@XmlSchema(
    xmlns={
        @XmlNs(prefix="mlf", namespaceURI="special mlf URI")
    },
    elementFormDefault=XmlNsForm.UNQUALIFIED)

package com.company.camel;
import javax.xml.bind.annotation.*;

Message.java

package com.company.camel;
@XmlRootElement(name = "message", namespace = "special mlf URI")
@XmlAccessorType(XmlAccessType.FIELD)
public class Message {

    @XmlAttribute(required = false)
    private int id;

    @XmlAttribute(namespace = "")
    private String product;

    @XmlAttribute(namespace = "", required = false)
    private String type;

    @XmlPath("flm:header/flm:action/@value")
    private String action;

    @XmlPath("flm:header/flm:notify-failure/@type")
    private String notifyFailureType;

    @XmlPath("flm:header/flm:notify-failure/@value")
    private String notifyFailureValue;

    @XmlPath("flm:payload")
    private Payload payload;

    //SNIP
}

Payload.java

package com.company.camel;
@XmlRootElement(name="payload", namespace="special mlf URI")
@XmlAccessorType(XmlAccessType.FIELD)
public class Payload {

    @XmlAttribute
    private String status;

    @XmlAnyElement(lax=true)
    Object body;

    //Getters&setters snipped
}  

Because I need to unmarshal this class from Spring MVC REST and Camel (no I cannot use Camel for REST), I set up JAXB in Spring like this:

@Configuration
@ComponentScan(basePackages="com.company.camel")
public class CamelConfig extends CamelConfiguration
{

    //SNIP

// The JAXBDataFormat is used inside Camel routes 
@Bean
public JaxbDataFormat jaxbDataFormat() {
    return new JaxbDataFormat(jaxb2Marshaller().getJaxbContext());
}

//used directly by Spring MVC
@Bean
public Jaxb2Marshaller jaxb2Marshaller() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setPackagesToScan(new String[]{"com.company"});
    return marshaller;
}
도움이 되었습니까?

해결책

noticed that you had another unanswered question... my condolences, JAXB can be a pain to troubleshoot. Could you perhaps post the entire project?

We had a large Spring project where Spring loaded JAXB-annotated classes, complete with package-info.java files, from an imported JAR.

Then another developer added code to manually call JAXBContext.newInstance on a class in the same package as a class in the imported JAR. This new class was not in the imported JAR, the new class was in the main project. Additionally, there was no package-info in the main project for that package.

Pretty sure the original JAXB package mapping from the imported JAR was being blown away and replaced.

Look for any additional calls to JAXB that shouldn't be there.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top