class cast exception in narrow a jndi reffrence in ejb

孤人 提交于 2020-01-03 08:49:09

问题


I am trying to write a simple stateless sesssion bean but I have problem with narrow reference I give in lookup time. I got

class cast exeption

I use

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

my component

package codes;

import java.rmi.RemoteException;

import javax.ejb.EJBObject;

public interface SinaObject extends EJBObject {

    String getHello() throws RemoteException;
}

my client

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>

the exception I receive

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

I will be extremely grateful for your advices.


回答1:


First of all, your xml file indicates you are using EJB3 (which is actually the only version even worth considering), but your bean is an EJB2 bean.

If your server indeed runs EJB3, remove the XML file and remove the needless EJB home and component implementations. Add the @Stateless annotation and a remote interface. Make sure it looks something like this:

@Remote
public interface SinaRemote {
    String getHello();
}

@Stateless
public class SinaBean implements SinaRemote {

    public String getHello() {
        return "hello";
    }
}

Then correct your JNDI properties. The following is wrong:

p.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.namingrg.jnp.interfaces");

it should be:

p.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");

(the variants people use here are almost endless and it basically always works anyway, but just to be sure use the correct variant)

Furthermore, and most likely the main culprit, you're using the ejb-name as-if it was a global JNDI name but this is not the case. The ejb-name is a somewhat confusing logical name that's used as an extra kind of qualifier when referring to a specific bean when injecting or creating an ejb-ref.

In your case you're setting it to the same as the unqualified bean name, which is already the default. Since SinaBean exists, I'm guessing you're not deploying via an EAR, but deploy a standalone EJB jar, right?

If you are using JBoss AS 6 (EJB3.1) you can use the global portable JNDI names, otherwise the old JBoss specific JNDI naming can be used: [ear name]/[simple bean name]/remote. Note that [simple bean name] is not the ejb-name, but again in your case they happened to be the same. Since [ear name]/ is removed when you're deploying only an EJB jar, this explains the exception you're getting: SinaBean is a directory (context in JNDI terms), which can contain the actual entries local, remote and no-interface. What you're doing is trying to cast this intermediate directory node to the proxy to your bean, which of course doesn't work.

Anyway, finally, remove the usage of PortableRemoteObject, this is no longer needed. The client code will then look like this:

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



回答2:


Here If you are using EJB 2.0 along with Jboss 5.0 and trying to type cast Object obj to your Home Object from Client as below then it might throw java.lang.ClassCastException com.sun.proxy.$Proxy104 cannot be cast to org.omg.CORBA.Object .

Code to lookup JNDI : java.lang.Object obj = ctx.lookup("java:comp/env/ATSessionBean"); ATHome home = (ATHome) PortableRemoteObject.narrow(obj, ATHome.class);

Solution : Here u need to add additional jars in classpath of Client app those are available in Higher version of JBOSS. So better to download latest version **jboss-7.1.1.Final server and deploy your application and it will run successfully. :)** download JBOSS server (Download EAP 6.4.0) from below link : http://jbossas.jboss.org/downloads/



来源:https://stackoverflow.com/questions/6816996/class-cast-exception-in-narrow-a-jndi-reffrence-in-ejb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!