【问题标题】:WebLogic deploy exception using @WebParam in SpringBoot CXF applicationWebLogic 在 SpringBoot CXF 应用程序中使用 @WebParam 部署异常
【发布时间】:2017-07-02 11:42:51
【问题描述】:

我正在开发一个以 SpringBoot 1.4.1 为主要框架的应用程序。该应用程序是一个 Maven 动态 Web 项目,它公开了一些 Web 服务并连接到各种数据库。它同时拥有服务器和客户端,以便与 Microsoft Dynamics 或 AutoCad 等其他程序连接。

它充当一些应用程序和一些数据库之间的“通道”。

Web 服务使用 CXF 3.1.8 开发,数据库访问使用 Spring JPA 完成 CRUD 方法,MyBatis 完成复杂查询。

一切都是通过 java clases 和 java beans 配置的(不使用 xml 配置文件)。

该应用程序在 spring boot 嵌入式 Tomcat(将其部署为 spring boot 应用程序)和 WebLogic 12c 服务器(部署为 maven-build war)中都可以正常工作。

但我对某些 Web 服务方法有一个奇怪的行为。具体来说,除了删除方法之外,所有方法都可以正常工作。

这是代码的一小部分。

我有一个 java 父类,它实现了将由 Web 服务共享的方法。然后我有 2 个或更多 java 类扩展这个父类并调用 super.method()。

这里是父类:

@Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
public class FooService extends ServiceConfigurator {

    @Autowired
    protected FooRepository fooRepository;
    @Autowired
    protected FooMapper fooMapper;
    @Autowired
    protected FooFacade fooFacade;

    public ServiceResult persistFoo(final Foo foo) {
        this.getServiceResult();
        try {
            Foo result = this.fooFacade.persistFoo(foo, this.serviceResult);
            if (CollectionUtils.isEmpty(this.serviceResult.getErrors())) {
                result = this.fooMapper.findOne(result.getId());
                this.serviceResult.getResults().add(result);
                this.serviceResult.setSuccess(true);
            }
        } catch (final Exception e) {
            logger.error("ERROR", e);
            this.serviceResult.getErrors().addAll(Utils.addErrors(e));
            e.printStackTrace();
        }
        return this.serviceResult;
    }

    public ServiceResult deleteFoo(final Foo foo) {
        this.getServiceResult();
        try {
            final Helper helper = this.fooMapper.findById(helper.getId());
            final Foo existing = this.fooMapper.find(helper.getId(),     foo.getNumber(), foo.getVersion());
            this.fooFacade.deleteFoo(existing, this.serviceResult);
            if (CollectionUtils.isEmpty(this.serviceResult.getErrors())) {
                this.serviceResult.setSuccess(true);
            }
        } catch (final Exception e) {
            logger.error("ERROR", e);
            this.serviceResult.getErrors().addAll(Utils.addErrors(e));
            e.printStackTrace();
        }
        return this.serviceResult;
    }
}

这里有一个子类:

@Service("fooImpService ")
@WebService(serviceName = "FooImpService ")
public class FooImpService extends FooService {

    public ServiceResult createFoo(@WebParam(name = "foo") final Foo foo) {
        return super.persistFoo(foo);
    }

无论我在哪里部署我的应用程序,上述方法都可以正常工作,其他方法也是如此(例如):

@Transactional(readOnly = false)
public ServiceResult findId(@WebParam(name = "idOne") final String idOne, @WebParam(name = "idTwo") final String idTwo,
        @WebParam(name = "version") final String version) {
    this.getServiceResult();
    try {
        final Foo foo = this.fooMapper.findById(idOne);
        final Fooresult = this.fooMapper.findByVersion(foo.getId(), idTwo, version);
        if (result != null) {
            this.serviceResult.getResults().add(result.getId());
            this.serviceResult.setSuccess(true);
        }
    } catch (final Exception e) {
        logger.error("ERROR", e);
        this.serviceResult.getErrors().addAll(Utils.addErrors(e));
        e.printStackTrace();
    }
    return this.serviceResult;
}

这些方法既可以作为 Spring Boot 应用程序,也可以作为部署在 WebLogic 中的 jar 文件或 war 文件。

但是,这个方法:

public ServiceResult deleteFoo(@WebParam(name = "foo") final Foo foo) {
    return super.deleteFoo(foo);
}

如果我将应用程序部署为 Spring Boot 应用程序,则可以在嵌入式 Tomcat 中正常工作,但是当我尝试将 war 部署到 WebLogic 时,出现以下异常:

Caused by: java.lang.NullPointerException:
    at com.sun.xml.ws.spi.db.JAXBWrapperAccessor.getPropertyAccessor(JAXBWrapperAccessor.java:261)
    at com.sun.xml.ws.db.toplink.JAXBContextWrapper.getElementPropertyAccessor(JAXBContextWrapper.java:170)
    at com.sun.xml.ws.server.sei.EndpointArgumentsBuilder$DocLit.<init>(EndpointArgumentsBuilder.java:598)
    at com.sun.xml.ws.server.sei.TieHandler.createArgumentsBuilder(TieHandler.java:143)
    at com.sun.xml.ws.server.sei.TieHandler.<init>(TieHandler.java:115)
    at com.sun.xml.ws.db.DatabindingImpl.<init>(DatabindingImpl.java:118)
    at com.sun.xml.ws.db.DatabindingProviderImpl.create(DatabindingProviderImpl.java:74)
    at com.sun.xml.ws.db.DatabindingProviderImpl.create(DatabindingProviderImpl.java:58)
    at com.sun.xml.ws.db.DatabindingFactoryImpl.createRuntime(DatabindingFactoryImpl.java:120)
    at com.sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:521)
    at com.sun.xml.ws.server.EndpointFactory.create(EndpointFactory.java:300)
    at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:164)
    at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:577)
    at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:560)
    at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:639)
    at weblogic.wsee.jaxws.JAXWSDeployedServlet.getEndpoint(JAXWSDeployedServlet.java:355)
    at weblogic.wsee.jaxws.JAXWSServlet.registerEndpoint(JAXWSServlet.java:167)
    at weblogic.wsee.jaxws.JAXWSServlet.init(JAXWSServlet.java:79)
    at weblogic.wsee.jaxws.JAXWSDeployedServlet.init(JAXWSDeployedServlet.java:91)
    at javax.servlet.GenericServlet.init(GenericServlet.java:244)
    at weblogic.servlet.internal.StubSecurityHelper$ServletInitAction.run(StubSecurityHelper.java:343)
    at weblogic.servlet.internal.StubSecurityHelper$ServletInitAction.run(StubSecurityHelper.java:294)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:326)
    at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197)
    at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
    at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71)
    at weblogic.servlet.internal.StubSecurityHelper.initServletInstance(StubSecurityHelper.java:99)
    at weblogic.servlet.internal.StubSecurityHelper.createServlet(StubSecurityHelper.java:87)
    at weblogic.servlet.internal.StubLifecycleHelper.createOneInstance(StubLifecycleHelper.java:71)
    at weblogic.servlet.internal.StubLifecycleHelper.<init>(StubLifecycleHelper.java:57)
    at weblogic.servlet.internal.StubLifecycleHelper.<init>(StubLifecycleHelper.java:31)
    at weblogic.servlet.internal.ServletStubImpl.initStubLifecycleHelper(ServletStubImpl.java:673)
    at weblogic.servlet.internal.ServletStubImpl.prepareServlet(ServletStubImpl.java:612)
    at weblogic.servlet.internal.WebAppServletContext.preloadServlet(WebAppServletContext.java:2054)
    at weblogic.servlet.internal.WebAppServletContext.loadServletsOnStartup(WebAppServletContext.java:2031)
    at weblogic.servlet.internal.WebAppServletContext.preloadResources(WebAppServletContext.java:1920)
    at weblogic.servlet.internal.WebAppServletContext.start(WebAppServletContext.java:3091)
    at weblogic.servlet.internal.WebAppModule.startContexts(WebAppModule.java:1823)
    at weblogic.servlet.internal.WebAppModule.start(WebAppModule.java:882)
    at weblogic.application.internal.ExtensibleModuleWrapper$StartStateChange.next(ExtensibleModuleWrapper.java:360)
    at weblogic.application.internal.ExtensibleModuleWrapper$StartStateChange.next(ExtensibleModuleWrapper.java:356)
    at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45)
    at weblogic.application.internal.ExtensibleModuleWrapper.start(ExtensibleModuleWrapper.java:138)

这个异常可能是由与@WebParam 注释相关的东西引起的,因为当我从删除方法中删除注释时,应用程序被正确部署并且方法在 WebLogic 中工作正常。

【问题讨论】:

  • 我有一个类似的问题,春季启动我的 jar 和战争工作正常,而 WLS 在我使用 JAXB 的地方不起作用,我开始知道 WLS 使用它自己的 JAXBMarshaller,我添加了包在 META-INF 中并使用 prefer-application-resources 映射到 weblogic.xml。我认为这与您的问题不同,但也请检查这一行。
  • 看起来像上面评论中提到的类冲突。
  • @user3428736 您在 weblogic.xml 中添加了哪些包?在我的应用程序中,我有 jaxb-core 和 jaxb-impl jar,但我不确定要添加哪些包...也许是 com.sun.xml?
  • @DANIEL ALVAREZ 添加 META-INF\services 与名为 com.sun.xml.ws.spi.db.BindingContextFactory 的文件和 JAXBContext 与您的包作为一个文件,并在您的网络中添加位置-logic.xml 如上所述。

标签: java spring-boot jaxb weblogic12c spring-cxf


【解决方案1】:

以下链接https://axis.apache.org/axis2/java/core/docs/app_server.html 用于 Axis,但似乎更普遍适用于 weblogic 上的自定义战争。它指出

如果你想部署自定义 WAR,比如在集群环境中,你需要在 WEB-INF 中分别添加两个文件,分别命名为 modules 和 services 目录下的“services.list”和“modules.list”。

WEB-INF/services/services.list :应该列出您想要公开的所有服务(aar 文件)。 WEB-INF/modules/modules.list : 应该列出你想要使用的所有模块(mar 文件)。

注意:在这两种情况下,请每行列出一个条目。

WebLogic 附带的 JAR 与 Axis2 中存在的 JAR 冲突。因此用于确保打包在 Axis2 WAR 中的 JAR 是从 WEB-INF/lib 中提取的。您可以通过将 WEB-INF/weblogic.xml 中的元素设置为 true 来执行此操作。 weblogic.xml 的示例如下所示:

<weblogic-web-app>
     <container-descriptor>
         <prefer-web-inf-classes>true</prefer-web-inf-classes>
     </container-descriptor>
</weblogic-web-app>

如果设置为 true,则该元素将强制 WebLogic 的类加载器加载位于 Web 应用程序的 WEB-INF 目录中的类,而不是应用程序或系统类。这是推荐的方法,因为它只影响单个 Web 模块。

对于 CXF,类似的文档位于 http://cxf.apache.org/docs/application-server-specific-configuration-guide.html#ApplicationServerSpecificConfigurationGuide-WebLogic

在 META-INF 文件夹中创建一个 weblogic-application.xml(特定于 Weblogic)。

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-application xmlns="http://www.bea.com/ns/weblogic/90">
    <application-param>
        <param-name>webapp.encoding.default</param-name>
        <param-value>UTF-8</param-value>
    </application-param>
    <prefer-application-packages>
        <package-name>javax.jws.*</package-name>
    </prefer-application-packages>
</weblogic-application>

【讨论】:

  • 我已经为 log4j 定义了类似的东西。我在使用 WLS jar 时遇到了问题,因此我在 weblogic.xml 中添加了以下代码:org.slf4j-application-packages> 我会测试那个参数并告诉你会发生什么。谢谢。
  • 您的服务在 services.list 中吗?
  • 不。我正在使用 apache CXF,所有配置都是通过 java 配置类完成的,我在其中定义服务端点。服务列表在部署时生成。我可以查看和使用所有服务和所有服务方法,并且除了删除方法之外,它们都可以与 @WebParam 注释一起正常工作。奇怪的行为。正如您之前提到的,我认为这个问题更多地与 WLS 执行的 jars 相关,而不是其他任何事情。
  • 除了我不使用任何配置文件(也不使用 xml 或属性)之外,我认为 services.list 对 Axis 来说是可以的,但与 CXF 无关。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-20
  • 1970-01-01
  • 2014-03-12
  • 2014-09-10
  • 2016-05-05
  • 1970-01-01
相关资源
最近更新 更多