Glassfish + JPA + Maven +EJB

7 respostas
M

Oi,
Estou tentando desenvolver uma aplicação em JEE utilizando EJB, JPA, Glassfish, no entanto tenho um problema do qual não consigo resolver.
É o seguinte estou fazendo um appclient que faz uma requisição a um stateless session bean, bem eu estou conseguindo uma resposta na primeira requisição, mas se eu tento fazer uma segunda requisição estou obtendo uma excessão indicando que meu EntityManager está fechado.
Se tento fazer uma terceira requisição da certo, uma quarta consigo a excessão de novo e assim por diante, ou seja, ele responde corretamente requisições impares, mas lança a exessão nas pares.
Essa é a excessão:

14/05/2009 07:56:55 com.sun.enterprise.appclient.MainWithModuleSupport 

WARNING: ACC003: Application threw an exception.

javax.ejb.EJBException: nested exception is: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:

java.rmi.RemoteException: null; nested exception is:

java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager.

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:

java.rmi.RemoteException: null; nested exception is:

java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager.

at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.mapSystemException(Util.java:243)

at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:205)

at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:152)

at com.sun.corba.ee.impl.presentation.rmi.bcel.BCELStubBase.invoke(BCELStubBase.java:225)

at br.ufg.inf.lbs.sdl.__LocationServiceRemote_Remote_DynamicStub.getLocation(br/ufg/inf/lbs/sdl/__LocationServiceRemote_Remote_DynamicStub.java)

at br.ufg.inf.lbs.sdl._LocationServiceRemote_Wrapper.getLocation(br/ufg/inf/lbs/sdl/_LocationServiceRemote_Wrapper.java)

at br.ufg.inf.lbs.sdl.App.main(App.java:2

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:597)

at com.sun.enterprise.util.Utility.invokeApplicationMain(Utility.java:266)

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

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

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

Caused by: java.rmi.RemoteException: null; nested exception is:

java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager.

at com.sun.enterprise.iiop.POAProtocolMgr.mapException(POAProtocolMgr.java:251)

at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1411)

at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1316)

at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:210)

at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:77)

at $Proxy41.getLocation(Unknown Source)

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:597)

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

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

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

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

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

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

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

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

at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:563)

at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2567)

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

Caused by: java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager.

at org.eclipse.persistence.internal.jpa.EntityManagerImpl.verifyOpen(EntityManagerImpl.java:1210)

at org.eclipse.persistence.internal.jpa.EJBQueryImpl.setMaxResults(EJBQueryImpl.java:833)

at br.ufg.inf.lbs.sdl.LocationServiceBean.getLocation(LocationServiceBean.java:61)

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:597)

at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1011)

at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:175)

at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2920)

at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4011)

at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:203)

 17 more

javax.ejb.EJBException: nested exception is: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:

java.rmi.RemoteException: null; nested exception is:

java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager.

at br.ufg.inf.lbs.sdl._LocationServiceRemote_Wrapper.getLocation(br/ufg/inf/lbs/sdl/_LocationServiceRemote_Wrapper.java)

at br.ufg.inf.lbs.sdl.App.main(App.java:2

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:597)

at com.sun.enterprise.util.Utility.invokeApplicationMain(Utility.java:266)

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

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

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

Exception in thread main java.lang.RuntimeException: java.lang.reflect.InvocationTargetException

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

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

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

Caused by: java.lang.reflect.InvocationTargetException

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:597)

at com.sun.enterprise.util.Utility.invokeApplicationMain(Utility.java:266)

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

 2 more

Caused by: javax.ejb.EJBException: nested exception is: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:

java.rmi.RemoteException: null; nested exception is:

java.lang.IllegalStateException: Attempting to execute an operation on a closed EntityManager.

at br.ufg.inf.lbs.sdl._LocationServiceRemote_Wrapper.getLocation(br/ufg/inf/lbs/sdl/_LocationServiceRemote_Wrapper.java)

at br.ufg.inf.lbs.sdl.App.main(App.java:2

 8 more

Não estou certo onde o problema está sendo gerado, afinal estou usando muitas tecnogias, já tentei muita coisa no entanto não consigo resolver esse problema enfim gostaria de pedir ajuda. Se alguém aki tem alguma idéia de como resolver por favor me ajude.
Eu ficaria extremamente agradecido

Obrigado

7 Respostas

Javabuntu

antes de sair criando um monte de tópicos iguais:
http://www.guj.com.br/posts/list/126571.java#683738
http://www.guj.com.br/posts/list/126570.java#683737

deveria ler esse artigo:
http://www.guj.com.br/posts/list/50115.java

e criando esse monte de tópicos iguais pra aumentar suas chances de solucionar seu problema, você só acaba minando suas chances de respostas, tem gente que não gosta disso e acaba não te ajudando mesmo sabendo a resposta da sua dúvida. :twisted:

M

Desculpe não tinha intenção de ofender ninguem apenas postei o mesmo topico tanto no forum de JEE quanto no de persistencia pois não sei ao certo a origem desse erro, se é alguma questão de configuração do glassfish, se é alguma notação do JPA que estou esquecendo de fazer ou se por um acaso estou pecando em algum conceito fundamental de JEE.
É a primeira vez que posto uma duvida em um forum e não imaginava que colocar um mesmo topico em duas sessões diferentes poderia gerar esse tipo de reação, afinal o que pensei foi que deveria dividir o pedido em areas do qual acredita-se que poderiam estar gerando o erro.
Sinto muito se violei uma boa pratica da comunidade no entanto alego inexperiencia e não negligencia, desde já me retiro do forum e peço desculpa por qualquer inconveniente

javaBeats

Bem, agora que você se desculpou… :wink:

Preste atenção na exceção lançada. Uma busca rápida no Google e no Java tutorial vai te informar que você está tentando reutilizar um contexto de persistência que já foi fechado pelo container. Não tem como apontar exatamente o que você está fazendo de errado sem olhar código, mas com certeza é um problema relacionado a manutenção do estado do seu componente server side, bem como sua transação JTA. Quando você executa o método pela segunda vez, está usando uma referência antiga do EntityManager, já fechada. Na terceira você obtém uma referência nova, e aí o erro não acontece. Investigue também a referência que você está guardando do bean remoto.

M

Tipo então como faço, pra fazer com que isso de certo, pensando no que vc me disse dei uma pesquisada e já que o contexto estava sendo fechado troquei a minha notação de @Stateless para @Stateful e deu certo agora ele responde corretamente a cada requisição, no entanto creio que fazer isso é meio POG, queria realmente entender o por que de a cada requisição o cliente não obtem um novo contexto. Tipo como o session bean estava sendo gerenciado pelo conteiner acreditei que todo esse processo deveria ser automatico no entanto ao que parece a transaction não é finalizada. Pode ser pedir um pouco demais, mas poderia dar uma rapida olhada no código do meu sessionBean e me indicar qual o grande erro.

package br.ufg.inf.lbs.sdl;

import br.ufg.inf.lbs.commons.entities.PositionNotification;

import java.util.ArrayList;

import java.util.Date;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Vector;

import javax.ejb.Stateless;

import javax.ejb.TransactionAttribute;

import javax.persistence.EntityManager;

import javax.persistence.PersistenceContext;

import javax.persistence.Query;

/**

  • Interface do Serviço de Dados de Localização.
    */
    @Stateless
    public class LocationServiceBean implements LocationServiceRemote {

    @PersistenceContext(unitName = sdl)
    
    private EntityManager em;
    
    private Query simpleQuery;
    
    private Query historyQuery;
    

    public LocationServiceBean() {
    }

    public LocationServiceBean(EntityManager em) {
    
    this.em = em;
    
    }
    
    private Query createQueryFindByDeviceId() {
    
    return em.createQuery(SELECT p FROM Notification p WHERE p.device.gid=:id +
    
    " ORDER BY p.receivedAt DESC");
    
    }
    
    private Query getQueryFindByDeviceId() {
    
    if (simpleQuery == null) {
    
    simpleQuery = createQueryFindByDeviceId();
    
    }
    
    return simpleQuery;
    
    }
    
    <a class="mention" href="/u/override">@Override</a>
    
    public List getLocation(List ids) {
    
    if (ids == null) {
    
    throw new IllegalArgumentException();
    
    }
    
    List<PositionNotification> list = new ArrayList<PositionNotification>();
     simpleQuery = getQueryFindByDeviceId();
     simpleQuery.setMaxResults(1);
    
     for (String id : ids) {
    
         simpleQuery.setParameter("id", id);
         List result = simpleQuery.getResultList();
         if (result.size() > 0) {
             PositionNotification position = (PositionNotification) result.get(0);
    
             if (position != null) {
                 list.add(position);
             }
         }
     }
     return list;
    

    }

}

javaBeats

Parece que o problema está no seu cliente. A referência do bean, como você obtém?

M

Ja implementei de ambas as formas por injeção de dependencia e por lookup, seja como for ta dando no mesmo, de qualquer forma envio a versão com injeção de dependecia:

public class App
{

@EJB
private static LocationServiceRemote bean;
private static List<String> ids;
private static List<PositionNotification> list;

public static void main( String[] args )
{
    System.out.println( "Eu sou uma aplicação cliente de um contêiner!");

    ids = new ArrayList<String>();
    ids.add("10A53R");
    ids.add("32W77U");
    list = bean.getLocation(ids);
    System.out.println( "Realizada a requisição");

    if(list==null) {
        System.out.println("Serviço não executado.");
        return;
    }

    System.out.println("Posições:");

    System.out.println(list);
}

}

javaBeats

Cara, tá estranho… mapeamento das entidades?

Meu palpite é que sua entidade tem algum relacionamento Lazy, que ao ser serializado para o cliente, usa o contexto de persistência, e como ele já está fechado (afinal, seu bean é stateless), o erro é gerado.

Para testar, caso sua entidade tenha relacionamento lazy, traga-os já na consulta, ou faça a inicialização - via get() - antes de adicionar o resultado à lista. Isto deve confirmar se o meu palpite está correto ou não.

Criado 14 de maio de 2009
Ultima resposta 14 de mai. de 2009
Respostas 7
Participantes 3