3

我正在尝试使用 EclipseLink MOXy 作为部署在 JBoss EAP 6.1.0.Beta1 应用服务器上的 JAX-WS Web 服务的 JAXB 提供程序。现在我已经按照这里javax.xml.ws.Provider的描述实现了,并将文件放入包含我的实现和 web 服务中使用的域类的包中。这是该文件的内容:jaxb.propertiesProvider

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

当我尝试部署包含该服务的 Web 应用程序时,日志中出现以下错误:

@XmlValue is not allowed on a class that derives another class

在我的例子中,使用 MOXy 作为 JAXB 提供者的主要原因是能够@XmlValue在子类中使用注释。当我尝试在使用 MOXy 的测试应用程序中使用与 Web 服务相同的类解组时,不会发生此错误。此外,堆栈跟踪中没有来自org.eclipse.persistence包及其子包的类,只有com.sun.xml.bind.v2类。显然,在部署 Web 应用程序时不使用 MOXy。所有必需的 Maven 工件org.eclipse.persistence都在 WAR 文件中:

$ jar tf my-app.war | grep org.eclipse.persistence
WEB-INF/lib/org.eclipse.persistence.antlr-2.5.0.jar
WEB-INF/lib/org.eclipse.persistence.asm-2.5.0.jar
WEB-INF/lib/org.eclipse.persistence.moxy-2.5.0.jar
WEB-INF/lib/org.eclipse.persistence.core-2.5.0.jar 

我究竟做错了什么?据我了解,Provider在调用 web 服务时在运行时调用。但是错误发生在部署时。我应该重新实现一些东西Provider吗?

4

2 回答 2

1

第一步是确保 EclipseLink 库位于正确的位置。您可以尝试直接使用 MOXy API,而不是将 MOXy 配置为 JAXB 提供程序吗?

import org.eclipse.persistence.jaxb.JAXBContext;
import org.eclipse.persistence.jaxb.JAXBContextFactory;

public class Demo {

    public static void main(String[] args) {
        JAXBContext jc = JAXBContextFactory.createContext(new Class[] {Foo.class, Bar.class}), null);
    }

}
于 2013-06-27T18:44:52.793 回答
0

似乎无法将自定义 JAXB 提供程序与 ApacheCXF 2.6.6 一起使用,后者在 JBoss EAP 6.1.0.Beta1 中用作 JAX-WS 提供程序。实例化 JAXBContext 的上下文工厂被硬编码为com.sun.xml.bind.v2.ContextFactory在 ApacheCXF 中实例化(请参阅ApacheCXF 源代码createContext中的类的静态方法)。JAXBContextCache

UPD:对不起,错误的答案。有一种方法可以在 ApacheCXF 支持的 Web 服务中使用 MOXy 作为 JAXB 提供程序。例如:

import org.eclipse.persistence.jaxb.JAXBContextFactory;
...

@ServiceMode(Service.Mode.PAYLOAD)
@WebServiceProvider(
        portName = "...",
        serviceName = "...",
        targetNamespace = "...",
        wsdlLocation = "..."
)
public class MyService implements Provider<Source>{

    private JAXBContext jaxbContext;

    public MyService() {
        try {
            this.jaxbContext = JAXBContextFactory.createContext(new Class[]{
                    ...
            }, null);
        } catch (JAXBException e) {
            throw new WebServiceException(e);
        }
    }

    @Override
    public Source invoke(Source request) {
        try {
            Unmarshaller unmarshaller = this.jaxbContext.createUnmarshaller();
            ...
        } catch (JAXBException e) {
            throw new WebServiceException(e);
        }
    }
}
于 2013-07-01T07:39:37.800 回答