[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjms-developer
Subject:    [openjms-developer] [ openjms-Bugs-831469 ] ClassCastException when using MDBs in Sun ONE AS7
From:       "SourceForge.net" <noreply () sourceforge ! net>
Date:       2003-12-22 13:33:22
[Download RAW message or body]

Bugs item #831469, was opened at 2003-10-28 11:26
Message generated for change (Comment added) made by tanderson
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=474136&aid=831469&group_id=54559

Category: client
Group: v0.7.6-rc1
Status: Open
Resolution: None
Priority: 5
Submitted By: Bo Min Jiang (jiangb)
Assigned to: Tim Anderson (tanderson)
Summary: ClassCastException when using MDBs in Sun ONE AS7

Initial Comment:
I am running Sun ONE Application Server 7 with OpenJMS 
as the JMS provider, and have run into a problem with 
Message Driven Beans.

In the onMessage method of class 
org.exolab.jms.client.JmsConnectionConsumer, a 
ServerSession object is being retrieved from a server 
session pool, and is then cast into a JmsServerSession 
object.  However, the server session pool is an 
application server specific object (for Sun ONE AS7, it's 
implemented by class 
com.iplanet.ias.ejb.containers.IASServerSessionImpl), 
and cannot necessarily be cast into an a 
JmsServerSession object - a ClassCastException occurs 
as a result.  Unfortunately, Sun ONE does not allow me 
to specify a different implementation of the 
ServerSession interface.

Is there a workaround for the problem described?  I need 
to use Sun ONE AS7, and am curious if a similar problem 
exists when using other application servers.

----------------------------------------------------------------------

>Comment By: Tim Anderson (tanderson)
Date: 2003-12-23 00:33

Message:
Logged In: YES 
user_id=557161

I don't believe the changes are in the spirit of the JMS spec. 
Section 8.2.6 states that the application server is responsible 
for creating the thread associated with the Session, so the 
thread creation in JmsSession.run() should be redundant.
This also means that the session could be accessed by 
multiple threads of control, which is not supported by the 
spec.
There is no need to cast to a JmsServerSession - in fact this 
class should be removed.
Also, the message shouldn't be acknowledged in 
JmsConnectionConsumer.onMessage() - the 
ServerSessionPool could create CLIENT_ACKNOWLEDGE or 
transacted sessions.

----------------------------------------------------------------------

Comment By: Tim Anderson (tanderson)
Date: 2003-12-17 23:38

Message:
Logged In: YES 
user_id=557161

Will have a look at the changes this weekend (20/12).
Note that patches can be applied faster if you attach diffs, 
as per 
http://openjms.sourceforge.net/volunteers.html#Submitting 
changes

----------------------------------------------------------------------

Comment By: Neil Kolban (kolban)
Date: 2003-12-10 10:39

Message:
Logged In: YES 
user_id=625504

I realize that this is completely against the spirit of 
OpenSource ... but I would love to test your changes ... 
however ... I am not skilled on building Java apps/classes.  
Would it be possible to email me a copy of your changes as 
replacement JAR files and I will test on WAS V5.1 on your 
behalf?

Neil
(kolban@us.ibm.com)

----------------------------------------------------------------------

Comment By: Bo Min Jiang (bmjiang)
Date: 2003-12-10 06:56

Message:
Logged In: YES 
user_id=645251

I downloaded the source for version v0.7.6-rc1 and made 
some changes that will allow OpenJMS to work with Sun ONE 
when it comes to MDBs.  I've done some testing, and would 
like to get feedback on whether my logic is correct and 
applies with other app servers.

The changes I made are as follows:

JmsSession:
--------------------------------

/**
     * The message cache holds all messages for the session. 
The messages are
     * sent to the listener during start.
     */
    private Vector _messageCache = new Vector();


    /**
     * Add a message to the message cache. This message 
will be processed
     * when the start method is called.
     *
     * @param       message         message to add.
     */
    void addMessage(Message message) {
        _messageCache.addElement(message);
    }

// implementation of Session.run
    public void run() {
        // application server functionality
      (new Thread(new Runnable() {

            /**
             * This method will iterate through the list of 
messages
             * in the cache and send them to the registered 
listener
             */
            public void run() {
                try {
                    Enumeration messages = 
_messageCache.elements();
                    while (messages.hasMoreElements()) {
                        _listener.onMessage((Message) 
messages.nextElement());
                    }
                } catch (Exception exception) {
                    _log.error(
                        "Error in the Session.run method",
                        exception);
                } finally {
                  // Clear message cache
                  _messageCache.clear();
                }
            }
        })).start();
    }

JmsConnectionConsumer:
--------------------------------

public void onMessage(Message message) {
        try {
            // not very sophisticated at this point. Simply get a 
server
            // session put the message in it and start it.
            getSession().acknowledgeMessage(message);

            ServerSession serverSession = (ServerSession) 
_pool.getServerSession();

            //--------------------------
            // BMJ - changes to work with JMSServerSession
            // and other app servers
            //--------------------------

            // If ServerSession is instance of JmsServerSession, 
then add message
            // to server session, else add message to session in 
app server specific server session
            if (serverSession instanceof JmsServerSession)
            {
               JmsServerSession localSession =
                     (JmsServerSession) _pool.getServerSession();
                     
               localSession.addMessage(message);
               localSession.start();
            }
            else
            {
               // ServerSession is application server specific. 
Therefore add
               // message to session and process
               JmsSession session = (JmsSession) 
serverSession.getSession();
               session.addMessage(message);

               // Cause the Session's run method to be called to 
process messages that were just assigned to it.              
               serverSession.start();
            }
        } catch (Exception exception) {
            _log.error(exception, exception);
        }
    }

----------------------------------------------------------------------

Comment By: Neil Kolban (kolban)
Date: 2003-12-09 13:31

Message:
Logged In: YES 
user_id=625504

Folks,
For what its worth ... I stumbled into EXACTLY this 
problem trying to integrate OpenJMS with IBM's WebSphere 
Application Server V5.  Exactly the same problem, exactly 
the same symptoms.

Unfortunately, I have no skills or time to go further into 
the guts of OpenJMS and *contribute* any solutions but I 
would be DELIGHTED to hear from anyone who attempts to get 
this working and am willing to run tests ...

Neil
(kolban@us.ibm.com)

----------------------------------------------------------------------

Comment By: Mike Spille (scubabear68)
Date: 2003-11-19 07:06

Message:
Logged In: YES 
user_id=583085

I don't have time for a fully integrated diff, but the essence 
of the fix for this is:

JmsSession.run():

    public void run() {
        if (connConsumer == null) {
            return;
        }
        Message msg;
        while ((msg = connConsumer.nextMessage()) != null) {
            execute (msg);
        }
        connConsumer = null;
   }


JmsConnectionConsumer:
abstract class JmsConnectionConsumer
    implements ConnectionConsumer, MessageListener 
{
    private Message activeMessage;
    private static int objCount = 0;

    /**
     * This constructor simply manaages the server session 
pool and the 
     * the maximum number of messages that can be loaded 
on any one server
     * session.
     * 
     * @param       pool            the server session pool
     * @param       maxMessages     max number of messages 
it can send to down
     *                              a server session object at any one 
time.
     */
    JmsConnectionConsumer(ServerSessionPool pool, int 
maxMessages) 
    {
        pool_ = pool;
        maxMessages_ = (maxMessages > 0) ? maxMessages : 
1;
        objCount++;
    }

    /**
     * Return a reference ot the server session pool instance 
use by this
     * object
     * <p>
     * If the object is not set or there is any other issue throw 
the 
     * JMSException exception.
     *
     * @return      ServerSessionPool
     * @exception   JMSException
     */
    public ServerSessionPool getServerSessionPool() 
        throws JMSException
    {
        return pool_;
    }
 
    /** 
     * Since a provider may allocate some resources on behalf 
of a 
     * ConnectionConsumer outside the JVM, clients should 
close them when
     * they are not needed. Relying on garbage collection to 
eventually 
     * reclaim these resources may not be timely enough.
     *  
     * @exception JMSException if a JMS fails to release 
resources on
     *                         behalf of ConnectionConsumer or it 
fails
     *                         to close the connection consumer.
     */
    public void close() 
        throws JMSException 
    {
        pool_ = null;
    }

    /**
     * Impmentation of MessageListener.onMessage, which will 
receive
     * messages from the server. In this most simply case it 
actually 
     * loads each individual message into a server session and 
calls 
     * the start method.
     * <p>
     * If this methods gets an error then it will send an error 
message
     * to the logger and return successful
     *
     * @param       message         message send back by the 
server.
     */
    public void onMessage(Message message)
    {
        try
        {
            // not very sophisticated at this point. Simply get a 
server
            // session put the message in it and start it.
            /* MWS - This looks incorrect.  The App Server 
implements the ServerSession pool object, therefore it's 
wrong for us to assume it's one of ours
            getSession().acknowledgeMessage(message);
            JmsServerSession local_session = (JmsServerSession)
pool_.getServerSession();
            local_session.addMessage(message);
            local_session.start();
            */
			activeMessage = message;
            ServerSession servSession = pool_.getServerSession
();
            JmsSession session = (JmsSession)
servSession.getSession();
            session.setConnectionConsumer (this);
            servSession.start();
        }
        catch (Exception exception)
        {
        }
    }

    Message
    nextMessage ()
    {
        Message msg = activeMessage;
        activeMessage = null;
        return (msg);
    }

    /**
     * Abstract mathod that returns the proxy to the server 
side session attached
     * to this object
     *
     * @return      Session
     */
    abstract JmsSession getSession();

    /**
     * Return the maximum number of messages that can be 
loaded down any one
     * server session
     *
     * @return      int
     */
    int getMaxMessages()
    {
        return maxMessages_;
    }

    /**
     * This is a reference to the server session pool, which is 
used to deliver
     * messages to the actual processing client.
     */
    private ServerSessionPool pool_ = null;

    /**
     * This attribute describes the maximum number of 
messages that can be 
     * loaded on a server session at any one time.
     */
    private int maxMessages_ = 1;
}



----------------------------------------------------------------------

Comment By: Tim Anderson (tanderson)
Date: 2003-10-28 11:51

Message:
Logged In: YES 
user_id=557161

OpenJMS's support for MDB's is untested - if you have the 
time, any contribution with respect to this would be much 
appreciated.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=474136&aid=831469&group_id=54559


-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials.
Become an expert in LINUX or just sharpen your skills.  Sign up for IBM's
Free Linux Tutorials.  Learn everything from the bash shell to sys admin.
Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click
_______________________________________________
openjms-developer mailing list
openjms-developer@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openjms-developer
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic