TomCat chamando EJB do JBoss

eu jah havia tentado isso, mas por via das duvidas fiz de novo

deu o seguinte:

java.lang.ClassCastException: javax.naming.Reference cannot be cast to neg.AcaoRemota

precisa usar o narrow não tem como eu acho

Seu cliente JSE está rodando em qual container??? No jboss né?

meu cliente jse nao tah rodando em container nenhum

eu rodo ocmo qualquer aplicação jse, o jboss, glassfish e afins nem sabe q essa apkicação existe rsrs só respondem aos pedidos dela :slight_smile:

valeu

aff… vacilo meu, é verdade… são quase 3:00 da manã to quase dormindo aqui no pc…kkkk…

Mas a respeito do erro do classCast se vc der um F5 e debugar para ver o que acontece no narrow fica fácil de enteder… da uma olhada no que ele faz:

PortableRemoteObject.narrow(referencia, neg.AcaoRemota.class);
 public java.lang.Object narrow ( java.lang.Object narrowFrom, 
	java.lang.Class narrowTo) throws ClassCastException 
    {
        java.lang.Object result = null;

        if (narrowFrom == null)
            return null;

        if (narrowTo == null) 
            throw new NullPointerException("invalid argument");

        try { 
            if (narrowTo.isAssignableFrom(narrowFrom.getClass())) 
                return narrowFrom;

	    // Is narrowTo an interface that might be
	    // implemented by a servant running on iiop?
	    if (narrowTo.isInterface() && 
		narrowTo != java.io.Serializable.class &&
		narrowTo != java.io.Externalizable.class) {
	
		org.omg.CORBA.Object narrowObj 
		    = (org.omg.CORBA.Object) narrowFrom;                
		
		// Create an id from the narrowTo type...
		String id = RepositoryId.createForAnyType(narrowTo);
		
		if (narrowObj._is_a(id)) {
		    return Utility.loadStub(narrowObj,narrowTo);
		} else {
		    throw new ClassCastException( "Object is not of remote type " +
			narrowTo.getName() ) ;
		}
	    } else {
		throw new ClassCastException( "Class " + narrowTo.getName() + 
		    " is not a valid remote interface" ) ;
	    }
        } catch(Exception error) {
	    ClassCastException cce = new ClassCastException() ;
	    cce.initCause( error ) ;
	    throw cce ;
        }
    }

narrowFrom é o seu objeto referencia que neste caso é um NamingContext (aqui é onde esta o erro pois na verdade o que deveria estar aqui é o seu proxy stub e não o NamingContext ), narrowTo é o seu AcaoRemota…

Se estivesse tudo certo o método retornaria o narrowFrom no if da linha 13 mas como NamingContext não é um subtipo nem um tipo da sua AcaoRemota ele passa por este if e tenta dar um cast para org.omg.CORBA.Object na linha 22 dando o classCastException…

realmente, bem abservado,

eu fiz o debug da aplicação rodando no jboss e realmente ele entra no IF

mas pq no tomcat nao entra?, a versão da interface é a mesma :S

Então kara…como tinha te falado no primeiro post de alguma forma seu proxy stub não está sendo localizado…

Provavelmente no tomcat o nome que vc pesquisa na jndi é diferente da forma que vc faz no jboss ou na sua aplicação JSE…

É meio complicado mas vc vai ter que ir fazendo tentativas nessa linha abaixo para retornar um proxy stub e não um NamingContext

  referencia = jndiContexto.lookup(nome);

Na variável nome tente pelo nome totalmente qualificado(pacote, classe,método),ou pelo nome absoluto(java:comp/env/NomeDoSeuBean/remote) ou pelo nome do contexto + o nome do bean (NomeDoContextoDaSuaAplicaçãoEJB/NomeDoSeuBean/remote)… ou outras formas…

Cara, pode ser que esse não seja exatamente o problema aí, mas o narrow é totalmente inútil se você está usando somente EJB3.

Cara, pode ser que esse não seja exatamente o problema aí, mas o narrow é totalmente inútil se você está usando somente EJB3.[/quote]

é, estive vendo um artigo da sun e mostrou isso mesmo :S

mas no livro Enterprise JavaBeans 3.0 mostra usando assim, aí eu acabei fazendo dessa forma

Mas então, conseguiu fazer funcionar com o lookup direto?

Abraços.

cara
eu nao consegui ainda

tah muito triste a situação :S

só pra mim dar uma distraída eu tentei implantar o ejb no glassfish, pra ver se eu acessava do tomcat

affe … piorei a situaçao

ALGUEM POR FAVORRRR explica um negócio, diz a documentação que eu tenho q por no meu classpath um arquivo chamado appserv-rt.jar que se encontra na pasta lib do glassfish, mas, esse arquivo tem 3K e NAO TEM nenhuma classe dentro dele :S e manda tambem botar no classpath do cliente um arquivo chamado javaee.jar que tambem tem 3K e nenhuma classe.

o pior é que quando roda o cliente, ele reclama das classes que estariam nesses jars, mais porq raios que esses meus jars estao vazios? eu baixei hoje o glassfish, nem tah zuado as pastas :S

Pessoal,

Passei por um problema semelhante e descobri a solução. Talvez também se aplique neste caso. Este é código que uso para fazer o lookup e invocar um método no objeto remoto EJB 3.0 a partir de duas aplicações clientes distintas:

final Properties props = new Properties();
props.put("java.naming.factory.initial", "org.jboss.naming.NamingContextFactory");
props.put("java.naming.provider.url", "jnp://localhost:2099");
props.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");

final Context initial = new InitialContext(props);
final SismService service = (SismService) initial.lookup("my-name/remote-sgbds.SismService");
System.out.println(service.getStringLength("Angelo"));

A primeira aplicação é uma aplicação J2SE convencional onde tudo funciona perfeitamente. A segunda é uma aplicação que roda em um contexto meio enrolado de explicar, mas cuja a execução gerava a seguinte exceção:

O que estava acontecendo era o seguinte: o método lookup em determinado momento obtém um objeto do tipo javax.naming.Reference. Este objeto é uma referência para o objeto EJB remoto e contém, além do endereço para alcançar o objeto remoto, o nome de uma classe factory capaz de construir um proxy para conversar com o objeto remoto. Para instanciar um objeto factory adequado, o método lookup primeiramente carregará na máquina virtual a classe cujo nome foi obtido do Reference.

No meu caso, o nome da classe era org.jboss.ejb3.proxy.impl.objectfactory.session.stateless.StatelessSessionProxyObjectFactory (pode ser obtido inspecionando-se o objeto Reference na IDE). O método lookup não estava encontrando esta classe no classpath e ao invés de criar um proxy, simplesmente retornava o objeto Reference, causando a cast exception.

A carga desta classe factory é feita em tempo de execução, por reflexão. Ou seja, o código da aplicação compila perfeitamente, embora possam existir classes que não estão no seu classpath e serão necessárias mais tarde. Para garantir que as classes necessárias sejam encontradas, o arquivo jbossall-client.jar tem que estar no classpath das aplicações clientes.

Eu havia colocado este arquivo no classpath das duas aplicações cliente, mas uma delas insistia em continuar sem funcionar. A causa do problema é que no meu “ambiente estranho”, são utilizados dois class loaders distintos. Um responsável pela carga de classes “de sistema” (pacotes java, javax, etc) e outro por classes de propósito específico. Um deles tinha acesso as classes de jbossall-client.jar e o outro não. No caso do colega javando, que está tendo problemas com uma aplicação cliente rodando dentro do Tomcat, a causa do problema pode ser a mesma, pois o Tomcat também utiliza vários class loaders (http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html).

Minha hipótese para o problema do fórum: Talvez, o class loader do Tomcat que precisa enxergar as classes do jbossall-client.jar não esteja conseguindo. Provavelmente, o arquivo jbossall-client.jar está listado dentre as bibliotecas da aplicação web, mas não nas bibliotecas “gerais do container”. Quando o class loader da aplicação detecta a necessidade de instanciar javax.naming.InitialContext, delega a tarefa para o class loader geral (pois javax pode ser visto como um recurso de sistema). Mas este class loader geral não enxerga as bibliotecas do class loader filho e falha ao tentar instanciar a classe factory por reflexão.

Abraços,
Ângelo

P.S.: Outro detalhe: observe que o arquivo jbossall-client.jar contém apenas um diretório META-INF contendo um MANIFEST gigante, responsável por listar todas os demais jars do cliente jboss facilitando o trabalho de deploy em alguns casos. Apenas colocar este cara dentro do classpath de uma aplicação sem garantir que todas os demais jars referenciados estão acessíveis pode não ser suficiente!!!