2015-07-20 95 views
0

我在使用JNDI检索bean时遇到了问题。为什么我不能通过JNDI使用远程接口访问我的EJB?

我有2个耳朵:clientear和workerear。 Clientear包含clientejb和libejb Workerear包含workerejb和libejb

的LIB包含MyInterface的 的workerejb包含豆和抽象类 和clientejb包含执行查找客户端代码。

我Bean上实现远程接口

public class MyBean implements MyInterface 

其JNDI绑定

java:global/jndinaming/MyBean!learning.jndinaming.MyInterface 

这是确定的。

现在我想它来扩展一个抽象类:

public abstract class MyAbstractClass implements MyInterface 
public class MyBean extends MyAbstractClass 

所以JNDI绑定成为

java:global/jndinaming/MyBean!learning.jndinaming.MyBean 

这是确定的,我调整了字符串和我的代码是这样的:

(MyInterface) ctx.lookup("java:global/jndinaming/MyBean!learning.jndinaming.MyInterface"); 

成为这样:

(MyInterface) ctx.lookup("java:global/jndinaming/MyBean!learning.jndinaming.MyBean"); 

我也得到一个类转换异常:

ClassCastException异常:不能投为myBean $$$ view68(ID = 938),以 MyInterface的

接口文件是在一个项目,该项目可由客户和工人项目访问。

客户端项目包含调用查找方法的代码。

worker项目有bean实现和抽象类。

这些项目位于不同的耳朵文件中,但位于相同的野蝇容器中。

为什么添加新的“图层”与抽象类会导致此类抛出异常?我能做些什么来解决它?

BTW: 尝试使用在nameNotFound例外

(MyInterface) ctx.lookup("java:global/jndinaming/MyBean!learning.jndinaming.MyInterface"); 

结果访问被抛出

编辑: 这是豆,抽象类和接口的当前状态:

接口:

import javax.ejb.Remote; 

@Remote 
public interface MyInterface { 
    public void print(); 

} 

抽象类:

public abstract class MyAbstractClass implements MyInterface{ 

} 

为myBean

@Stateless 
public class MyBean extends MyAbstractClass{ 

    @Override 
    public void print() { 
     System.out.println("MyAbstractClassExtender.PRINT"); 

    } 

} 

客户机代码:

@Stateless 
public class TimedBean { 
    @Resource 
    private SessionContext    ctx; 

    @Schedule(second="*/10", minute="*", hour="*") 
    public void run() throws NamingException{ 
      MyInterface c2 = (MyInterface) ctx.lookup("java:global/workerear/workerejb-0.0.1-SNAPSHOT/MyAbstractClassExtender!learning.lib.MyInterface"); 
     c2.print(); 
    } 

} 
+0

请给你的每个类/接口上 – Phuthib

+0

当然,我会后整个代码在这里 – JSBach

回答

1

从接口卸下@Remote并将其添加到bean解决了这个问题:

public interface MyInterface { 
    public void print(); 

} 

@Stateless 
@Remote(MyInterface.class) 
public class MyBean extends MyAbstractClass{ 

    @Override 
    public void print() { 
     System.out.println("MyAbstractClassExtender.PRINT"); 

    } 

} 

然后JNDI绑定将是这一个:

java:global/workerear/workerejb-0.0.1-SNAPSHOT/MyBean!learning.lib.MyInterface 

而且演员阵容。

+1

花了一段时间来找回注释的简短描述或源,很高兴你得到它的工作。我猜测注解处理器可能会查看“实现”来确定远程/本地接口(即,如果@Remote在接口上而不在会话Bean中)。这是你提出的一个有趣的问题。 – Phuthib

0

注释处理器检查implements子句中的接口以确定远程/本地接口。因为这种情况下的接口是继承的,并且没有在implements子句中显式定义,所以注释处理器将假定容器的默认行为。

一个解决方案是一个工具添加到您的Bean:

@Stateless 
public class MyBean extends MyAbstractClass implements MyInterface{ 
    @Override 
    public void print() { 
     System.out.println("MyAbstractClassExtender.PRINT"); 

    } 
} 

另一个在你的答案表示将与申报的远程接口在bean来代替:

@Stateless 
@Remote(MyInterface.class) 
public class MyBean extends MyAbstractClass{ 

    @Override 
    public void print() { 
     System.out.println("MyAbstractClassExtender.PRINT"); 

    } 
} 

有对于其中一种方法来说,这将是优点和缺点。我发现这个博客很有意思http://piotrnowicki.com/2013/03/defining-ejb-3-1-views-local-remote-no-interface/