Use WebServiceContext outside WebService - java

In my Web service, I have:
#WebService(serviceName = "myservice")
public class ServiceName{
#Resource
private WebServiceContext context;
In a stateless class I want to use the same operation:
#Stateless
public class MakeHappen{
#Resource
private WebServiceContext context;
But I receive an EJB exception. How can I inject this resource, outside webservice?

AFAIK no, only in the context of a Webservice.
See Interface WebServiceContext
A WebServiceContext makes it possible for a Webservice endpoint
implementation class to access message context and security
information relative to a request being served. Typically a
WebServiceContext is injected into an endpoint implementation class
using the #Resource annotation.
In your case, you should to decorate stateless EJB as Webservice. Open methods of the stateless EJB can be represented as Webservices.
#Stateless
#WebService
public class MakeHappen {
#Resource
private WebServiceContext context;
...

Web service endpoint belongs to a web tier and is managed by a web container (See Java EE 7 tutorial 6.1 Web Applications for more info).
Enterprise bean on the other hand is a business logic component. It is managed by EJB container (Java EE 7 tutorial 32.1 What Is an Enterprise Bean?).
This means that enterprise bean could not have WebServiceContext injected as it is managed by different container. This would also make no sense as EJB container have no WebServiceContext.

I had the same problem and this is how I solved it:
WebServiceContext wscontext = null;
try {
Context ctx = new InitialContext();
wscontext = (WebServiceContext) ctx.lookup("java:comp/WebServiceContext");
} catch (NamingException e) {
}

Related

JNDI #Resource annotation

In servlet and filter classes i can initialize DataSource variable via annotation
#Resource(name = "jdbc/testDB")
protected DataSource ds;
But how it initialize in basic class via annotation?
Usually thorows NullPointerException
public class AddAuto {
#Resource(name = "jdbc/testDB")
private DataSource ds;
}
What is your container?
If it's tomcat, the resource name should be something like this
#Resource(name = "java:/comp/env/jdbc/testDB")
protected DataSource ds;
I don't know about the other container, but JBoss would be same as Tomcat, and GlassFish as your value.
Also I suggest old lookup which help you so much for debugging
void init(){
DataSource ds=(DataSource)InitialContext.doLookup("java:/comp/env/jdbc/testDB");
}
Container inspects annotation only inside well-known componets like servlets, filters. You should transform your class to some component:
Web component (servlet, filters, web container listeners)
EJB (not supported by tomcat)
CDI beans
Or you can use non Java EE solution like spring

How come injection #Resource works outside the container?

I'm testing webservices in Java SE, and I see that #Resource does work, wasn't this true only within a Container ? or with CDI ? why does it work in SE also !?
#WebService
public class Teams {
#Resource
private WebServiceContext context;
}
I'm publishing using Endpoint.publish("http://localhost:9876/teams", new Teams());
Not true. Container will inject the instance of the resource on any EJB component.
http://docs.oracle.com/javaee/5/api/javax/annotation/Resource.html

Inject EJB 3.0 in WebLogic Server v10.3

I am having some issues trying to inject a stateless EJB into an Application Client Project. Both the App Client and the EJB are in the same EAR. Using JNDI, I am able to retrieve an instance of the EJB, but I'm not sure how should I do it with the #EJB annotation. I've tried using #EJB(name="something"), #EJB(mappedName="something"), but all I get is a null. Here is my code:
#Remote
public interface TimerEjbTestService {
public void testMethod();
}
#Stateless(mappedName="TimerEjbTestService")
public class TimerEjbTestBean implements TimerEjbTestService{
public void testMethod() {
System.out.println("Inside EJB.");
}
}
With JNDI I'm able to get the instance as follows:
Context ctx = new InitialContext();
TimerEjbTestService timerEjbTestService = (TimerEjbTestService) ctx.lookup("TimerEjbTestService#myejb.timerejbtestservice.services.TimerEjbTestService");
Any ideas on how can I do this?
You can do something like this:
#EJB
private TimerEjbTestService myBean;
In this way, the container injects the bean.
Also, since it is in the same ear (thus ran by the same JVM) the annotation for the interface should be #Local not #Remote.

How to access stateful session bean through remote interface proxy?

I have a testcase which makes use of OpenEjb's #LocalClient annotation (embedded container) and injects EJBs using the #EJB annotation:
#LocalClient
public class MyTestCase {
#EJB
private BoxDao boxDao;
...
}
BoxDao is a remote EJB interface. Now, for testing, I need to access some internal state of BoxDao's implementation BoxDaoBean, which is a stateful session bean. I created a protected method in BoxDaoBean, which exposes the needed internal state, but I found not yet a way to access it in my test case, since the injected BoxDao is a remote interface proxy (an cannot be cast to BoxDaoBean).
Is there a way to access the stateful session bean behind the remote interface BoxDao in the test case? Would not matter if solution is OpenEjb specific.
Update: We can't use EJB 3.1 specific solutions unfortunately, as we have several EJB 3.0 projects running. Using Proxy.getInvocationHandler(boxDao), I can get access to the OpenEjb container, via StatefulEjbObjectHandler. Is it possible to access the stateful bean this way?
You could try having BoxDaoBean also expose an #LocalBean interface. A single EJB can expose a near unlimited number of views from #WebService, #Local, #Remote, JAX-RS and more.
Just update your bean like so:
#Stateful
#LocalBean
public class BoxDaoBean implements BoxDao {
//...
}
Then add another field to your test:
#LocalClient
public class MyTestCase {
#EJB
private BoxDao boxDao;
#EJB
private BoxDaoBean boxDaoBean;
...
}

Adding a dependency to an EJB

I want to add a dependency to an EJB. How do I do this using Spring? The dependent object is a general service object. Based on code below I want to wire myDependency without having to use 'new'.
The EJB runs in weblogic.
#Stateless(mappedName = "MyBean")
public class MyBean implements MyBeanRemote, MyBeanLocal {
#EJB(name = "MyOtherBean")
private MyOtherBean myOtherBean;
private MyDependency myDependency;
...
}
This is well described in the Spring documentation:
For EJB 3 Session Beans and Message-Driven Beans, Spring provides a
convenient interceptor that resolves Spring 2.5's #Autowired
annotation in the EJB component class:
org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor.
This interceptor can be applied through an #Interceptors annotation in
the EJB component class, or through an interceptor-binding XML element
in the EJB deployment descriptor.
#Stateless
#Interceptors(SpringBeanAutowiringInterceptor.class)
public class MyFacadeEJB implements MyFacadeLocal {
// automatically injected with a matching Spring bean
#Autowired
private MyComponent myComp;
// for business method, delegate to POJO service impl.
public String myFacadeMethod(...) {
return myComp.myMethod(...);
}
...
}
Stateless EJBs and Spring beans, however, offer more or less the same possibilities. Mixing them together seems like unnecessary complexity.

Categories

Resources