Problemas con JMS dentro de un EJB de Sesion

51 views
Skip to first unread message

Pablo Augusto Sznajdleder

unread,
Jul 19, 2006, 5:59:00 AM7/19/06
to jav...@googlegroups.com
Gente, a ver si alguien me puede ayudar con esto.
Estoy haciendo unas pruebas con EJB (version 2.1) y JMS. Estoy utilizando JBoss 3.2.7.

Tengo un EJB de Sesion Stateless con un metodo llamado: metodoTransaccion(int id,String mssg).
Dentro de este metodo invoco a otros dos metodos privados en este orden:

            insertEnDB(id);
            sendMessageEnTopic(mssg);

Estoy haciendo unas pruebas con las transacciones del container de EJB. Pero antes de poder probar nada con las transacciones tengo un problema basico: cuando trato de enviar el mensaje al Topic (dentro del metodo sendMessageEnTopic() tira una excepcion diciendo: NoSuchMethodException...

06:43:32,912 ERROR [LogInterceptor] Unexpected Error in method: public abstract void test.interfaces.Facade.metodoTransaccion(int,java.lang.String) throws java.rmi.RemoteException
java.lang.NoSuchMethodError: javax.jms.TopicPublisher.send(Ljavax/jms/Message;)V
    at test.ejb.FacadeBean.sendMessageEnTopic(FacadeBean.java:146)
    at test.ejb.FacadeBean.metodoTransaccion(FacadeBean.java :104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Es decir: por que no encuentra ese metodo (es el metodo send() de la clase TopicPublisher) ?????

A continuacion les copio el codigo del bean con su documentacion XDoclet. Para simplificar elimine todos los metodos de ciclo de vida (ejbActivated, ejbPassivated, etc).
En el codigo resalte en negrita y en rojo los segmentos de codigo donde ocurre el error...

Hay que aclarar que ese mismo codigo (el del metodo sendMssgEnTopic) si lo corro desde un main() standalone funciona perfectamente. El problema es al llamarlo dentro del SessionBean, dentro del container.

Si alguien leyo hasta esta linea desde ya le estoy agradecido. Y si ademas me puede ayudar a encontrar el problama mucho mas agradecido todavia quedare :O)

Saludos !!!

----[CODIGO DEL EJB]-------

package test.ejb;

import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.PreparedStatement;

import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext ;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import javax.transaction.UserTransaction;

/**
 * XDoclet-based session bean. The class must be declared public according to
 * the EJB specification.
 *
 * To generate the EJB related files to this EJB: - Add Standard EJB module to
 * XDoclet project properties - Customize XDoclet configuration for your
 * appserver - Run XDoclet
 *
 * Below are the xdoclet-related tags needed for this EJB.
 *
 * @ejb.bean name="Facade"
 *              display-name="Name for Facade"
 *           description="Description for Facade"
 *           jndi-name="ejb/Facade"
 *           type="Stateless"
 *           view-type="remote"
 *           transaction-type="Container"
 */
public class FacadeBean implements SessionBean
{

    /**
     * An example business method
     *
     * @ejb.interface-method view-type = "remote"
     * @ejb.transaction type = "Required"
     * @throws EJBException
     *             Thrown if method fails due to system-level error.
     */
    public void metodoTransaccion(int id,String mssg) throws EJBException
    {
//        UserTransaction trx=null;
        try
        {
//            trx=context.getUserTransaction();
//            trx.begin();
           
           
            insertEnDB(id);
            sendMessageEnTopic(mssg);
           
//            trx.commit();
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
            throw new EJBException(ex);
        }
        finally
        {
            try
            {
//                trx.rollback();
            }
            catch(Exception ex)
            {
                ex.printStackTrace();
                throw new EJBException(ex);
            }
        }
    }

    private void sendMessageEnTopic(String mssg)
    {
        Context contextoInicial = null;
        TopicSession sesion = null;
        try
        {
            contextoInicial = new InitialContext();

            TopicConnectionFactory factory = (TopicConnectionFactory) contextoInicial.lookup("java:/XAConnectionFactory");
            Topic cola = (Topic) contextoInicial.lookup("topic/testTopic");
           
            TopicConnection conexion = factory.createTopicConnection();
            sesion = conexion.createTopicSession(true, TopicSession.AUTO_ACKNOWLEDGE);
           
            TopicPublisher enviaACola = sesion.createPublisher(cola);
           
            TextMessage mensaje = sesion.createTextMessage();
            mensaje.setText(mssg);
           
            enviaACola.send(mensaje);
           
            conexion.close();

        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            throw new EJBException(ex);
        }
    }

    private void insertEnDB(int id)
    {
        Connection con = null;
        PreparedStatement pstm = null;

        try
        {
            con = getConnection();
            String sql = "";
            sql += "INSERT INTO dept (deptno,dname,loc) ";
            sql += "VALUES (?,'Mi Dept','Mi Loc') ";
            pstm = con.prepareStatement(sql);
            pstm.setInt(1, id);

            if (pstm.executeUpdate() != 1)
            {
                throw new EJBException("---> Error al insertar !!");
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            throw new EJBException(ex);
        }
        finally
        {
            try
            {
                if (pstm != null) pstm.close();
                if (con != null) con.close();
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
                throw new EJBException(ex);
            }
        }
    }

    private Connection getConnection()
    {
        try
        {
            Context ctx = new InitialContext();
            DataSource ds = (DataSource) ctx.lookup("java:/OracleDS");
            return ds.getConnection();
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            throw new EJBException(ex);
        }
    }
}


--
Ing. Pablo Augusto Sznajdleder_________
(5411) 4637-8879  |  15-4419-JAVA (5282)

email: pab...@pablosz.com.ar
skype: pabloszn
http://www.PabloSZ.com.ar
http://www.JavaSOS.com.ar

Claudio Fernandez

unread,
Jul 19, 2006, 11:06:56 AM7/19/06
to jav...@googlegroups.com
Pablo, no será algún problema relacionado con las versiones de jms que
estas usando, ya que el MessageProducer (interfaz que extiende el
TopicPublisher) solo entiende el metodo send(..) a partir de la
versión 1.1, las versiones 1.0.x no lo tienen. Creo que quizas surja
el problema porque estas compilando con un jar y corriendo con otro
jar diferente...

No se, mi mejor apuesta viendo el problema así rapido.

David Brunstein

unread,
Jul 19, 2006, 12:00:27 PM7/19/06
to jav...@googlegroups.com
Hola Pablo,

No se si tendra que ver, en una clase aca veo que usa otra secuencia de pasos.

Metodo openConnection()
            m_connection = m_factory.createTopicConnection();        // esto lo tenes.
            m_connection.start();                                                    // vos no invocas start().

                                                                                     // vos lo invocas con true
           m_session = m_connection.createTopicSession( false, Session.AUTO_ACKNOWLEDGE );

           m_publisher = m_session.createPublisher( m_topic );     // m_publisher es una instancia de TopicPublisher


Metodo send(Message message)
    // message es un objeto devuelto por MessageBuilder.buildMessage()
            m_publisher.publish( message );


Metodo closeConnection()
            if( null != m_publisher ) m_publisher.close();
            if( null != m_session ) m_session.close();
            if( null != m_connection ) m_connection.close();
        m_publisher = null;
        m_session = null;
        m_connection = null;


Te repito quizas no tenga nada que ver, porque a vos te funca desde un main() y no corriendolo en el container. Quizas haya algun seteo que hacer.

Espero que te sirva,
David.

On 7/19/06, Claudio Fernandez <clau...@gmail.com> wrote:
Pablo, no será algún problema relacionado con las versiones de jms que
estas usando, ya que el MessageProducer (interfaz que extiende el
TopicPublisher) solo entiende el metodo send(..) a partir de la
versión 1.1 , las versiones 1.0.x no lo tienen. Creo que quizas surja
>  * @ ejb.bean name="Facade"
--
=======================
David Brunstein

Java/PB/VFP Developer
Winnipeg, MB
Canada

Before I speak, I have something important to say.
Antes de dar mi discurso, tengo algo importante que decir.
Antes de dar meu discurso, tenho algo importante para dizer.
G.M.

pela_uy

unread,
Jul 20, 2006, 11:08:08 AM7/20/06
to JavaSOS
Hola Pablo, creo que estas teniendo problemas con los jars
(compilaciones distintas), verificar el classpath.

Saludos,
Alfredo

Reply all
Reply to author
Forward
0 new messages