我遇到使用JNDI检索bean的问题。
我有两只耳朵:clientear和workerear。 Clientear包含clientejb和libejb Workerear包含workerejb和libejb
lib包含MyInterface workerejb包含bean和抽象类 clientejb包含执行查找的客户端代码。
我实现远程接口的bean
public class MyBean implements MyInterface
它的JNDI绑定是
java:global/jndinaming/MyBean!learning.jndinaming.MyInterface
没关系。
现在我希望它扩展一个Abstract类:
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");
我得到了一个Class Cast异常:
ClassCastException:无法将MyBean $$$ view68(id = 938)强制转换为 MyInterface的
接口文件位于客户和工作项目均可访问的项目中。
客户端项目包含调用查找方法的代码。
worker项目具有bean实现和抽象类。
项目位于单独的ear文件中,但位于同一个wildfly容器中。
为什么在抽象类中添加新的“图层”会导致此类强制转换异常?我该怎么做才能解决它?
顺便说一句: 尝试使用
进行访问 (MyInterface) ctx.lookup("java:global/jndinaming/MyBean!learning.jndinaming.MyInterface");
导致抛出nameNotFound异常的结果
编辑: 这是bean的当前状态,Abstract类和接口:
接口:
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 :(得分: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 :(得分: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/