【问题标题】:Why is JAXB trying to bind Spring's ApplicationContext?为什么 JAXB 试图绑定 Spring 的 ApplicationContext?
【发布时间】:2011-09-20 18:52:30
【问题描述】:

我正在开发一个公开 JAX-WS Web 服务的 Spring 应用程序。 Web 服务实现依赖于我的服务层中的一些 spring 管理的对象,看起来像这样

@WebService
public class BlahService {
    ...
    public void setFooService(FooService f) {
        ...
    }
}

其中FooService 在应用程序上下文中定义,并在webapp 启动期间注入BlahServiceFooService 依赖于BarService,它在应用程序上下文中再次定义并在启动时注入,因此上述BlahService传递依赖于BarService

这是他棘手的部分。 BarService 实现了ApplicationContextAware,所以它的代码类似于通常的

public class BazService implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    public final void setApplicationContext(ApplicationContext ctx) {
        this.applicationContext = ctx;
    }
    ...
}

现在除非我用@XmlTransient 注释setApplicationContext,否则应用程序将无法启动,抱怨applicationContext 是一个接口,因此无法绑定到JAXB。我错过了什么?为什么 JAXB 试图将 ApplicationContext 绑定到 XML?

Stacktrace 或者它没有发生

####<Jun 22, 2011 7:28:31 PM CEST> <Info> <ServletContext-/MyApp> <duck> <myserver> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1308763711259> <BEA-000000> <Initializing Spring root WebApplicationContext> 
####<Jun 22, 2011 7:28:32 PM CEST> <Error> <HTTP> <duck> <myserver> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1308763712595> <BEA-101216> <Servlet: "myApp-jax-ws-servlet" failed to preload on startup in Web application: "MyApp.war".
javax.xml.ws.WebServiceException: Unable to create JAXBContext
    at com.sun.xml.ws.model.AbstractSEIModelImpl.createJAXBContext(AbstractSEIModelImpl.java:164)
    at com.sun.xml.ws.model.AbstractSEIModelImpl.postProcess(AbstractSEIModelImpl.java:94)
    at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:281)
    at com.sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:363)
    at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:202)
    at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:496)
    at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:539)
    at weblogic.wsee.jaxws.JAXWSDeployedServlet.getEndpoint(JAXWSDeployedServlet.java:183)
    at weblogic.wsee.jaxws.JAXWSServlet.registerEndpoint(JAXWSServlet.java:135)
    at weblogic.wsee.jaxws.JAXWSServlet.init(JAXWSServlet.java:64)
    at weblogic.wsee.jaxws.JAXWSDeployedServlet.init(JAXWSDeployedServlet.java:54)
    at javax.servlet.GenericServlet.init(GenericServlet.java:241)

    ... lots of weblogic stuff ...

Caused By: java.security.PrivilegedActionException: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
org.springframework.context.ApplicationContext is an interface, and JAXB can't handle interfaces.
    this problem is related to the following location:
        at org.springframework.context.ApplicationContext
        at public final org.springframework.context.ApplicationContext my.package.myApp.service.db.DBManager.getApplicationContext()
        at my.package.myApp.service.db.DBManager
        at public my.package.myApp.service.db.DBManager my.package.myApp.service.sso.SSOInterface.getDBManager()
        at my.package.myApp.service.sso.SSOInterface
        at public my.package.myApp.service.sso.SSOInterface my.package.myApp.ws.inBound.jaxws.SetSsoInterface.arg0
        at my.package.myApp.ws.inBound.jaxws.SetSsoInterface
org.springframework.context.ApplicationContext does not have a no-arg default constructor.
    this problem is related to the following location:
        at org.springframework.context.ApplicationContext
        at public final org.springframework.context.ApplicationContext my.package.myApp.service.db.DBManager.getApplicationContext()
        at my.package.myApp.service.db.DBManager
        at public my.package.myApp.service.db.DBManager my.package.myApp.service.sso.SSOInterface.getDBManager()
        at my.package.myApp.service.sso.SSOInterface
        at public my.package.myApp.service.sso.SSOInterface my.package.myApp.ws.inBound.jaxws.SetSsoInterface.arg0
        at my.package.myApp.ws.inBound.jaxws.SetSsoInterface

    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.xml.ws.model.AbstractSEIModelImpl.createJAXBContext(AbstractSEIModelImpl.java:151)
    at com.sun.xml.ws.model.AbstractSEIModelImpl.postProcess(AbstractSEIModelImpl.java:94)
    at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:281)
    at com.sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:363)
    at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:202)
    at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:496)
    at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:539)
    at weblogic.wsee.jaxws.JAXWSDeployedServlet.getEndpoint(JAXWSDeployedServlet.java:183)
    at weblogic.wsee.jaxws.JAXWSServlet.registerEndpoint(JAXWSServlet.java:135)
    at weblogic.wsee.jaxws.JAXWSServlet.init(JAXWSServlet.java:64)
    at weblogic.wsee.jaxws.JAXWSDeployedServlet.init(JAXWSDeployedServlet.java:54)
    at javax.servlet.GenericServlet.init(GenericServlet.java:241)

        ... lots of weblogic stuff again ...

Caused By: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
org.springframework.context.ApplicationContext is an interface, and JAXB can't handle interfaces.
    this problem is related to the following location:
        at org.springframework.context.ApplicationContext
        at public final org.springframework.context.ApplicationContext my.package.myApp.service.db.DBManager.getApplicationContext()
        at my.package.myApp.service.db.DBManager
        at public my.package.myApp.service.db.DBManager my.package.myApp.service.sso.SSOInterface.getDBManager()
        at my.package.myApp.service.sso.SSOInterface
        at public my.package.myApp.service.sso.SSOInterface my.package.myApp.ws.inBound.jaxws.SetSsoInterface.arg0
        at my.package.myApp.ws.inBound.jaxws.SetSsoInterface
org.springframework.context.ApplicationContext does not have a no-arg default constructor.
    this problem is related to the following location:
        at org.springframework.context.ApplicationContext
        at public final org.springframework.context.ApplicationContext my.package.myApp.service.db.DBManager.getApplicationContext()
        at my.package.myApp.service.db.DBManager
        at public my.package.myApp.service.db.DBManager my.package.myApp.service.sso.SSOInterface.getDBManager()
        at my.package.myApp.service.sso.SSOInterface
        at public my.package.myApp.service.sso.SSOInterface my.package.myApp.ws.inBound.jaxws.SetSsoInterface.arg0
        at my.package.myApp.ws.inBound.jaxws.SetSsoInterface

    at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:102)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:478)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:308)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1149)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:169)
    at com.sun.xml.bind.api.JAXBRIContext.newInstance(JAXBRIContext.java:160)
    at com.sun.xml.ws.developer.JAXBContextFactory$1.createJAXBContext(JAXBContextFactory.java:74)
    at com.sun.xml.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:159)
    at com.sun.xml.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:151)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.xml.ws.model.AbstractSEIModelImpl.createJAXBContext(AbstractSEIModelImpl.java:151)
    at com.sun.xml.ws.model.AbstractSEIModelImpl.postProcess(AbstractSEIModelImpl.java:94)
    at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:281)
    at com.sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:363)
    at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:202)
    at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:496)
    at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:539)
    at weblogic.wsee.jaxws.JAXWSDeployedServlet.getEndpoint(JAXWSDeployedServlet.java:183)
    at weblogic.wsee.jaxws.JAXWSServlet.registerEndpoint(JAXWSServlet.java:135)
    at weblogic.wsee.jaxws.JAXWSServlet.init(JAXWSServlet.java:64)
    at weblogic.wsee.jaxws.JAXWSDeployedServlet.init(JAXWSDeployedServlet.java:54)
    at javax.servlet.GenericServlet.init(GenericServlet.java:241)

    ... more weblogic stuff ...

【问题讨论】:

    标签: java spring jaxb jax-ws jaxb2


    【解决方案1】:

    默认情况下,JAXB 实现将映射所有公共字段和属性。您可以使用@XmlTransient 注解来防止属性被映射:

    @XmlTransient
    public void setFooService(FooService f) {
        ...
    }
    

    【讨论】:

    • 是的,我找到了。问题是为什么 JAXB 试图编组我的 BlahService(以及它所有的直接和传递依赖项,一旦到达 ApplicationContext 就会火上浇油)。
    【解决方案2】:

    JAXB 获取所有 bean 属性(由 getter/setter 访问)并尝试编组或解组它。

    我不明白的一件事 - 你是想编组 BazService 吗?不是单例服务吗?

    【讨论】:

    • 是的,我知道 JAXB 将尝试编组所有公共属性。问题是我没有编组任何东西,至少不是明确的。
    【解决方案3】:

    另一种选择是通过构造函数 arg 注入 fooService

    BlahService { ... 公共 BlashService(FooService f) { this.fooService=f; }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-05
      • 2011-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多