You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@axis.apache.org by "Kroll, Stephanie" <SK...@gers.com> on 2003/05/08 22:24:03 UTC

Possible bug in JavaProvider with EJB in session scope?

Hi All,

We're using WebSphere and I'm trying to migrate from Axis 1.0 to Axis 1.1
RC2.  We do not use Wsdl2Java skeleton classes but deploy our service
objects directly to Axis.

I'm having a problem with SessionEJB-implemented services running in session
scope.  On the first call to the service during the session, it works fine.
But on the second and subsequent calls, the service fails.  I've traced the
problem down to the included code in the JavaProvider class that stores the
service object in the session after the first call.

The first time through, the call to session.get(serviceName) returns null
and so a new service object gets created and returned (the service object is
a session EJB stub class created by the WebSphere EJB deploy-code
generator).  However, the unsynchronized call to session.set(serviceName,
obj) fails silently and does not set the stub class in the session; instead
the previously set LockObject remains there.  On subsequent client requests
to the service, the LockObject gets returned as the service object, which
obviously fails.  This code works fine with the RPC Provider and a standard
Java class as the service object.

I tried adding a line to call session.remove(serviceName) to remove the
LockObject before attempting to set the EJB stub class, and that solved the
problem.
Is this a bug? Has anyone else seen this or does anyone know what is going
on here?

Thanks

    /**
     * Get a service object from a session.  Handles threading / locking
     * issues when multiple threads might be accessing the same session
     * object, and ensures only one thread gets to create the service
     * object if there isn't one already.
     */
    private Object getSessionServiceObject(Session session,
                                           String serviceName,
                                           MessageContext msgContext,
                                           String clsName) throws Exception
{
        Object obj = null;
        boolean makeNewObject = false;

        // This is a little tricky.
        synchronized (session.getLockObject()) {
            // store service objects in session, indexed by class name
            obj = session.get(serviceName);

            // If nothing there, put in a placeholder object so
            // other threads wait for us to create the real
            // service object.
            if (obj == null) {
                obj = new LockObject();
                makeNewObject = true;
                session.set(serviceName, obj);
            }
        }

        // OK, we DEFINITELY have something in obj at this point.  Either
        // it's the service object or it's a LockObject (ours or someone
        // else's).

        if (LockObject.class == obj.getClass()) {
            LockObject lock = (LockObject)obj;

            // If we were the lucky thread who got to install the
            // placeholder, create a new service object and install it
            // instead, then notify anyone waiting on the LockObject.
            if (makeNewObject) {
                obj = getNewServiceObject(msgContext, clsName);
                session.remove(serviceName);		//******* <- I added
this line
                session.set(serviceName, obj);
                lock.complete();
            } else {
                // It's someone else's LockObject, so wait around until
                // it's completed.
                lock.waitUntilComplete();

                // Now we are guaranteed there is a service object in the
                // session, so this next part doesn't need syncing
                obj = session.get(serviceName);
            }
        }

        return obj;
    }



-----------------------------------------------------
Stephanie Kroll
Senior Software Engineer

Corporate Office
GERS, Inc.