Problemas com EJB3 + JPA

Olá pessoal. Antes de mais nada agradeço pelo tempo dedicado por ler este post.
Estou concluindo um trabalho e estou com um probleminha no mesmo.
Tenho uma aplicação corporativa no Netbeans 6.7. No modulo EJB tenho minha camada de negocio com um Bean que é um facade:

@Stateless
public class BdFactory_Bean implements BdFactory_Remote {

    public BdListener getBD(int type) {
        BdListener bd = null;
        switch (type) {
          ...
        }
        return bd;
    }
}

Ele acessa uma camada de DAOs q realiza a persistência do que preciso. Essa aplicação tem uma parte WEB e uma parte Desktop.
Eu executo ela numa boa na WEB, ela realiza conexão com o banco tranqüilo.
Já na parte DeskTop, quando eu executo ela no NetBeans ela roda numa boa também. Porem quando tento executa-la pelo JWS (dentro do contêiner) ela da No Persistence Provider.
Tentei usar DI para o EntityManager sem sucesso:

@Stateless
public class BdFactory_Bean implements BdFactory_Remote {

    @PersistenceContext(unitName = "PU")
    private EntityManager em;

    public BdListener getBD(int type) {
        ConectionFactory.setEm(em);
        BdListener bd = null;
        switch (type) {
          ...
        }
        return bd;
    }
}

Uso o servidor GlassFish 2.1.
Alguem passou por essa dificuldade? Podem me dar umas dicas? :wink:

Não entendi muito bem. Você não consegue fazer o lookup no desktop, do EJB que recebe o EntityManager? Se for isso, coloca o teu código que faz lookup no desktop (InitialContext, lookup etc etc).

Bom, só para avisar, você não consegue injetar o PersistenceContext em uma classe comum desktop… Ok?

Olá.
Antes de mais nada obrigado por responder meu tópico Luciano.
Bom, meu lookup esta assim:

public class BdFactory {

    @EJB
    private static BdFactory_Remote remote;

    public static BdListener getBD(int type) {
        if (remote == null) {
            remote = new BdFactory_Bean();
        }
        return remote.getBD(type);
    }
}

Tanto o projeto WEB como o projeto DeskTop realizam o mesmo lookup. O projeto WEB com sucesso. E o projeto DeskTop quando executo no netbeans ele roda numa boa.
O problema e quando tento executa-lo pelo contêiner. Ele da o erro de No persistence provider. Eçe localiza o EJB, porem não o persistence provider.
O que eu acho que acontece é p seguinte:
Como o Persistence usa um JNDI o netbeans faz alguma coisa que faz com que ele funcione, algo que eu precisaria realizar no servidor GlassFish para liberar esse JNDI para acesso remoto.
Qnd uso o JDBC ao invez do JPA ele funciona numa boa. Porém como é um projeto acadêmico, necessito que seja JPA.

Obrigdo.

Bom, se o entity manager é utilizado sem problemas quando você usa a web como view, ele também deve funcionar quando usar desktop como view (a configuração de JNDI fica no teu persistence.xml, certo?). O que me parece ser problema é a injeção de dependência. Como eu disse, no desktop não funciona. Você tem que obter o EJB através de um lookup com InitialContext e não com injeção, como na tua classe BdFactory. Ex:

Hashtable props = new Hashtable(); props.put( InitialContext.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory" ); props.put( InitialContext.PROVIDER_URL, "jnp://" + [ip internet]:1099 ); InitialContext context = new InitialContext(props); AnotherBean ejb = (AnotherBean) context .lookup("java:comp/env/ejbname");

Faça um teste. Faça deploy dos teus ejbs, crie uma classe main, configure as propriedades que te passei acima e tente executar um método do EJB.

Obs.: Só para constar, existem alguns servidores que distribuem uma estrutura de libs que fazem com que a injeção de dependência funcione fora do servidor de aplicação, mas não é comum a todos.

Deixei desta forma:

[code]public class BdFactory {

private static BdFactory_Remote remote;

public static BdListener getBD(int type) {


    if (remote == null) {
        Hashtable props = new Hashtable();
        props.put(InitialContext.INITIAL_CONTEXT_FACTORY, "com.sun.appserv.naming.S1ASCtxFactory");
        props.put(InitialContext.PROVIDER_URL, "iiop://localhost:3700");
        try {
            InitialContext context = new InitialContext(props);
            remote = (BdFactory_Remote) context.lookup("org.rastro.presentation.bd.BdFactory_Remote");
        } catch (NamingException ex) {
            Logger.getLogger(BdFactory.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    return remote.getBD(type);
}[/code]

e ele da um erro de corba:
javax.ejb.EJBException: nested exception is: java.rmi.MarshalException: CORBA MARSHAL 1330446342

Uso o servidor GlassFish 2.1

Confira se as tuas propriedades estão corretas para o Glassfish.

Bom, encontrei diferente.

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

http://www.coderanch.com/t/438887/EJB-Other-Java-EE-Technologies/java/Accessing-Remote-EJB-Glassfish-from