我正在尝试编写一个简单的无状态sesssion bean,但是我在查找时给出了窄参考的问题。 我得到了
类强制转换
我用
eclipse IDE
我的bean类
package codes;
import java.rmi.RemoteException;
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
public class SinaBean implements SessionBean {
/**
*
*/
private static final long serialVersionUID = 1L;
public String getHello()
{
return "hello";
}
public void ejbCreate(){
}
@Override
public void ejbActivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
@Override
public void ejbPassivate() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
@Override
public void ejbRemove() throws EJBException, RemoteException {
// TODO Auto-generated method stub
}
@Override
public void setSessionContext(SessionContext arg0) throws EJBException,
RemoteException {
// TODO Auto-generated method stub
}
}
我的家庭界面
package codes;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface SinaHome extends EJBHome {
public SinaObject create() throws RemoteException,CreateException;
}
我的组件
package codes;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
public interface SinaObject extends EJBObject {
String getHello() throws RemoteException;
}
我的客户
package codes;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
Context con=null;
try {
Properties p=new Properties();
p.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
p.setProperty(Context.PROVIDER_URL, "localhost:1099");
p.setProperty(Context.URL_PKG_PREFIXES,
"org.jboss.namingrg.jnp.interfaces");
con = new InitialContext(p);
Object o=con.lookup("SinaBean");
System.out.println(o);/***/untill know it works.it sysout :
//org.jnp.interfaces.NamingContext@e83912***
@SuppressWarnings("unused")
SinaHome sh=(SinaHome)PortableRemoteObject.narrow(o, SinaHome.class);//***exeption is here!!***
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我的xml文件
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
<display-name>Ejb </display-name>
<enterprise-beans>
<session>
<display-name>SinaBean</display-name>
<ejb-name>SinaBean</ejb-name>
<home>codes.SinaHome</home>
<remote>codes.SinaObject</remote>
<ejb-class>codes.SinaBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
<security-identity>
<description></description>
<use-caller-identity></use-caller-identity>
</security-identity>
</session>
</enterprise-beans>
</ejb-jar>
我收到的例外
java.lang.ClassCastException
at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:229)
at javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:137)
at codes.Client.main(Client.java:27)
Caused by: java.lang.ClassCastException: org.jnp.interfaces.NamingContext cannot be cast to org.omg.CORBA.Object
at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:212)
... 2 more
我将非常感谢您的建议。
答案 0 :(得分:7)
首先,您的xml文件表明您正在使用EJB3(实际上这是唯一值得考虑的版本),但您的bean是EJB2 bean。
如果您的服务器确实运行EJB3,请删除XML文件并删除不必要的EJB主目录和组件实现。添加@Stateless
注释和远程接口。确保它看起来像这样:
@Remote
public interface SinaRemote {
String getHello();
}
@Stateless
public class SinaBean implements SinaRemote {
public String getHello() {
return "hello";
}
}
然后更正您的JNDI属性。以下是错误的:
p.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.namingrg.jnp.interfaces");
它应该是:
p.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
(人们在这里使用的变体几乎是无穷无尽的,无论如何它基本上总是有效,但只是为了确保使用正确的变体)
此外,很可能是主要罪魁祸首,你使用的是ejb-name
,如果它是一个全局JNDI名称,但事实并非如此。 ejb-name
是一个有点令人困惑的逻辑名称,当注入或创建ejb-ref时,它在引用特定bean时用作额外的限定符。
在您的情况下,您将其设置为与非限定bean名称相同,这已经是默认值。由于SinaBean
存在,我猜你没有通过EAR进行部署,而是部署一个独立的EJB jar,对吗?
如果您使用的是JBoss AS 6(EJB3.1),则可以使用global portable JNDI names,否则可以使用旧的JBoss特定JNDI命名:[ear name]/[simple bean name]/remote
。请注意,[简单bean名称]不是ejb-name,但在您的情况下,它们恰好相同。由于在您仅部署EJB jar时删除了[ear name]/
,这解释了您获得的异常:SinaBean
是一个目录(JNDI术语中的 context ),可以包含实际条目local
,remote
和no-interface
。你正在做的是尝试将这个中间目录节点转换为你的bean的代理,这当然不起作用。
无论如何,最后,删除PortableRemoteObject
的使用,这是no longer needed。客户端代码将如下所示:
Properties properties = new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
properties.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
properties.setProperty(Context.PROVIDER_URL, "localhost:1099");
context = new InitialContext(properties);
SinaRemote sina = (SinaRemote) context.lookup("SinaBean/remote");
答案 1 :(得分:0)
这里如果您正在使用EJB 2.0和Jboss 5.0并尝试从客户端键入强制转换对象obj到您的Home对象,那么它可能会抛出 java.lang.ClassCastException com.sun.proxy。$ Proxy104不能被强制转换为org.omg.CORBA.Object 。
查找JNDI的代码: java.lang.Object obj = ctx.lookup(&#34; java:comp / env / ATSessionBean&#34;); ATHome home =(ATHome)PortableRemoteObject.narrow(obj,ATHome.class);
解决方案:在这里你需要在客户端应用程序的类路径中添加更多版本的JBOSS。 最好下载最新版本** jboss-7.1.1.Final 服务器并部署您的应用程序,它将成功运行。 :)** 从以下链接下载JBOSS服务器(下载EAP 6.4.0):http://jbossas.jboss.org/downloads/