Glassfish4服务器& jersey2:为什么glassfish为应用提供自己的球衣2

时间:2016-06-30 20:35:24

标签: java java-ee jersey glassfish classloader

最近我尝试将Jersey2应用程序部署到Glassfish4.1。我有很多依赖问题,发现了很多ClassCastException。

后来我在这里找到了用户指南:https://jersey.java.net/documentation/latest/modules-and-dependencies.html#servlet-app-glassfish

我必须配置pom.xml,如:

<dependency> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> <version>2.0.1</version> <scope>provided</scope> </dependency>

<dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> <version>2.23.1</version> <scope>provided</scope> </dependency>

  

如果您使用的是Glassfish应用程序服务器,则无需使用您的应用程序打包任何内容,所有内容都已包含在内。您只需要声明(提供)对JAX-RS API的依赖,以便能够编译您的应用程序。

我的问题是为什么Glassfish必须为应用程序提供jersey2(JSR实现)本身。为什么不让应用程序选择它正在使用的JSR实现?

我还在glassfish-web.xml下添加WEB-INF

<glassfish-web-app> <class-loader delegate="false" /> </glassfish-web-app>

根据此处的文件(https://docs.oracle.com/cd/E19798-01/821-1752/beagb/index.html):

首先让Glassfish加载WEB-INF/lib/下的类。但是为什么Glassfish仍然使用自己的平针版和javax版?

对于javax,我猜Glassfish是一个java应用程序版本,它只支持特定的JSR实现。所以当我在我的应用程序中选择JSR实现时,我必须找到正确的Glassfish版本。

但为什么jersey2如此特别以至于玻璃鱼必须提供它。如果我想使用另一个版本的jersey2怎么办?

更新:

我又做了一些测试。

当我将一个jersey1应用程序(jersey1包含在war文件中)部署到glassfish4并要求glassfish4将类加载器进程委托给其父进程时,此应用程序正常工作,应用程序可以处理传入的休息请求。为什么?我想因为glassfish没有包含jersey1,所以它会从war文件中的库中加载jersey1,而glassfish4实际上是在使用jersey1。这是否意味着我可以覆盖glassfish默认行为,让应用程序选择JAX-RS实现。

如果我用jersey2替换jersey1并且仍然让glassfish4首先从战争中加载库,那么会抛出异常:

WebModule[/invoiceLoader]StandardWrapper.Throwable java.lang.ClassCastException: Cannot cast org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider to org.glassfish.jersey.server.spi.ComponentProvider at java.lang.Class.cast(Class.java:3369) at org.glassfish.jersey.internal.ServiceFinder$LazyObjectIterator.hasNext(ServiceFinder.java:713) at org.glassfish.jersey.server.ApplicationHandler.getRankedComponentProviders(ApplicationHandler.java:743) at org.glassfish.jersey.server.ApplicationHandler.access$600(ApplicationHandler.java:184) at org.glassfish.jersey.server.ApplicationHandler$4.get(ApplicationHandler.java:406) at org.glassfish.jersey.server.ApplicationHandler$4.get(ApplicationHandler.java:399) at org.glassfish.jersey.internal.util.collection.Values$LazyValueImpl.get(Values.java:340) at org.glassfish.jersey.server.ApplicationHandler.createApplication(ApplicationHandler.java:366) at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:342) at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:392) at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:177)

这个异常是如何发生的?

1 个答案:

答案 0 :(得分:3)

  

我的问题是为什么Glassfish必须为应用程序提供jersey2(JSR实现)本身。为什么不让应用程序选择它正在使用的JSR实现?

因为Glassfish是符合Java EE的服务器,而JAX-RS是EE规范的一部分。因此,它需要JAX-RS的实现来运行JAX-RS应用程序。它恰好使用Jersey作为实现,就像JBoss使用RESTEasy一样。如果服务器没有实现,那么它将不符合EE。应用程序应该能够运行完整的EE应用程序,仅针对单个EE jar编译应用程序。它不应该对实现有任何了解。

  

如果我想使用其他版本的jersey2怎么办?

您可以尝试用新的替换所有Jersey实施jar。请参阅Updating Jersey 2 in GlassFish 4