在ejb中狭窄jndi引用中的类强制转换异常



我正在尝试编写一个简单的无状态会话bean,但我在查找时间中给出了狭窄的参考。我得到

类强制转换异常

我使用

eclipse IDE

my bean class

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

my home interface

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();
        }

    }
}

my XML file

<?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
我将非常感谢您的建议。

首先,您的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),您可以使用全局可移植JNDI名称,否则可以使用旧的JBoss特定JNDI命名:[ear name]/[simple bean name]/remote。请注意,[简单bean名称]不是ejb名称,但在您的情况下,它们恰好是相同的。由于在只部署EJB jar时删除了[ear name]/,这就解释了您得到的异常:SinaBean是一个目录(JNDI术语中的上下文),它可以包含实际条目localremoteno-interface。您所做的是尝试将这个中间目录节点转换为bean的代理,这当然不起作用。

无论如何,最后,删除PortableRemoteObject的使用,这不再需要。客户端代码看起来像这样:

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");

如果您正在使用EJB 2.0和Jboss 5.0,并试图从客户端类型强制转换Object obj到您的Home Object,那么它可能会抛出java.lang。ClassCastException com.sun.proxy。$Proxy104不能强制转换为org.omg.CORBA。对象 .

查找JNDI的代码:java.lang. object obj = ctx.lookup("java:comp/env/ATSessionBean");ATHome home = (ATHome) portableemoteobject。狭窄(obj ATHome.class);

解决方案:这里你需要在客户端应用程序的类路径中添加额外的jar,这些jar在更高版本的JBOSS中可用。所以最好下载最新版本**jboss-7.1.1。最终的服务器和部署您的应用程序,它将成功运行。:) * *下载JBOSS服务器(下载EAP 6.4.0)从下面链接:http://jbossas.jboss.org/downloads/

最新更新