How would I build Rest + EJB using Weblogic? - java

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>

Related

Adding Spring boot to existing JSP project

We have an existing JSP project that serves a website and a REST interface. However its an old project (started in 2013) and now it does not scale well with new requirements. We would like to add Spring REST interface under the same project (sharing same tomcat and sessions) until we we migrate completely and drop the old REST interface (and the website) entirely.
Current project structure is:
Root/
website/
rest/
WEB-INF/
web.xml
classes/
META-INF/
context.xml
Current rest interface is accessible via /rest/xyz.jsp
Now we would like to use Spring and migrate rest/* such that they will be accessible via /api/*
How do I integrate Spring boot into this project? what set of configuration do I need to make?
Spring boot docs and internet weren't helpful.

WebSphere 9 : JAX-WS WebService Unable to Deploy

My Project recently decided to move to WebSphere 9 from WAS 8.5.5.6 and as part of this upgrade, we had JAX-WS services that needs to work as-is.
A little background on services - We had been using SUN Reference Implementation (sun-jaxws.xml) which was easier to configure, however with WAS upgrade sun-jaxws.xml file is now completely ignored along with the web.xml entries we had.
Steps we took to migrate from 8.5.5.6 to 9:
Migrated web.xml spec to 3.1 and removed all entries which were specific to Sun reference implementation (e.g. WSServletContextListener, or WSServlet and all the <servlet> and <servlet-mapping> entries)
Each of our services by default had #WebService annotation so we didn't had to make any changes there.
All our EJB's were modified from EJB 3.1 to EJB 3.2 - Again, since all of our code was already using Java based annotations, we didn't had to make any changes (just updated ejb-jar.xml to 3.2)
After doing the changes, we deployed the application and initially I got one common error for most of the web services:
JAX-WS Service Descriptions could not be correctly built because of the following error: javax.xml.ws.WebServiceException
Caused by: java.lang.Exception: A WSDL Definition could not be generated for the implementation class: gov.state.ServiceImpl
at com.ibm.ws.websvcs.wsdl.WASWSDLGenerator.generateWsdl(WASWSDLGenerator.java:257)
After getting the above error, I added wsdlLocation attribute on my web service implementation class as below:
#javax.jws.WebService(endpointInterface = "gov.state.ServiceIntegrationBean",
targetNamespace = "http://st.services.state.gov",
serviceName = "ServiceIntegrationService",
portName = "ServiceIntegration",
wsdlLocation="wsdl/ServiceIntegration/ServiceIntegration.wsdl")
The Error went away, server started all well - But my WSDL is not hitting the URL I configured..
Does anyone have any idea on what else I could be doing wrong.. or perhaps, if anyone knows how to re-use Sun Reference Implementation of JAX-WS WebServices on WebSphere 9?
Any help will be much appreciated.

RESTful service in Karaf without blueprint xml

I am new to Karaf, hence was looking for resources to create a project for RESTful web services using felix annotations and without the use of BundleActivator class(i mean by an actual class that needs to be written by me, but its ok if some compiler or maven plugin does the same for me) and blueprint xml file. So far I got success in the first part(BundleActivator part) which now after compilation auto creates my MANIFEST.MF with import and export statements, creates the relevant XML file for each component class, and packages it into a a nice jar bundle which works very well when I deploy it on Karaf container. But what is not working is the RESTful services. The bundle is deployed correctly, but the REST urls are not exposed and hence I am unable to access them.
Please help me in getting this done. I don't want to write an XML file which needs to be modified everytime there is an addition or deletion of a rest service.
Thanks
If you want to completely avoid blueprint then you should use cxf-dosgi. You simply annotate your rest service using jaxrs and publish it as an OSGi service with some special properties.
See the cxf-dosgi rest sample.
The example uses the standard DS annotation and the maven bundle plugin to create the DS component xml on the fly.
If you prefer to have blueprint at runtime then you can use the blueprint-maven-plugin. See this example.
I figured out a way to do so without using the CXF feature. That is, create a component class and in activate method get the object of ConfigurationAdmin and put the required context path against the jersy server process(using jersey publisher jar). Using this mehtod, I was able to deploy any rest/serlvet in Karaf without using blueprint.xml file. I hope this helps.

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

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.

Annotations (#EJB, #Resource, ...) within a RESTful Service

I'm trying to inject a EJB within my RESTful Service (RESTEasy) via Annotations.
public class MyServelet implements MyServeletInterface {
...
#EJB
MyBean mybean;
...
}
Unfortunately there is no compilation or AS error, the variable "mybean" is just null and I get a NullPointerException when I try to use it.
What I'm doing wrong?
Here are some side-informations about my architecture:
JBoss 4.2.2.GA
Java version: 1.5.0_17
local MDB-Project
remote EJB-Project
WAR Project with the RESTful Service which uses the remote EJB and sends messages to the local MDB-Project
Thanks in advance!
br
Dominik
p.s: everything is working fine when I use normal context lookup.
I had a similar problem (though without #Remote beans). The way it worked for me - sample application is here: https://github.com/kubamarchwicki/rest-app/ (this works: https://github.com/kubamarchwicki/rest-app/blob/master/service-webapp/src/main/webapp/WEB-INF/web.xml#L9)
The crack with context lookup is that the name changes with a change of the ear name. If you fancy things like versions, it makes the whole thing hard to trace or forces you to hardcode ear name somewhere in the code.
Just a few cents to an old discussion ;-)
This is not exactly my forte, so maybe I am way off... but, can you do EJB stuff in a WAR? I was under the impression you needed to do EJB work in an EAR.
JBoss 4.2.2.GA is not a fully compliant Java EE 5 server, it does not support EJB references injection in servlets or application clients, only in the EJB layer. Use JBoss 5 for that (or perform a lookup).
JBoss 4.2.2.GA supports only Servlet 2.4. There is no support of DI on Servlet 2.4. Hence you always get 'null' for myBean variable. As suggested, please migrate to JBoss 5.0 which supports Servlet 2.5 which makes use of Java 5 features like annotations.

Categories