是否可以在 jar 中公开 JAX RS 类 而无需在 web.xml / Application 子类中声明它们?

Is it possible to expose JAX RS classes inside jars without declaring them in web.xml / Application subclass?

我们正在尝试创建一个 .ear 项目,其中的 Web 应用程序公开了一些剩余 api。 该项目包括 "micro jars" 表示一些业务逻辑(由 @Path 注释),每个 jar 包含一些剩余 class (由 @Path 注释)。 该应用程序符合 Java EE 7 并部署在 WAS 9 实例上,结构化 .ear 是下面一个:

project.ear
|
|- META-INF
|    |- application.xml
|
|-lib
|    |- service1.jar                (with rest classes)
|    |              |- META-INF
|    |                      |- beans.xml
|    |              
|    |              
|    |
|    |- service2.jar  (with rest classes, same structure as service1.jar)
|    |   
|    |- core.jar      (with Application subclass, same structure as service1.jar)
|    
|    
|- app.war
|    |- classes (empty)
|    |- web.xml
|    |- beans.xml

web.xml 中的 .war 包包含对自定义应用程序 sub[=70 的引用=]:

<servlet>
  <description>JAX-RS Tools Generated - Do not modify</description>
  <servlet-name>JAX-RS Servlet</servlet-name>
  <servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
  <init-param>
    <param-name>javax.ws.rs.Application</param-name>
    <param-value>com.example.MyApplicationSubclass</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>


<servlet-mapping>
  <servlet-name>JAX-RS Servlet</servlet-name>
  <url-pattern>/resources/*</url-pattern>
</servlet-mapping>

每个 bean.xml 看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
     http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
     bean-discovery-mode="all">
 </beans>

MyApplicationSubclass 是空的,它确实有任何重写的方法并且使用基本的 @ApplicationPath 注释进行注释。

在 WebLogic 和 JBOSS 等其他 AS 上,不需要明确的 servlet 声明,一切都会自动发现,但在 WAS 上,我们发现了这些主要问题:

  1. 自动发现已完全关闭,@ApplicationPath@Path class 均未自动发现。
  2. MyApplicationSubclass 必须包含在 web.xml 的 .war
  3. 即使在 web.xml 中声明了 MyApplicationSubclass,也不会自动发现其余端点
  4. 即使通过反射,也无法从 MyApplicationSubclass 找到休息点 classes

有什么建议吗?为什么这个结构在其他AS上没问题? 这些问题与 Apache CXF 相关吗?

注意:我们也尝试使用父最后加载策略启动应用程序,但问题仍然存在。

问题很可能是应用程序 类 没有打包在 WAR 文件中。根据 JAX-RS 规范的第 2.3.2 节(我使用的是 JAX-RS 2.1 规范,但我相信相同的规则适用于 2.0):

A JAX-RS application is packaged as a Web application in a .war file. The application classes are packaged in WEB-INF/classes or WEB-INF/lib and required libraries are packaged in WEB-INF/lib.

听起来 WebSphere 比您试验过的其他一些应用服务器更符合字面意思。

因此,最简单、最可靠的解决方法是将 JAX-RS 应用程序 类 打包到 WAR 的 WEB-INF/classes 或 [=25] 的 JAR 中=] 目录而不是 EAR 的 lib 目录。

另一个选项(我自己没有测试过)可能是将 Class-Path: 属性添加到您的 WAR 的清单文件中,以显式引用包含 JAX-RS 应用程序的 JAR - iiuc ,这应该将这些 JAR 放在与 web 模块的其余部分相同的类路径中,从而允许加载它。

第三个选项(我也没有测试过)可能是将应用程序 类 放入共享库,然后将该共享库与 Web 模块相关联。

希望对您有所帮助!