Recently I tried to deploy a Jersey2 application to Glassfish4.1. I had lots of dependency issues and found a lot of ClassCastException.
Later I found the user guide here: https://jersey.java.net/documentation/latest/modules-and-dependencies.html#servlet-app-glassfish
I have to configure pom.xml like:
<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. You just need to declare (provided) dependency on JAX-RS API to be able to compile your application.
My question is that why Glassfish have to provide jersey2 (JSR implementation) itself for application. Why not just let application to choose the JSR implementation it is using?
I also add glassfish-web.xml under WEB-INF:
<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):
It will let Glassfish to load classes under WEB-INF/lib/ first. But why does Glassfish still use its own jersey version and javax version?
For javax, I guess Glassfish is a java application version and it only support specific JSR implementations. So when I choose JSR implementation in my application, and I have to find out the correct version of Glassfish.
But why is jersey2 so special that glassfish have to provide it. What if I want to use another version of 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. 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. Does this mean I can override glassfish default behavior to let application to choose the JAX-RS implementation.
And if I replaced jersey1 with jersey2 and still let glassfish4 to load libraries from war first, there was an exception thrown:
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. Why not just let application to choose the JSR implementation it is using?
Because Glassfish is a Java EE compliant server, and JAX-RS is part of the EE spec. So it needs an implementation of JAX-RS to run a JAX-RS application. It just happens to use Jersey as the implementation , just like JBoss uses RESTEasy. If the server didn't have an implementation, then it wouldn't be EE compliant. An application should be able to run a complete EE application only compiling the application against the single EE jar. It shouldn't have to know anything about implementations.
What if I want to use another version of jersey2?
You can just try to replace all the Jersey implementation jars with new ones. See Updating Jersey 2 in GlassFish 4.
Related
I have a web application running on Weblogic. It has com.jamonapi:jamon:2.81 as maven dependency.
I'm using org.springframework.aop.interceptor.JamonPerformanceMonitorInterceptor with aop configuration. For every service/dao method call, jamon interceptor calculates statistics and stores them in memory.
I setup a jetty base for deploying jamon.war and started it. I can access it via http://localhost:3162/jamon/jamonadmin.jsp
However, it shows only local statistics. It doesn't show any statistics from my web application running on Weblogic. This did not suprise me since I didn't do any configuration for this. The question is that how can I do this magic configuration to make jamon.war see the statistics collected in my web application running on weblogic.
Thanks.
You need to define jamon as a provided scope dependency in your webapp's pom.xml.
<dependency>
<groupId>com.jamonapi</groupId>
<artifactId>jamon</artifactId>
<version>2.81</version>
<scope>provided</scope>
</dependency>
This will ensure that your Weblogic webapp uses the jamonapi.jar files in your servlet container (jetty/lib/jamon-2.81.jar) instead of a duplicate copy deployed with the webapp itself.
Is it possible to override settings in TomEE for the embedded CXF JaxRS container? I've been trying to integrate my own in-interceptor for handling rouing of JaxRS services.
What I can't seem to do is get TomEE to load the interceptor when starting my service.
I've read a bunch of stuff that says that I should be able to configure the CXF stuff in TomEE by adding <pojo-deployment> to an openejb-jar.xml file in either META-INF or WEB-INF. When I try using this approach, my interceptor never gets called.
I've also seen references that state that TomEE uses tomee.xml to replace openejb-jar.xml, so I tried to do the pojo-deployment stuff there, but then I get an XML parse error because tomee.xml doesn't seem to understand the pojo-deployment tag.
Can someone point me to some decent docs or better yet a small example of configuring CXF in TomEE?
Thanks
openejb-jar.xml is the way to do it
I blogged about it here http://rmannibucau.wordpress.com/2012/10/04/jax-rsjax-ws-configuration-for-tomee-1-5-0/
only change on recent tomee version is the fact you need to set as class-name the jaxrs application you use (if noone use "jaxrs-application" which means default behavior)
so something like:
<openejb-jar xmlns="http://www.openejb.org/openejb-jar/1.1">
<pojo-deployment class-name="jaxrs-application">
<properties>
cxf.jaxws.in-interceptors = org.superbiz.MyInInterceptor
</properties>
</pojo-deployment>
</openejb-jar>
We are in the OSGi world.
JPA 2.1 supports injectable EntityListner.
And EclipseLink supports JPA 2.1.
But the OSGi Enterprise Spec 4.x only supports JPA 2.0.
So it seems that injectable EntityListener doesn't work in OSGi, even when EclipseLink supports them.
Is it currently possible to define EntityListener in blueprint.xml and use them for injection? This would allow to inject OSGi Services into an Entity Listener. (Currently we need an explicit lookup using FrameworkUtil to do the lookup.)
Has anybody done so successfully and can share some hints, especially in regard to the used bundle (versions)?
Have you tried using the following maven dependency with org.eclipse.persistence.jpa.PersistenceProvider in the provider-Element of the persistence.xml? In the case of a JEE application server, the classloader would prefer libraries packaged with the deployed application by the ones bundled with the server itself.
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.1</version>
<scope>provided</scope>
</dependency>
So I have a simple ejb (#stateless) deployed on a glassfish 3.1 server.
I want to call it from a standalone application.
It's working great if I add the gf-client.jar into my run configuration.
But how can I do if I do not have that file (the server is in another machine) ?
I tried using
<dependency>
<groupId>org.glassfish.common</groupId>
<artifactId>glassfish-naming</artifactId>
<version>LATEST</version>
</dependency>
But I have
Exception in thread "main" javax.naming.NameNotFoundException: java:global
at com.sun.enterprise.naming.impl.TransientContext.resolveContext(TransientContext.java:252)
at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:171)
at com.sun.enterprise.naming.impl.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:58)
at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:95)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:233)
at javax.naming.InitialContext.lookup(Unknown Source)
at be.java.tuto.Application.main(Application.java:17)
Thanks.
EDIT:
I just needed to invoke an EJB deployed on GF from my Tomcat server and resurrected my dependencies. And because I dont want to keep them back for myself :)...
My IDE is Eclipse so I created an User Library containing all the files shown above.
Hope this solves your problem!
I was facing the same problem. For just wanting to invoke a GF session-Bean method I had to add the complete gf-client.jar to my clients classpath.
My problem was that this library is referencing almost the whole GF-libray-folder and even after a clean-up there were >15 referenced jars left which I had to add to my clients classpath.
For me I did't want this overhead so I decided to call the remote method via JAX-WS webservice.
The advantage of using webservises is that it is very easy to add webservice capability to an already existing session-bean by annotating the bean-class with #WebService.
After publishing the bean to the appserver you're able to view your deployed endpoint and getting the WSDL. With this you can generate your webservice-stubs automatically by using the wsimport-tool shipped with your JDK and use this generated files in yor client to invoke the remote method.
See example here.
Once created those files are portable and can be used in any client.
So if your willing to change the way your client calls the remote method this would be a portable, lightweight (except of a bit more http overhead) and easy to implement alternative.
P.S.
You don't lose the ability of invoking your method via EJB-call.
Hope this helped, have Fun!
I have a need to build 1 restful web service using weblogic. This web service will have parameters to select a what data the service should return. Like 'customer', or 'product'.
Now I want to deploy the 'customer' and 'product' code as a separate deployable applications, so that I can add or remove new code without redeploying all the code each time there is a change.
So I want one generic webservice to call this business logic.
My question is, what is the best way to structure this? Can I deploy separate EJBs for my business logic and have the web service invoke the EJBs based on the passed parameters?
Or should I have the business components as a shared library and call them that way? I am looking for a way to get the best performance.
I will have about 20 different business modules written by other programers. Like I said I don't want all the modules in the same EAR or WAR file. They need to be separately deployable.
Any thoughts?
WebLogic 10.3.4 includes new Java EE6 API support including JAX-RS 1.1 with Jersey. We recently did a webcast on this functionality and Webcast #4 covers JAX-RS. Here's the link: http://www.oracle.com/technetwork/middleware/weblogic/learnmore/weblogic-javaee6-webcasts-358613.html There is also an example application on this called Oracle Parcel Service and you can download the code here: https://www.samplecode.oracle.com/sf/projects/oracle-parcel-svc/.
If you use JAXB you can marshall from JSON and XML into the same Java object. The challenge here is that the JAXB generated classes are not serializeable by default so if you wanted to access a remote EJB from the JAX-RS service then you would have a problem.
Since you can't have the modules in the same EAR, there is another option. You could possibly use Java EE shared libraries. Then you could deploy your EJB's as a Java EE Shared library and reference that library in your REST client. Here is an example:
In your EJB module, include something like the following in your manifest:
Extension-Name: ops-util
Implementation-Title: OPS 2.0 Utils Library EXAMPLE_ONLY
Implementation-Vendor: Oracle
Implementation-Vendor-Id: com.oracle
Implementation-Version: 2.0.1
Specification-Title: Oracle Parcel Service 2.0 Utils Library
Specification-Vendor: Oracle
Specification-Version: 2.0
Then reference the shared library in weblogic.xml (WAR) or weblogic-application.xml (EAR):
<wls:weblogic-application
xmlns:wls="http://www.bea.com/ns/weblogic/weblogic-application"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/javaee_5.xsd http://www.bea.com/ns/weblogic/weblogic-application http://www.bea.com/ns/weblogic/weblogic-application/1.0/weblogic-application.xsd">
<!-- server-version: 10.3 -->
<wls:library-ref>
<wls:library-name>ops-util</wls:library-name>
<wls:specification-version>2.0</wls:specification-version>
<wls:implementation-version>2.0.1</wls:implementation-version>
<wls:exact-match>false</wls:exact-match>
</wls:library-ref>
</wls:weblogic-application>