简体   繁体   English

Glassfish4服务器和jersey2:glassfish为什么要向应用程序提供自己的jersey2

[英]Glassfish4 server & jersey2: why does glassfish provide its own jersey2 to application

Recently I tried to deploy a Jersey2 application to Glassfish4.1. 最近,我尝试将Jersey2应用程序部署到Glassfish4.1。 I had lots of dependency issues and found a lot of ClassCastException. 我有很多依赖项问题,并且发现了很多ClassCastException。

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

I have to configure pom.xml like: 我必须像这样配置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>

If you are using Glassfish application server, you don't need to package anything with your application, everything is already included. 如果您使用的是Glassfish应用程序服务器,则无需在应用程序中打包任何内容,所有内容均已包含在内。 You just need to declare (provided) dependency on JAX-RS API to be able to compile your application. 您只需要声明(提供)对JAX-RS API的依赖关系就可以编译您的应用程序。

My question is that why Glassfish have to provide jersey2 (JSR implementation) itself for application. 我的问题是,为什么Glassfish必须自己提供jersey2(JSR实现)才能进行应用。 Why not just let application to choose the JSR implementation it is using? 为什么不让应用程序选择它正在使用的JSR实现呢?

I also add glassfish-web.xml under WEB-INF : 我还在WEB-INF下添加glassfish-web.xml

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

According to the document here ( https://docs.oracle.com/cd/E19798-01/821-1752/beagb/index.html ): 根据此处的文档( https://docs.oracle.com/cd/E19798-01/821-1752/beagb/index.html ):

It will let Glassfish to load classes under WEB-INF/lib/ first. 它会让Glassfish首先在WEB-INF/lib/下加载类。 But why does Glassfish still use its own jersey version and javax version? 但是,为什么Glassfish仍然使用自己的球衣版本和javax版本?

For javax, I guess Glassfish is a java application version and it only support specific JSR implementations. 对于Javax,我猜Glassfish是Java应用程序版本,它仅支持特定的JSR实现。 So when I choose JSR implementation in my application, and I have to find out the correct version of Glassfish. 因此,当我在应用程序中选择JSR实现时,我必须找出正确的Glassfish版本。

But why is jersey2 so special that glassfish have to provide it. 但是,为什么jersey2如此特别,以至于玻璃鱼必须提供它。 What if I want to use another version of jersey2? 如果我想使用另一个版本的jersey2,该怎么办?


Updated: 更新:

I ran some more tests. 我进行了更多测试。

When I deployed a jersey1 application (jersey1 is included in war file) to glassfish4 and asked glassfish4 to delegate class loader process to its parent, and this application works, and application can handle incoming rest requests. 当我将jersey1应用程序(war1中包含jersey1)部署到glassfish4并要求glassfish4将类加载器进程委托给它的父级时,该应用程序开始工作,并且应用程序可以处理传入的其余请求。 Why? 为什么? I guess since glassfish does not have jersey1 included, it will load jersey1 from libraries inside war file, and glassfish4 is actually working with jersey1. 我猜因为glassfish不包含jersey1,它将从war文件中的库中加载jersey1,而glassfish4实际上正在使用jersey1。 Does this mean I can override glassfish default behavior to let application to choose the JAX-RS implementation. 这是否意味着我可以重写glassfish的默认行为,以使应用程序选择JAX-RS实现。

And if I replaced jersey1 with jersey2 and still let glassfish4 to load libraries from war first, there was an exception thrown: 如果我用jersey2替换jersey1,但仍然让glassfish4首先从war加载库,则会引发异常:

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)

How did this exception happen? 异常是如何发生的?

My question is that why Glassfish have to provide jersey2 (JSR implementation) itself for application. 我的问题是,为什么Glassfish必须自己提供jersey2(JSR实现)才能进行应用。 Why not just let application to choose the JSR implementation it is using? 为什么不让应用程序选择它正在使用的JSR实现呢?

Because Glassfish is a Java EE compliant server, and JAX-RS is part of the EE spec. 因为Glassfish是Java EE兼容服务器,而JAX-RS是EE规范的一部分。 So it needs an implementation of JAX-RS to run a JAX-RS application. 因此,它需要JAX-RS的实现才能运行JAX-RS应用程序。 It just happens to use Jersey as the implementation , just like JBoss uses RESTEasy. 恰好是使用Jersey作为实现,就像JBoss使用RESTEasy一样。 If the server didn't have an implementation, then it wouldn't be EE compliant. 如果服务器没有实现,那么它将不符合EE。 An application should be able to run a complete EE application only compiling the application against the single EE jar. 应用程序应仅能够针对单个EE jar编译应用程序,才能运行完整的EE应用程序。 It shouldn't have to know anything about implementations. 它不需要了解任何实现。

What if I want to use another version of jersey2? 如果我想使用另一个版本的jersey2,该怎么办?

You can just try to replace all the Jersey implementation jars with new ones. 您可以尝试用新的替换所有Jersey实施jar。 See Updating Jersey 2 in GlassFish 4 . 请参阅在GlassFish 4中更新球衣2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM