java - EJB 不是 "visible"给 EJB 管理器。不能使用 CDI 或 JNDI 来引用它

标签 java jakarta-ee annotations ejb jndi

当我试图创建一个新的 EJB 并将其注入(inject)另一个 EJB 以便我可以调用它的资源时,我突然遇到了一个奇怪的问题。我正在使用 Glassfish 3.1 和 Java EE 6。

我以前在同一个项目中做过几次,没有出现问题,但由于某种原因,这个 EJB 导致了部署错误。只要我添加注释

@EJB EJBname ejbname;

对于我想在其中引用它并保存的 bean,我收到部署服务器错误。

服务器日志显示:

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...

我不知道井号 # 的含义,也不知道我是否可以确认这是正确的语法。但是,看起来这是我的类所在的正确包。

我正在做的正是我为其他 EJB 所做的,它们都是简单的@stateless session bean。这似乎类似于未在构建路径中列出的引用库文件。好像它有名字但找不到实际位置。对于 EJB 注入(inject),我不确定如何解决这个问题。

编辑: 带有我需要的东西的 EJB: 包 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);

带有导致部署错误的注入(inject)的 EJB: 包 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;

一旦我添加上面的行“@EJB ThriftClient tclient”,它就不会部署并且我得到 NameException、JNDI 查找、映射空类型的异常。它拒绝以这种方式被发现。

最佳答案

我不确定您是否正确地使用了您的 ejbName。假设您有以下 bean:

@Stateless
public class MrBean implements MrBeanInterface {}

然后你需要注入(inject)带有@EJB注解的bean,如下所示:

@EJB
private MrBeanInterface mrBean;

注意类是MrBeanInterface,不是直接的MrBean。或者,如果您使用 CDI 并且对同一接口(interface)有 2 个实现,您也可以像这样注入(inject)一个 bean:

@Stateless
public class MrBean  implements BeanInterface {}

@Stateless
public class MrsBean implements BeanInterface {}

@Inject
@Exact(MrBean.class)
private BeanInterface mrBean;

更新 1:

这是来自 Oracle's tutorial :

  • Java EE 应用程序客户端通过以下方式引用企业 bean 实例 使用@EJB 注释来注释静态字段。注释的 静态字段代表企业bean的业务接口(interface), 当应用程序时,它将解析为 session bean 实例 客户端容器在运行时注入(inject)资源引用。

关于什么是EJB?什么时候使用EJB?EJB的好处?,可以引用这个article .

更新 2:

根据您的更新,您的@LocalBean 没有任何接口(interface)。这可能违反了 EJB 3.0 的规范。在这个Oracle's documentation ,他们提到:

  • 当使用 EJB 3.0 编程模型对 bean 进行编程时,您是 需要指定业务接口(interface)。

此外,在这个tutorial他们从 IBM 定义了一个 No-Interface Local SessionBean,如下所示:

  • 该 bean 不公开任何其他客户端 View (本地、远程、2.x 远程主页、2.x 本地主页、Web 服务)并且其实现子句为空。
  • 该 bean 公开至少一个其他客户端 View 。该 bean 指定它在 bean 类或部署描述符中使用 @LocalBean 注释公开无接口(interface) View 。

简而言之,我认为您仍然应该为您的 ThriefClient 指定一个接口(interface),即使您不需要使用它也是如此。

@Stateless
@LocalBean
public class ThriefClient implements ThriefInterface {
   // Your  functions
}

@Local
public interface ThriefInterface {
   // Empty interface
}

或者,在 EJB 3.1 中,您可以尝试这样做:

@Stateless
public class ThriefClient {
   // Your  functions
}

@Stateless
public class RSSbean {
    @EJB
    private ThriefClient thriefClient;
}

关于java - EJB 不是 "visible"给 EJB 管理器。不能使用 CDI 或 JNDI 来引用它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8663476/

相关文章:

jpa - 我应该使用 @NamedQuery 注释还是 addNamedQuery 方法?

ios - Mapview - 防止发现坐标为零

java - 将 Java XML 和持久性注释放在同一个 bean 上是否有效?

java - 在 twitter4j 的 ResponseList 上使用 .add() 方法?

java - 在 Java 中使用流的 byte[] 到 byte[] 的 ArrayList

java - 使用 spock 模拟返回链式方法

java - itext:PdfPCell 中的嵌套列表显示不完整

Spring Data JPA 之类的项目不依赖于 Spring

java - 并行事务如何产生OptimistickLockException?

java - 当我使用 Autowiring 和组件注释时,我的 spring bean 没有被注入(inject)或创建