You need to enable JavaScript to run this app. 如何为REST API项目创建带依赖Jar包?打包运行报CXF错误如何解决?
优惠活动
大模型
产品
解决方案
定价
更多

如何为REST API项目创建带依赖Jar包?打包运行报CXF错误如何解决?

问题根因

你遇到的启动报错和业务代码逻辑无关,核心是Maven Assembly打全量Fat Jar时,*SPI(服务发现机制)*的配置文件被覆盖丢失:

  • 开发环境直接在控制台运行代码时,所有CXF依赖JAR独立加载,每个JAR包内META-INF/services路径下的SPI配置文件可被Java ServiceLoader正常扫描识别,自动将HTTP传输对应的HttpDestinationFactory注册到CXF全局Bus上,因此服务可正常启动。
  • 使用Maven Assembly构建包含全部依赖的Jar包时,默认打包规则会将所有依赖包内的文件解压后统一归档到最终Jar包;遇到相同路径的SPI配置文件时,会直接用后加载的文件覆盖先加载的内容,最终导致CXF HTTP传输组件的注册配置丢失,抛出“找不到已注册HttpDestinationFactory”的异常。
  • 你尝试删除setAddress传入值里的http前缀后程序不报错的现象,是因为去掉协议头后,CXF会将该地址识别为本地直连的非网络监听地址,不会触发HTTP传输组件的初始化逻辑;但此时程序根本没有启动端口监听,自然无法通过HTTP访问REST接口。
需补充的必要配置
  • 调整maven-assembly-plugin的打包策略,新增对META-INF/services目录的文件合并规则,避免SPI配置被覆盖。在assembly的打包描述符中增加如下合并配置,确保所有依赖的服务声明文件内容被整合到同一最终文件中:
    <containerDescriptorHandlers>
      <containerDescriptorHandler>
        <handlerImplementation>
          org.apache.maven.plugins.shade.resource.ServicesResourceTransformer
        </handlerImplementation>
      </containerDescriptorHandler>
    </containerDescriptorHandlers>
    
  • 若不调整打包配置,可在业务启动代码中手动注册HTTP传输组件,绕过SPI自动加载失效的问题。在初始化JAXRSServerFactoryBean的逻辑中补充以下代码:
    // 获取CXF全局默认Bus
    Bus bus = BusFactory.getDefaultBus();
    // 手动将HTTP传输工厂注册到Bus扩展点
    bus.setExtension(new HTTPTransportFactory(), HttpDestinationFactory.class);
    // 将注册完成的Bus绑定到服务工厂
    sf.setBus(bus);
    
  • 检查项目依赖完整性,确认已引入CXF内置Jetty HTTP监听模块cxf-rt-transports-http-jetty。如果只引入了JAXRS API相关依赖、缺失该传输层组件,哪怕SPI配置正常,也会因为没有实际的HTTP服务实现类抛出相同报错。

内容的提问来源于stack exchange,提问作者John Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.01 08:06:01