I have a weird problem that suddenly sprung up when I was trying to create a new EJB and inject it into another EJB so I could call its resources. I'm using Glassfish 3.1, and Java EE 6.
I've done this a couple of times before without problems in the same project, but for some reason this EJB causes deployment errors. As soon as I add the annotation
@EJB EJBname ejbname;
To the bean I want to reference it in and save I get a deployment server error.
server logs reveals:
Caused by: javax.naming.NameNotFoundException: com.bob.thrift.ThriftClient#com.bob.thrift.ThriftClient not found
javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=com.bob.logic.RSSbean/tclient,Remote 3.x interface =com.bob.thrift.ThriftClient,ejb-link=null,lookup=,mappedName=,jndi-name=com.bob.thrift.ThriftClient,refType=Session' . Actual (possibly internal) Remote JNDI name used for lookup is 'com.bob.thrift.ThriftClient#com.bob.thrift.ThriftClient' [Root exception is javax.naming.NamingException: Lookup failed for...
I don't know what that hash symbol # means or if I can confirm that that is the correct syntax. It looks like that is the correct package where my class exists, however.
I'm doing exactly what I did for the other EJBs they're all simple @stateless session beans. This seems to be analogous to a referenced library file not being listed in the buildpath. As if it has the name but it can't find the actual location. I'm not sure how to resolve this in the case of EJB injection.
Edit: The EJB with the stuff I need: package com.bob.thrift;
import com.bob.thrift.sendEventMessage2;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransportException;
import javax.annotation.ManagedBean;
import javax.ejb.Remote;
import javax.ejb.Local;
import javax.ejb.LocalBean;
import javax.ejb.Singleton;
import javax.ejb.Stateless;
@Stateless
@LocalBean
public class ThriftClient {
public ThriftClient(){}
public String sendToServer(String say){
System.out.println("Entering ThriftClient's main method starting server connection...");
String msg;
//**Make Socket**
TSocket socket = new TSocket("137.222.23.23",1111);
//**Make Buffer**
//TSocket bufferedSocket = (socket); skipping this step because the jvm already handles
//the buffering on this end.
//**put in protocol**
TBinaryProtocol protocol = new TBinaryProtocol(socket);
//**create client to use protocol encoder**
sendEventMessage2.Client client = new sendEventMessage2.Client(protocol);
The EJB with the injection that causes deployment errors: package com.bob.logic;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.bob.eao.XRSSeao;
import com.bob.thrift.ThriftClient;
@Stateless
@LocalBean
//@WebService
public class RSSbean {
private String inputString;
private List Statuses;
@EJB private ThriftClient tclient;
As soon as I add the above line "@EJB ThriftClient tclient" it will not deploy and I get NameException, JNDI lookup, mapping null type of exceptions. It refuses to be found this way.
I'm not sure if you did it correctly with your ejbName
. Suppose you have the following bean:
@Stateless
public class MrBean implements MrBeanInterface {}
Then you need to inject the bean with @EJB
annotation as following:
@EJB
private MrBeanInterface mrBean;
Notice that the class is MrBeanInterface
, not MrBean
directly. Alternatively, if you use CDI and you have 2 implementation for the same interface, you can also inject a bean like this:
@Stateless
public class MrBean implements BeanInterface {}
@Stateless
public class MrsBean implements BeanInterface {}
@Inject
@Exact(MrBean.class)
private BeanInterface mrBean;
UPDATE 1:
This is from Oracle's tutorial:
Regarding What is EJB?
, When to use EJB?
and Benefits of EJB?
, you can refer to this article.
UPDATE 2:
According to your update, your @LocalBean
does not have any interfaces. This might have violated EJB 3.0's specs. In this Oracle's documentation, they mentioned:
Besides, in this tutorial from IBM, they defined a No-Interface Local SessionBean as following:
In brief, I think you should still specify an interface for your ThriefClient
even if you don't need to use it.
@Stateless
@LocalBean
public class ThriefClient implements ThriefInterface {
// Your functions
}
@Local
public interface ThriefInterface {
// Empty interface
}
Alternatively, in EJB 3.1, you can try this:
@Stateless
public class ThriefClient {
// Your functions
}
@Stateless
public class RSSbean {
@EJB
private ThriefClient thriefClient;
}