How are you supposed to access EJB when using Easyrest? - java

I have been trying to get Resteasy to work (and not it dose). However I now have another headache with accessing the EJB:s. I have tried injecting them, looking them up with jndi and most other solutions but none of them works.
I get massages like: java.lang.RuntimeException: Class is not a root resource.
Or: java.lang.IllegalArgumentException: Wrong target.
Or just: NullPointer
Using JBoss 5.1.0.GA and Resteasy 1.2.1.GA... Can't find any documentation on how this could be done. Do anybody know?

Have you seen this: EJB Integration?
Resteasy currently only has simple integration with EJBs. To make an EJB a JAX-RS resource, you must annotate an SLSB's #Remote or #Local interface with JAX-RS annotations:
Next, in RESTeasy's web.xml file you must manually register the EJB with RESTeasy using the resteasy.jndi.resources

Related

How to add a EJB Interceptor programmatically?

I'm trying to add a Interceptor in a EJB at runtime programmatically via CDI extensions.
This EJB exposes a Remote interface for remote calls. But I'm trying to add this Interceptor in the implementation class of this EJB adding the #Interceptors annontation like in this other SO question (CDI Extensions - Add Interceptors in ProcessAnnotatedType phase)
I think the CDI Extension only executes after the EJB are already registered because the Interceptor is never called.
But, for test purpose I have successfully register and execute an Interceptor programmatically in a simple CDI Bean.
The problem is when I'm try to register in a EJB.
Am I missing something?
Edit:
I'm using Wildfly 8
I think the key problem here is the difference between #Interceptors (EJB ones) and #Interceptor (CDI ones). CDI does not govern EJB container hence adding the EJB annotation (#Interceptors) in CDI extension won't necessarrily kick EJB logic into effect - EJB container might have started at that moment and it won't know of the annotation. Furthermore the CDI extension would add this annotation to the AnnotatedType which is a structure EJB probably won't make use of. On the other hand, all this really depends on the application server as it is responsible for CDI/EJB integration hence as a "bonus" the behavior might differ between AS.
CDI extension is something which allows you to hook into CDI bootstrap lifecycle, therefore you are able to use/enable/add CDI interceptors. I would try going that way instead. BTW even the SO question you referred to speaks of beans.xml/#Priority for enablement which means it uses CDI interceptors and not EJB ones.
Also, an EJB bean should automatically become CDI bean therefore you can attach CDI interceptor to it without changing the bean itself.

Creating EJB 3.0 or 3.1

I would be very much thankful to clear me some question about this new EJB3.0 and above version:
1) if suppose I need ejbCreate, ejbActivate and all other events so how can I get it from the new EJB3.0 and above ver.
2) I always have problem to find particular xml file to alocate a JNDI name according to variety of Application Servers so is there any way that I can give JNDI name without xml file and can also be use a portable name that in every Application Server it can be findable of EJB deployed on app server remotely
3)Can any buddy tell me, i have hosting plan of Java/Linux which supports
i) Tomcat - 5.5.xSupport
ii)JDK - 1.6.x Support
iii)JSP/servlet - 2.0 Support
can it be possible that EJB 3.1 be deployed because some where i have got that tomcat is not able to deploy EJB so please give me some advice help...
Thank You...!!!
please Help me...!!!
1) if suppose i need ejbCreate, ejbActivate and all other events so
how can i get it from the new EJB3.0 and above ver.
In EJB 3 and above, the EJB lifecycle is handled through life cycle annotations, such as: #PostConstruct and #PreDestroy.
2) i always have problem to find perticular xml file to alocate a JNDI
name according to variety of Application Servers so is there any way
that i can give JNDI name without xml file and can also be use a
portable name that in every Application Server it can be findable of
EJB deployed on app server remotly
The #Stateless and #Stateful annotations have two attributes that might solve this issue (name and mappedName). Yet
The mapped name is product-dependent and often installation-dependent.
Hope it helps you.
1) ejbCreate, ejbActivate etc. are related to EJB 2.x, if you need similar functionality in EJB 3.x, you should decorate your methods with annotations #PostActivate, #PrePassivate etc. Method signature should follow certain rules, example for #PostActivate:
The method annotated with #PostActivate must follow these
requirements:
The return type of the method must be void.
The method must not throw a checked exception.
The method may be public, protected, package private or private.
The method must not be static.
The method must not be final.
This annotation does not have any attributes.
2) It seems that you're referring to name and mappedName attributes of #Stateless and #Stateful annotations. For more details see official documentation. From my experience mappedName is better, but it's application-server-specific, e.g. on Glassfish it works perfectly. Example:
#Stateless(mappedName="ejb/myBean")
public class MyFirstBean {
..
}
Since no one answered Question 3 ..
3)Can any buddy tell me, i have hosting plan of Java/Linux which supports i) Tomcat - > 5.5.xSupport ii)JDK - 1.6.x Support iii)JSP/servlet - 2.0 Support
No, you are going to need a server that supports Java EE. Read How to deploy EJB based application on Tomcat

Apache CXF web services problems

I have a multi-module project using Maven. On one of the modules I have several web services developed using Apache CXF Framework 2.5.4. At the moment I have two "problems" or questions.
First of all, if I call to a method of one of the web services that should return a List, if the list is empty, it returns "null" instead of the empty list.
I was trying to find out what could be the problem, if it's a bug of the CXF version I'm using or if I should use some annotation to modify the definition of the method or the response, but I couldn't find anything. I've seen some people with the same problem, but no solution.
The other thing I wanted to ask is: I'm developing a web application using MVC pattern. I'm wondering which way I should call the web service from the Controller instead of using ClasspathXmlCpplicationContext and then context.getBean().
For example, the bean definition for one of the web services on the client side is:
<jaxws:client id="deviceWSClient"
serviceClass="..IDeviceWebService"
address="http://localhost:8080/../DeviceWS" />
I've already tried usin #Autowired or #WebServiceRef annotations. With these it works but not doing a HTTP request to the web service, I guess it gets the dependency from the local repository. I think what I need is the way of injecting this bean on the Controller.
To answer your questions
For your first question: If the list is empty it is correctly handled by CXF version 2.6.1 - the service returns a empty. Just to demonstrate I have a sample service where types are defined this way:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "MemberSearchResponse", namespace="http://bk.org/memberservice/" )
public class MemberSearchResponse {
#XmlElementWrapper(name="memberDetails")
private List<MemberDetail> memberDetails;
If I return a empty memberDetails above, the xml that goes over the wire is this:
<ns2:searchMemberResponse xmlns:ns2="http://bk.org/memberservice/">
<ns2:MemberSearchResponse>
<memberDetails/>
</ns2:MemberSearchResponse>
</ns2:searchMemberResponse>
EDIT
It is correctly handled as part of a wrapper type like above, but DOES return null if instead of returning a wrapper type, the list is directly returned.
Consider a Webservice interface defined this way:
#WebMethod(operationName = "searchMember")
List<MemberDetail> searchMember(#WebParam(name = "MemberSearchRequest") MemberSearchRequest memberSearchRequest);
If the List returned is an Empty list, it gets serialized as null by CXF 2.6.1 also.
The workaround is to use a wrapper type
EDIT END
For your second question:
You are creating a client bean this way:
<jaxws:client id="deviceWSClient"
serviceClass="..IDeviceWebService"
address="http://localhost:8080/../DeviceWS" />
Once you have created a Spring bean this way, you can treat it just like a normal Spring bean and inject it the way you would do with any normal Spring bean, for eg, either inject it this way:
<bean id="consumerBean" class="...">
<property name="deviceWS" ref="deviceWSClient">
</bean>
or use #Autowired
#Autowired IDWebService deviceWSClient
Or user #Resource
#Resource IDWebService deviceWSClient
These are the usual ways of injecting in a bean.
I have a sample application at this github location that you can play with:
https://github.com/bijukunjummen/memberservice-codefirst.git
Just start up the server using mvn tomcat:run and run a test org.bk.memberservice.TestCxfIntegrationTest which will make a request to the CXF service.
#WebServiceRef probably works if you follow this link on Spring forum. There you use different way for jaxws configuration. See the last post on the list.
Another ways to define the client are discussed on this SO question. There is e.g a solution where you finally use #Autowired annotation after you have given some extra configuration. See the last answer on the question.
The another issue you mentioned was about this cxf List related issue where also a solution is told for a workaround to the problem. So it is a bug. Version 2.2.7 has it fixed, but again in version 2.2.9 problem is arisen again. Wierd that until your version 2.5.4 it is back on error state. You could try the work around still, if it fixes the issue for you.

Integrating EJB3 with Spring

I'm building application with EJB and Spring 3. I have three maven modules - Spring jars, EJB jar and web part. In the web part I want to call my EJB session bean. Here comes the code of it:
#Controller
public class IndexController {
#EJB
PaymentRemote paymentRemote;
}
I have also an application context file, with the content:
<jee:local-slsb id="paymentRemote" jndi-name="ejb/myBean"
business-interface="net.learntechnology.ejb.PaymentRemote"/>
and
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
<property name="alwaysUseJndiLookup" value="true"/>
In my ejb module I have an interface:
#Local
public interface PaymentRemote {
}
Unfortunately when I deploy it on JBoss as 5 i get the following error:
Error creating bean with name 'paymentRemote': Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: ejb not bound.
I saw a lot of examples in net and all are configured like this. I'm stuck with it...
Could any one help me with this? I would be more than grateful!
For JBOSS the proper pattern is:
application-name/bean/remote or local
Since my comment turned out to be the answer, I'll rephrase it....
Make sure that the EJB is actually bound to JNDI under the name you're expecting. The error message suggests that it's not.
In JBoss, to the JMX Console, look for the JNDIView object, and invoke its list method. If your EJB is present on ejb/myBean, it should appear here. If not, look for its under a different name, and bind to that.

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