Acesso aos componentes EJB pelo módulo client (EJB 3.0)

25 respostas
L

Bom dia pessoal,

Preciso de ajuda para acessar um SessionBean pelo módulo client.

Seguinte estou pesquisando sobre EJB 3.0 para ser utilizado no desenvolvimento de um ERP em java obviamente. O mesmo deve possuir clients Swing e Web.

Estou utilizando
IDE: netBeans 5.5.
Banco de dados: PostgreSQL 8.1
AS: Application Server PE 9
EJB: 3.0

Bom, iniciei procurando desenvolver alguma aplicação de teste. Para isso, criei algumas tabelas no banco.

Iniciei o desenvolvimento dos meus EJB pelos Entity Bean:
Segue um exemplo do EntityBean para persistir dados na tabela PAIS.

******* EntityBean - Pais **********
import java.io.Serializable;
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

/**
 * Entity class Pais
 * 
 * @author Administrador
 */
@Entity
@Table(name = "pais")
@NamedQueries( {
        @NamedQuery(name = "Pais.findByIdPais", query = "SELECT p FROM Pais p WHERE p.idPais = :idPais"),
        @NamedQuery(name = "Pais.findByDescricao", query = "SELECT p FROM Pais p WHERE p.descricao = :descricao"),
        @NamedQuery(name = "Pais.findBySigla", query = "SELECT p FROM Pais p WHERE p.sigla = :sigla")
    })
public class Pais implements Serializable {

    @Id @GeneratedValue 
    @Column(name = "id_pais", nullable = false)
    private BigDecimal idPais;

    @Column(name = "descricao", nullable = false)
    private String descricao;

    @Column(name = "sigla", nullable = false)
    private String sigla;
    
    /** Creates a new instance of Pais */
    public Pais() {
    }

    /**
     * Creates a new instance of Pais with the specified values.
     * @param idPais the idPais of the Pais
     */
    public Pais(BigDecimal idPais) {
        this.idPais = idPais;
    }

    /**
     * Creates a new instance of Pais with the specified values.
     * @param idPais the idPais of the Pais
     * @param descricao the descricao of the Pais
     * @param sigla the sigla of the Pais
     */
    public Pais(BigDecimal idPais, String descricao, String sigla) {
        this.idPais = idPais;
        this.descricao = descricao;
        this.sigla = sigla;
    }

    /**
     * Gets the idPais of this Pais.
     * @return the idPais
     */
    public BigDecimal getIdPais() {
        return this.idPais;
    }

    /**
     * Sets the idPais of this Pais to the specified value.
     * @param idPais the new idPais
     */
    public void setIdPais(BigDecimal idPais) {
        this.idPais = idPais;
    }

    /**
     * Gets the descricao of this Pais.
     * @return the descricao
     */
    public String getDescricao() {
        return this.descricao;
    }

    /**
     * Sets the descricao of this Pais to the specified value.
     * @param descricao the new descricao
     */
    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    /**
     * Gets the sigla of this Pais.
     * @return the sigla
     */
    public String getSigla() {
        return this.sigla;
    }

    /**
     * Sets the sigla of this Pais to the specified value.
     * @param sigla the new sigla
     */
    public void setSigla(String sigla) {
        this.sigla = sigla;
    }

    /**
     * Returns a hash code value for the object.  This implementation computes 
     * a hash code value based on the id fields in this object.
     * @return a hash code value for this object.
     */
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (this.idPais != null ? this.idPais.hashCode() : 0);
        return hash;
    }

    /**
     * Determines whether another object is equal to this Pais.  The result is 
     * <code>true</code> if and only if the argument is not null and is a Pais object that 
     * has the same id field values as this object.
     * @param object the reference object with which to compare
     * @return <code>true</code> if this object is the same as the argument;
     * <code>false</code> otherwise.
     */
    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Pais)) {
            return false;
        }
        Pais other = (Pais)object;
        if (this.idPais != other.idPais && (this.idPais == null || !this.idPais.equals(other.idPais))) return false;
        return true;
    }

    /**
     * Returns a string representation of the object.  This implementation constructs 
     * that representation based on the id fields.
     * @return a string representation of the object.
     */
    @Override
    public String toString() {
        return "dev.com.destro.gerenciador.domain.Pais[idPais=" + idPais + "]";
    }
    
}
Em seguida criei o SessionBean - PaisFacade
import java.math.BigDecimal;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceContext;
import javax.swing.DefaultComboBoxModel;

/**
 *
 * @author Administrador
 */
@Stateless(mappedName="PaisFacade")
public class PaisFacade implements PaisFacadeLocal, PaisFacadeRemote {

    @PersistenceContext
    private EntityManager em;
    
    /** Creates a new instance of PaisFacade */
    public PaisFacade() {
    }

    public void create(Pais pais) {
        em.persist(pais);
    }

    public void edit(Pais pais) {
        em.merge(pais);
    }

    public void destroy(Pais pais) {
        em.merge(pais);
        em.remove(pais);
    }

    public Pais find(Object pk) {
        return (Pais) em.find(Pais.class, pk);
    }

    public List findAll() {
        return em.createQuery("select object(o) from Pais as o").getResultList();
    }

    public void insert(String descricao, String sigla) {
        Pais pais = new Pais();
        pais.setDescricao(descricao);
        pais.setSigla(sigla);
        create(pais);
    }

    public void update(BigDecimal id, String descricao, String sigla) {
        Pais pais = find(id);
        pais.setDescricao(descricao);
        pais.setSigla(sigla);
        edit(pais);
    }

    public void delete(BigDecimal id) {
        Pais pais = find(id);
        destroy(pais);
    }
    
}
Interface Remota - PaisFacadeRemote
import java.math.BigDecimal;
import java.util.List;
import javax.ejb.Remote;
import javax.swing.DefaultComboBoxModel;

/**
 *
 * @author Administrador
 */
@Remote
public interface PaisFacadeRemote {
    void create(Pais pais);

    void edit(Pais pais);

    void destroy(Pais pais);

    Pais find(Object pk);

    List findAll();
    
    void insert(String descricao, String sigla);
    
    void update(BigDecimal id, String descricao, String sigla);
    
    void delete(BigDecimal id);
    
}
Conteúdo do arquivo sun-ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 EJB 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_0-0.dtd">
<sun-ejb-jar>
  <enterprise-beans>
    <ejb>
      <ejb-name>PaisFacade</ejb-name>
      <jndi-name>PaisFacade</jndi-name>
    </ejb>
   </enterprise-beans>
</sun-ejb-jar>

Bom agora vou mostrar a classe do módulo cliente que tenta acessar o SessionBean.

import...
/**
 *
 * @author  Administrador
 */
public class PaisForm extends JDialog {
    @EJB
    private PaisFacadeRemote bean;
    /** Creates new form PaisForm */
    public PaisForm(Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        bean = lookupPaisFacade();
        atualizar();
    }
    
    //... outros métodos, muitos deles utilizam o objeto bean

    private PaisFacadeRemote lookupPaisFacade() {
        try {
            Context c = new InitialContext();
            return (PaisFacadeRemote) c.lookup("PaisFacade");
        }
        catch(NamingException ne) {
            JOptionPane.showMessageDialog(this, ne.getExplanation());
            Logger.getLogger(getClass().getName()).log(Level.SEVERE,"exception caught" ,ne);
            throw new RuntimeException(ne);
        }
    }
}

Bom, acontece que sempre que eu tento chamar algum método que utilize algum método do objeto bean (ex. bean.findAll()) é gerada a seguinte exception:

Exception in thread "AWT-EventQueue-0" javax.ejb.EJBException: nested exception is: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
        java.rmi.RemoteException
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
        java.rmi.RemoteException
        at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.mapSystemException(Util.java:188)
        at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:172)
        at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:119)
        at com.sun.corba.ee.impl.presentation.rmi.bcel.BCELStubBase.invoke(BCELStubBase.java:197)
        at dev.com.destro.gerenciador.domain.__PaisFacadeRemote_Remote_DynamicStub.getAll(__PaisFacadeRemote_Remote_DynamicStub.java)
        at dev.com.destro.gerenciador.domain._PaisFacadeRemote_Wrapper.getAll(dev.com.destro.gerenciador.domain._PaisFacadeRemote_Wrapper.java)
.
.
.
etc.

Se alguém puder me ajudar ficarei muito grato.

Atenciosamente,
Leandro Nimet

25 Respostas

R

Beleza, Inimet?

Se você está usando EJB 3.0, não precisa fazer lookup, nem mexer nos descriptors, como o sun-ejb-jar.xml. O App Server (baseado no Glassfish) define valores JNDI padrão, baseado no nome qualificado da classe e injeta uma instância do EJB na classe cliente, através da DI (Injeção de Dependência). Daí você também não precisaria usar o atributo mappedName para @Stateless.

É claro que você decide a forma de implementar. Só estou dizendo isso porque, fazendo da forma padrão e mais simples, é mais difícil dar erro no programa. Enfim…

O problema não é o método destroy, mas do jeito que está, ele também lançará uma excessão quando o seu cliente fizer uso dele. Ao invés de

public void destroy(Pais pais) { em.merge(pais); em.remove(pais); }
use:

public void destroy(Pais pais) { em.remove(em.merge(pais)); }

Outra coisa: o stack trace da exception que o Glassfish lança não é de muita ajuda. Use o log para melhor identificar o problema.

Segue um link com uma série de erros comuns e possíveis soluções ao implementar EJB 3 no Glassfish: http://horstmann.com/elvis/hated-error-messages.html
Não por acaso, a página foi nomeada como Hated Errors Messages in Glassfish.

R

1-Usa o glassfish que é mais “atualizado” com a especificação
2-Vc não precisa fazer o lookup se tiver usando o módulo swing como app-client. Ou seja, vc tem que usar pelo link com jws.
3-Até agora eu só consegui fazer funcionar se eu colocar o @EJB no main do cliente.
4-Mas nada impede que vc use o lookup. Pelo menos no Jboss eu usei e funcionou.

R

Outra coisa, como vc está usando o netbeans, vc tem que executar a aplicação enterprise e não somente o app-client. O netbeans vai fazer o deploy do ear e não somente do ejb e do cliente separados.

L

E ae blz Rodrigo

Rodrigo.Lima:
1-Usa o glassfish que é mais “atualizado” com a especificação
2-Vc não precisa fazer o lookup se tiver usando o módulo swing como app-client. Ou seja, vc tem que usar pelo link com jws.
3-Até agora eu só consegui fazer funcionar se eu colocar o @EJB no main do cliente.
4-Mas nada impede que vc use o lookup. Pelo menos no Jboss eu usei e funcionou.

O servidor de aplicação que estou utilizando é baseado no glassfish.
Naum entendi direito o que vc quis dizer no ponto 2. Poderia me explicar melhor?

Att,

Leandro Nimet

L

Ae pessoal,

Ainda não consegui resolver o problema.

Estou tentando chamar um EJB agora a partir de uma nova classe Main.class
Soh lembrando q essa classe estah no módulo client.

public class Main {

@EJB
private static PaisFacadeRemote paisFacade;

/** Creates a new instance of Main */
public Main() {
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    Pais pais = new Pais();
    pais.setDescricao("Canadá");
    pais.setSigla("CAN");
    paisFacade.create(pais);
}

}

A Exception que eh gerada agora:

com.sun.enterprise.InjectionException: Exception attempting to inject Resolved Ejb-Ref aplicacaoteste.Main/paisFacade@jndi: ejb.PaisFacadeRemote - > PaisFacade into class aplicacaoteste.Main

at com.sun.enterprise.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:373)

at com.sun.enterprise.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:193)

at com.sun.enterprise.util.InjectionManagerImpl.injectClass(InjectionManagerImpl.java:131)

at com.sun.enterprise.util.InjectionManagerImpl.injectClass(InjectionManagerImpl.java:123)

at com.sun.enterprise.appclient.MainWithModuleSupport.(MainWithModuleSupport.java:325)

at com.sun.enterprise.appclient.Main.main(Main.java:180)

Caused by: javax.naming.NameNotFoundException: ejb.PaisFacadeRemote#ejb.PaisFacadeRemote not found

at com.sun.enterprise.naming.TransientContext.doLookup(TransientContext.java:203)

at com.sun.enterprise.naming.TransientContext.lookup(TransientContext.java:175)

at com.sun.enterprise.naming.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:61)

at com.sun.enterprise.naming.RemoteSerialContextProviderImpl.lookup(RemoteSerialContextProviderImpl.java:116)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:585)

at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:121)

at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:650)

at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:193)

at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1705)

at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1565)

at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:947)

at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:178)

at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:717)

at com.sun.corba.ee.impl.transport.SocketOrChannelConnectionImpl.dispatch(SocketOrChannelConnectionImpl.java:473)

at com.sun.corba.ee.impl.transport.SocketOrChannelConnectionImpl.doWork(SocketOrChannelConnectionImpl.java:1270)

at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:479)

Exception in thread main java.lang.RuntimeException: com.sun.enterprise.InjectionException: Exception attempting to inject Resolved Ejb-Ref aplicacaoteste.Main/paisFacade@jndi: ejb.PaisFacadeRemote - > PaisFacade into class aplicacaoteste.Main

at com.sun.enterprise.appclient.MainWithModuleSupport.(MainWithModuleSupport.java:364)

at com.sun.enterprise.appclient.Main.main(Main.java:180)

Caused by: com.sun.enterprise.InjectionException: Exception attempting to inject Resolved Ejb-Ref aplicacaoteste.Main/paisFacade@jndi: ejb.PaisFacadeRemote - > PaisFacade into class aplicacaoteste.Main

at com.sun.enterprise.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:373)

at com.sun.enterprise.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:193)

at com.sun.enterprise.util.InjectionManagerImpl.injectClass(InjectionManagerImpl.java:131)

at com.sun.enterprise.util.InjectionManagerImpl.injectClass(InjectionManagerImpl.java:123)

at com.sun.enterprise.appclient.MainWithModuleSupport.(MainWithModuleSupport.java:325)

 1 more

Caused by: javax.naming.NameNotFoundException: ejb.PaisFacadeRemote#ejb.PaisFacadeRemote not found

at com.sun.enterprise.naming.TransientContext.doLookup(TransientContext.java:203)

at com.sun.enterprise.naming.TransientContext.lookup(TransientContext.java:175)

at com.sun.enterprise.naming.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:61)

at com.sun.enterprise.naming.RemoteSerialContextProviderImpl.lookup(RemoteSerialContextProviderImpl.java:116)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:585)

at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:121)

at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:650)

at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:193)

at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1705)

at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1565)

at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:947)

at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:178)

at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:717)

at com.sun.corba.ee.impl.transport.SocketOrChannelConnectionImpl.dispatch(SocketOrChannelConnectionImpl.java:473)

at com.sun.corba.ee.impl.transport.SocketOrChannelConnectionImpl.doWork(SocketOrChannelConnectionImpl.java:1270)

at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:479)

Puts será que falta ajustar alguma configuração do servidor de aplicacoes q estou utilizando?

Se alguém tiver uma idéia do q possa ser…

Att,

Leandro Nimet

F

Leandro, parece que falta escrever o jndi.properties na aplicação cliente, dizendo o endereço do servidor jndi.

Infelizmente não tô com nenhum exemplo dele aqui agora, tenta o google…

L

Opa,

Fabio Kung:
Leandro, parece que falta escrever o jndi.properties na aplicação cliente, dizendo o endereço do servidor jndi.

Infelizmente não tô com nenhum exemplo dele aqui agora, tenta o google…

Tipow, quando puder posta aí o arquivo jndi.properties de exmplo.

R

lnimet:

com.sun.enterprise.InjectionException: Exception attempting to inject Resolved Ejb-Ref aplicacaoteste.Main/paisFacade@jndi: ejb.PaisFacadeRemote - > PaisFacade into class aplicacaoteste.Main

Caused by: javax.naming.NameNotFoundException: ejb.PaisFacadeRemote#ejb.PaisFacadeRemote not found

O Application Container está rodando, pois, caso contrário, nem haveria como tentar resolver o EJB por DI.

Quanto a esse tal de jndi.properties, nunca usei, não vi, nem senti falta dele. Fiquei curioso, pode mandar um exemplo? É mesmo necessário para EJB 3.0? Pergunto porque o tutorial da Sun não faz menção a ele.

O que parece daqui, é que sua classe Main, no cliente, está tentando encontrar PaisFacade pelo JNDI padrão, enquanto no servidor, o JNDI foi redefinido para PaisFacade. Ou seja, nomes diferentes.

Eu não costumo redefinir o JNDI, está dando certo por aqui. Comecei seguindo o tutorial da Sun. Tem alguns exemplos muito bons. Dá uma pesquisada nele.

F

e quando você quer acessar seu ejb remotamente? De outra máquina, numa aplicação stand-alone rodando fora do seu servidor de aplicações?

É para isso que serve o jndi.properties. Alguém tem que dizer o endereço do servidor jndi (que geralmente também é o servidor de ejbs).

R

Fabio Kung:
e quando você quer acessar seu ejb remotamente? De outra máquina, numa aplicação stand-alone rodando fora do seu servidor de aplicações?

Os procedimentos que utilizo são os seguintes:

Se executar o cliente na mesma máquina em que está o servidor Glassfish, utilizo o comando appclient -client <AplicacaoCliente.jar>.

Se o cliente estiver em outra máquina, acessando o servidor pela NET, e essa máquina não tiver o Glassfish/AppServer, é possível obter o Client Container através do comando package-appclient . Daí, é só extrair o conteúdo do appclient.jar e configurar alguns arquivos, entre esses, sun-acc.xml.

Links sobre o assunto que achei interessantes:
http://blogs.sun.com/pblaha/entry/ejb_3_0_client_in
http://docs.sun.com/source/817-6092/hman1m/appclient.1m.html
http://docs.sun.com/source/817-6092/hman1m/package-appclient.1m.html
http://docs.sun.com/app/docs/coll/134.4

I

Leandro,
um pouco off, mas no seu código tem:
BigDecimal idPais??? :shock:

BigDecimal é uma das coisas mais leeentas que tem, e a menos que existam infinitos idPais no seu programa(o que eu duvido), deve ser evitado a todo custo o seu uso.Use apenas para cálculos científicos ou aplicações financeiras que exijam precisão.

R

lnimet:
E ae blz Rodrigo

Rodrigo.Lima:
1-Usa o glassfish que é mais “atualizado” com a especificação
2-Vc não precisa fazer o lookup se tiver usando o módulo swing como app-client. Ou seja, vc tem que usar pelo link com jws.
3-Até agora eu só consegui fazer funcionar se eu colocar o @EJB no main do cliente.
4-Mas nada impede que vc use o lookup. Pelo menos no Jboss eu usei e funcionou.

O servidor de aplicação que estou utilizando é baseado no glassfish.
Naum entendi direito o que vc quis dizer no ponto 2. Poderia me explicar melhor?

Att,

Leandro Nimet

Blz,
É isso mesmo, vc não precisa fazer lookup, esqueça lookup. O glassfish implementa a especificação, sua aplicação vai ser chamada usando java web start. Se vc for no admin do glassfish e clicar na sua aplicação vai ver que o módulo app-cliente tem uma opção de launch, vc tem que chamar a sua aplicação por ali. Note que no jboss isso não existe pq ele não é um container. mas nada te impede de usar o lookup.

Posso estar enganado tb.

R

Fabio Kung:
e quando você quer acessar seu ejb remotamente? De outra máquina, numa aplicação stand-alone rodando fora do seu servidor de aplicações?

É para isso que serve o jndi.properties. Alguém tem que dizer o endereço do servidor jndi (que geralmente também é o servidor de ejbs).


Fábio, fiquei cismado com esse jndi.properties e fui atrás dele. Acabei encontrando a resposta na Mundo Java n° 20, no artigo que fala sobre EJB 3.0.

Esse arquivo é necessário para o lookup quando se utiliza o JBoss. Por isso eu nem conhecia, já que utilizo o Glassfish.

No caso do nosso colega, que também usa o Glassfish (ou App Server), ele também não precisará do arquivo jndi.properties.

F

Bom saber.

Pra mim já que jndi é uma especificação deveria ser independente de app server.

Talvez funcione também com o glassfish. Ele só tem um jeito alternativo de fazer isso.

L

E ae Rafael,

RafaelRio:
Fabio Kung:
e quando você quer acessar seu ejb remotamente? De outra máquina, numa aplicação stand-alone rodando fora do seu servidor de aplicações?

É para isso que serve o jndi.properties. Alguém tem que dizer o endereço do servidor jndi (que geralmente também é o servidor de ejbs).


Fábio, fiquei cismado com esse jndi.properties e fui atrás dele. Acabei encontrando a resposta na Mundo Java n° 20, no artigo que fala sobre EJB 3.0.

Esse arquivo é necessário para o lookup quando se utiliza o JBoss. Por isso eu nem conhecia, já que utilizo o Glassfish.

No caso do nosso colega, que também usa o Glassfish (ou App Server), ele também não precisará do arquivo jndi.properties.

Explicando melhor o teste q estou fazendo…

Pelo NetBeans acesso New Project --&gt Enterprise Application
São então criados os seguintes módulos:

  • NomeDaAplicacao
  • NomeDaAplicacao-app-client
  • NomeDaAplicacao-ejb
  • NomeDaAplicacao-war

Todos os SessionBeans e EntityBeans sao criados no módulo NomeDaAplicacao-app-client dentro de Source Packages.

As telas nas quais estou tentando chamar os EJB se encontram no módulo NomeDaAplicacao-ejb dentro de Source packages

Essa é a mesma estrutura que vc utiliza?

Posta aí algum trecho de código pra exemplificar a estrutura q vc utiliza!!!

Att,

Leandro Nimet

R

lnimet:
E ae Rafael,

RafaelRio:
Fabio Kung:
e quando você quer acessar seu ejb remotamente? De outra máquina, numa aplicação stand-alone rodando fora do seu servidor de aplicações?

É para isso que serve o jndi.properties. Alguém tem que dizer o endereço do servidor jndi (que geralmente também é o servidor de ejbs).


Fábio, fiquei cismado com esse jndi.properties e fui atrás dele. Acabei encontrando a resposta na Mundo Java n° 20, no artigo que fala sobre EJB 3.0.

Esse arquivo é necessário para o lookup quando se utiliza o JBoss. Por isso eu nem conhecia, já que utilizo o Glassfish.

No caso do nosso colega, que também usa o Glassfish (ou App Server), ele também não precisará do arquivo jndi.properties.

Explicando melhor o teste q estou fazendo…

Pelo NetBeans acesso New Project --&gt Enterprise Application
São então criados os seguintes módulos:

  • NomeDaAplicacao
  • NomeDaAplicacao-app-client
  • NomeDaAplicacao-ejb
  • NomeDaAplicacao-war

Todos os SessionBeans e EntityBeans sao criados no módulo NomeDaAplicacao-app-client dentro de Source Packages.

As telas nas quais estou tentando chamar os EJB se encontram no módulo NomeDaAplicacao-ejb dentro de Source packages

Essa é a mesma estrutura que vc utiliza?

Posta aí algum trecho de código pra exemplificar a estrutura q vc utiliza!!!

Att,

Leandro Nimet

Cara, vc trocou tudo, nunca ia funcionar assim.

Seguinte:
Os seus SessionBeans e EntityBeans, regras de negócio, tudo deve ficar no seu NomeDaAplicacao-ejb. Já no NomeDaAplicacao-app-client vão ficar as telas que usam as regras do ejb. O nome já diz tudo, app-client, fica no cliente. Qual o motivo de ter criado uma aplicação web tb?

L

Rodrigo.Lima:
lnimet:
E ae Rafael,

RafaelRio:
Fabio Kung:
e quando você quer acessar seu ejb remotamente? De outra máquina, numa aplicação stand-alone rodando fora do seu servidor de aplicações?

É para isso que serve o jndi.properties. Alguém tem que dizer o endereço do servidor jndi (que geralmente também é o servidor de ejbs).


Fábio, fiquei cismado com esse jndi.properties e fui atrás dele. Acabei encontrando a resposta na Mundo Java n° 20, no artigo que fala sobre EJB 3.0.

Esse arquivo é necessário para o lookup quando se utiliza o JBoss. Por isso eu nem conhecia, já que utilizo o Glassfish.

No caso do nosso colega, que também usa o Glassfish (ou App Server), ele também não precisará do arquivo jndi.properties.

Explicando melhor o teste q estou fazendo…

Pelo NetBeans acesso New Project --&gt Enterprise Application
São então criados os seguintes módulos:

  • NomeDaAplicacao
  • NomeDaAplicacao-app-client
  • NomeDaAplicacao-ejb
  • NomeDaAplicacao-war

Todos os SessionBeans e EntityBeans sao criados no módulo NomeDaAplicacao-app-client dentro de Source Packages.

As telas nas quais estou tentando chamar os EJB se encontram no módulo NomeDaAplicacao-ejb dentro de Source packages

Essa é a mesma estrutura que vc utiliza?

Posta aí algum trecho de código pra exemplificar a estrutura q vc utiliza!!!

Att,

Leandro Nimet

Cara, vc trocou tudo, nunca ia funcionar assim.

Seguinte:
Os seus SessionBeans e EntityBeans, regras de negócio, tudo deve ficar no seu NomeDaAplicacao-ejb. Já no NomeDaAplicacao-app-client vão ficar as telas que usam as regras do ejb. O nome já diz tudo, app-client, fica no cliente. Qual o motivo de ter criado uma aplicação web tb?

Ow foi mals, na verdade eu distraído acabei digitando errado na hora que estah criando o post, ou seja, na aplicacao estah assim:
Telas e interfaces no módulo client, Entity Beans e SessionsBeans no módulo ejb.

Baixei os fontes de algums exemplos do tutorial JavaEE da sun.
Em um desse exemplos, de uma aplicação bancária, pude observar o mecanismo implementado para buscar os EJB. Tratava-se de uma classe EJBGetter que tinha vários métodos estáticos para buscar o ejb apropriado através de lookup.

Implementei tal classe na esperança de resolver o meu problema, mas continua gerando a mensagem de erro: NameNotFoundException.

Eu não vou desistir, continuo buscando uma solução pra isso, se alguém ver alguma luz no fim do túnel grita aí.

G

Para acessar o Glassfish use essas propriedades no JNDI

Properties props = new Properties(); props.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory"); props.setProperty("java.naming.factory.url.pkgs", "com.sun.enterprise.naming"); props.setProperty("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");

[]s

C

Guerr@:
Para acessar o Glassfish use essas propriedades no JNDI

Properties props = new Properties(); props.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory"); props.setProperty("java.naming.factory.url.pkgs", "com.sun.enterprise.naming"); props.setProperty("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");

[]s

Guerr@,

Então … Estou tendo dificuldade para conectar em um cliente standalone. Uso essas propriedades do JNDI.

Hashtable env = new Hashtable();
            env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.SerialInitContextFactory");
            env.put(Context.STATE_FACTORIES, "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
            env.put(Context.URL_PKG_PREFIXES, "com.sun.enterprise.naming");
            env.put(Context.PROVIDER_URL, "192.168.1.3");
            this.ctx = new InitialContext(env);
            ContatoFacadeRemote contatoFacade = (ContatoFacadeRemote)this.ctx.lookup("ContatoFacade");

Entretanto a exceção abaixo é retornada.

Veja que a parte destacada em negrito… está tentando conectar em localhost, mas deveria estar conectando em 192.168.1.3.

Alguém sabe me dizer o porque disso?

Obrigado,
Cleiton

M

cara… seta esses caras no teu properties…

// optional.  Defaults to localhost.  Only needed if web server is running 
    // on a different host than the appserver    
    props.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");

    // optional.  Defaults to 3700.  Only needed if target orb port is not 3700.
    props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");

comigo funciona dessa forma…

falow…

L

Só para complementar aqui.

https://glassfish.dev.java.net/javaee5/ejb/EJB_FAQ.html

t+
abração

M

marllonSimoes:
cara… seta esses caras no teu properties…

// optional.  Defaults to localhost.  Only needed if web server is running 
    // on a different host than the appserver    
    props.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");

    // optional.  Defaults to 3700.  Only needed if target orb port is not 3700.
    props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");

comigo funciona dessa forma…

falow…

Desculpem ressuscitar esse tópico, mas isso é essencial na minha solução.
Esse código tá conectando uma aplicação Swing com um EJB. Me lembro de ter feito um exemplo local de EJB onde depois de ter construído o projeto, pega-se um arquivo-ejb.jar e colocava junto com as bibliotecas da aplicação Swing. Agora para acessar um EJB remotamente, configurando o Properties isso passa a ser desnecessário?

T

O acesso a um metodo Main nao tem o @EJB. Da uma olhada no topico

http://www.guj.com.br/posts/list/113853.java

eu postei e ja esta resolvido. Se nao entender da um toque…

O codigo ficou assim:

public static void main(String[] args) {
    
            Properties props = new Properties();
            props.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory");
            props.setProperty("java.naming.factory.url.pkgs", "com.sun.enterprise.naming");
            props.setProperty("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
            props.put(Context.PROVIDER_URL, "iiop://localhost:2809");
            Context ctx = new InitialContext(props);
            SessionBeanRemote remote = (SessionBeanRemote) ctx.lookup(SessionBeanRemote.class.getName());
M

E quanto ao arquivo-ejb.jar, não precisa adicioná-lo nas bibliotecas do aplicativo desktop?

R

E quanto ao arquivo-ejb.jar, não precisa adicioná-lo nas bibliotecas do aplicativo desktop?Sim

Criado 29 de novembro de 2006
Ultima resposta 2 de jan. de 2009
Respostas 25
Participantes 11