dain        2005/06/06 11:20:56

  Modified:    modules/core/src/java/org/openejb/server/ejbd
                        EjbRequestHandler.java JndiRequestHandler.java
  Log:

  Clean up thread context class loaders in a finally block.  This allows class 
loaders to be garbage collected.
  
  Revision  Changes    Path
  1.20      +133 -129  
openejb/modules/core/src/java/org/openejb/server/ejbd/EjbRequestHandler.java
  
  Index: EjbRequestHandler.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/server/ejbd/EjbRequestHandler.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- EjbRequestHandler.java    28 Mar 2005 22:55:55 -0000      1.19
  +++ EjbRequestHandler.java    6 Jun 2005 15:20:56 -0000       1.20
  @@ -127,144 +127,148 @@
   
           CallContext call = null;
           EJBContainer container = null;
  -
  +        ClassLoader oldClassLoader = 
Thread.currentThread().getContextClassLoader();
           try {
  -            container = getContainer(req);
  -            ClassLoader cl = container.getClassLoader();
  -            Thread.currentThread().setContextClassLoader(cl);
  -            in.setClassLoader(cl);
  -
  -            Method methodInstance = req.getMethodInstance();
  -            int methodIndex = container.getMethodIndex(methodInstance);
  -            req.setMethodIndex(methodIndex);
  -
  -            /**
  -             * The identification principal contains the subject id.  Use 
this
  -             * id to obtain the registered subject.
  -             */
  -            Subject subject = null;
  -            IdentificationPrincipal principal = (IdentificationPrincipal) 
req.getClientIdentity();
  -            if (principal != null && principal.getId() != null) {
  -                subject = 
ContextManager.getRegisteredSubject(principal.getId());
  -            } else {
  -                subject = container.getDefaultSubject();
  -            }
  +            try {
  +                container = getContainer(req);
  +                ClassLoader cl = container.getClassLoader();
  +                Thread.currentThread().setContextClassLoader(cl);
  +                in.setClassLoader(cl);
  +
  +                Method methodInstance = req.getMethodInstance();
  +                int methodIndex = container.getMethodIndex(methodInstance);
  +                req.setMethodIndex(methodIndex);
  +
  +                /**
  +                 * The identification principal contains the subject id.  
Use this
  +                 * id to obtain the registered subject.
  +                 */
  +                Subject subject = null;
  +                IdentificationPrincipal principal = 
(IdentificationPrincipal) req.getClientIdentity();
  +                if (principal != null && principal.getId() != null) {
  +                    subject = 
ContextManager.getRegisteredSubject(principal.getId());
  +                } else {
  +                    subject = container.getDefaultSubject();
  +                }
   
  -            ContextManager.setCurrentCaller(subject);
  -            ContextManager.setNextCaller(subject);
  +                ContextManager.setCurrentCaller(subject);
  +                ContextManager.setNextCaller(subject);
   
  -            log.debug("setting cl=" + cl + " for " + 
container.getContainerID());
  -        } catch (RemoteException e) {
  -            replyWithFatalError
  -                    (out, e, "No such deployment");
  -            return;
  -            /*
  -                logger.warn( req + "No such deployment: "+e.getMessage());
  -                res.setResponse( EJB_SYS_EXCEPTION, e);
  -                res.writeExternal( out );
  +                log.debug("setting cl=" + cl + " for " + 
container.getContainerID());
  +            } catch (RemoteException e) {
  +                replyWithFatalError
  +                        (out, e, "No such deployment");
                   return;
  -            */
  -        } catch (Throwable t) {
  -            replyWithFatalError(out, t, "Unkown error occured while 
retrieving deployment");
  -            return;
  -        }
  +                /*
  +                    logger.warn( req + "No such deployment: 
"+e.getMessage());
  +                    res.setResponse( EJB_SYS_EXCEPTION, e);
  +                    res.writeExternal( out );
  +                    return;
  +                */
  +            } catch (Throwable t) {
  +                replyWithFatalError(out, t, "Unkown error occured while 
retrieving deployment");
  +                return;
  +            }
   
  -        try {
  -            call = CallContext.getCallContext();
  -            call.setEJBRequest(req);
  -            call.setContainer(container);
  -        } catch (Throwable t) {
  -            replyWithFatalError(out, t, "Unable to set the thread context 
for this request");
  -            return;
  -        }
  +            try {
  +                call = CallContext.getCallContext();
  +                call.setEJBRequest(req);
  +                call.setContainer(container);
  +            } catch (Throwable t) {
  +                replyWithFatalError(out, t, "Unable to set the thread 
context for this request");
  +                return;
  +            }
   
  -        //logger.info( "EJB REQUEST : "+req );
  +            //logger.info( "EJB REQUEST : "+req );
   
  -        try {
  -            switch (req.getRequestMethod()) {
  -                // Remote interface methods
  -                case EJB_OBJECT_BUSINESS_METHOD:
  -                    doEjbObject_BUSINESS_METHOD(req, res);
  -                    break;
  -
  -                    // Home interface methods
  -                case EJB_HOME_METHOD:
  -                    doEjbHome_METHOD(req, res);
  -                    break;
  -
  -                case EJB_HOME_CREATE:
  -                    doEjbHome_CREATE(req, res);
  -                    break;
  -
  -                case EJB_HOME_FIND:
  -                    doEjbHome_FIND(req, res);
  -                    break;
  -
  -                    // javax.ejb.EJBObject methods
  -                case EJB_OBJECT_GET_EJB_HOME:
  -                    doEjbObject_GET_EJB_HOME(req, res);
  -                    break;
  -
  -                case EJB_OBJECT_GET_HANDLE:
  -                    doEjbObject_GET_HANDLE(req, res);
  -                    break;
  -
  -                case EJB_OBJECT_GET_PRIMARY_KEY:
  -                    doEjbObject_GET_PRIMARY_KEY(req, res);
  -                    break;
  -
  -                case EJB_OBJECT_IS_IDENTICAL:
  -                    doEjbObject_IS_IDENTICAL(req, res);
  -                    break;
  -
  -                case EJB_OBJECT_REMOVE:
  -                    doEjbObject_REMOVE(req, res);
  -                    break;
  -
  -                    // javax.ejb.EJBHome methods
  -                case EJB_HOME_GET_EJB_META_DATA:
  -                    doEjbHome_GET_EJB_META_DATA(req, res);
  -                    break;
  -
  -                case EJB_HOME_GET_HOME_HANDLE:
  -                    doEjbHome_GET_HOME_HANDLE(req, res);
  -                    break;
  -
  -                case EJB_HOME_REMOVE_BY_HANDLE:
  -                    doEjbHome_REMOVE_BY_HANDLE(req, res);
  -                    break;
  -
  -                case EJB_HOME_REMOVE_BY_PKEY:
  -                    doEjbHome_REMOVE_BY_PKEY(req, res);
  -                    break;
  -            }
  -        } catch (org.openejb.InvalidateReferenceException e) {
  -            res.setResponse(EJB_SYS_EXCEPTION, e.getCause());
  -        } catch (org.openejb.ApplicationException e) {
  -            res.setResponse(EJB_APP_EXCEPTION, e.getCause());
  -        } catch (org.openejb.SystemException e) {
  -            res.setResponse(EJB_ERROR, e.getCause());
  -
  -            // TODO:2: This means a severe error occured in OpenEJB
  -            // we should restart the container system or take other
  -            // aggressive actions to attempt recovery.
  -            log.fatal(req + ": OpenEJB encountered an unknown system error 
in container: ", e);
  -        } catch (java.lang.Throwable t) {
  -            //System.out.println(req+": Unkown error in container: ");
  -            replyWithFatalError(out, t, "Unknown error in container");
  -            return;
  -        } finally {
  -            log.debug("EJB RESPONSE: " + res);
               try {
  -                res.writeExternal(out);
  -            } catch (java.io.IOException e) {
  -                if (e instanceof NotSerializableException && res.getResult() 
!= null) {
  -                    log.fatal("Invocation result object is not serializable: 
" + res.getResult().getClass().getName(), e);
  -                } else {
  -                    log.fatal("Couldn't write EjbResponse to output stream", 
e);
  +                switch (req.getRequestMethod()) {
  +                    // Remote interface methods
  +                    case EJB_OBJECT_BUSINESS_METHOD:
  +                        doEjbObject_BUSINESS_METHOD(req, res);
  +                        break;
  +
  +                        // Home interface methods
  +                    case EJB_HOME_METHOD:
  +                        doEjbHome_METHOD(req, res);
  +                        break;
  +
  +                    case EJB_HOME_CREATE:
  +                        doEjbHome_CREATE(req, res);
  +                        break;
  +
  +                    case EJB_HOME_FIND:
  +                        doEjbHome_FIND(req, res);
  +                        break;
  +
  +                        // javax.ejb.EJBObject methods
  +                    case EJB_OBJECT_GET_EJB_HOME:
  +                        doEjbObject_GET_EJB_HOME(req, res);
  +                        break;
  +
  +                    case EJB_OBJECT_GET_HANDLE:
  +                        doEjbObject_GET_HANDLE(req, res);
  +                        break;
  +
  +                    case EJB_OBJECT_GET_PRIMARY_KEY:
  +                        doEjbObject_GET_PRIMARY_KEY(req, res);
  +                        break;
  +
  +                    case EJB_OBJECT_IS_IDENTICAL:
  +                        doEjbObject_IS_IDENTICAL(req, res);
  +                        break;
  +
  +                    case EJB_OBJECT_REMOVE:
  +                        doEjbObject_REMOVE(req, res);
  +                        break;
  +
  +                        // javax.ejb.EJBHome methods
  +                    case EJB_HOME_GET_EJB_META_DATA:
  +                        doEjbHome_GET_EJB_META_DATA(req, res);
  +                        break;
  +
  +                    case EJB_HOME_GET_HOME_HANDLE:
  +                        doEjbHome_GET_HOME_HANDLE(req, res);
  +                        break;
  +
  +                    case EJB_HOME_REMOVE_BY_HANDLE:
  +                        doEjbHome_REMOVE_BY_HANDLE(req, res);
  +                        break;
  +
  +                    case EJB_HOME_REMOVE_BY_PKEY:
  +                        doEjbHome_REMOVE_BY_PKEY(req, res);
  +                        break;
  +                }
  +            } catch (InvalidateReferenceException e) {
  +                res.setResponse(EJB_SYS_EXCEPTION, e.getCause());
  +            } catch (org.openejb.ApplicationException e) {
  +                res.setResponse(EJB_APP_EXCEPTION, e.getCause());
  +            } catch (org.openejb.SystemException e) {
  +                res.setResponse(EJB_ERROR, e.getCause());
  +
  +                // TODO:2: This means a severe error occured in OpenEJB
  +                // we should restart the container system or take other
  +                // aggressive actions to attempt recovery.
  +                log.fatal(req + ": OpenEJB encountered an unknown system 
error in container: ", e);
  +            } catch (Throwable t) {
  +                //System.out.println(req+": Unkown error in container: ");
  +                replyWithFatalError(out, t, "Unknown error in container");
  +                return;
  +            } finally {
  +                log.debug("EJB RESPONSE: " + res);
  +                try {
  +                    res.writeExternal(out);
  +                } catch (java.io.IOException e) {
  +                    if (e instanceof NotSerializableException && 
res.getResult() != null) {
  +                        log.fatal("Invocation result object is not 
serializable: " + res.getResult().getClass().getName(), e);
  +                    } else {
  +                        log.fatal("Couldn't write EjbResponse to output 
stream", e);
  +                    }
                   }
  +                call.reset();
               }
  -            call.reset();
  +        } finally {
  +            Thread.currentThread().setContextClassLoader(oldClassLoader);
           }
       }
   
  
  
  
  1.12      +39 -37    
openejb/modules/core/src/java/org/openejb/server/ejbd/JndiRequestHandler.java
  
  Index: JndiRequestHandler.java
  ===================================================================
  RCS file: 
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/server/ejbd/JndiRequestHandler.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- JndiRequestHandler.java   8 May 2005 19:37:06 -0000       1.11
  +++ JndiRequestHandler.java   6 Jun 2005 15:20:56 -0000       1.12
  @@ -90,47 +90,49 @@
   
           Thread thread = Thread.currentThread();
           ClassLoader contextClassLoader = thread.getContextClassLoader();
  -
  -        if (req.getClientModuleID() != null) {
  -            contextClassLoader = thread.getContextClassLoader();
  -            try {
  -                ObjectName objectName = new 
ObjectName(req.getClientModuleID());
  -                ClassLoader classLoader = 
(ClassLoader)KernelRegistry.getSingleKernel().getAttribute(objectName, 
"classLoader");
  -                thread.setContextClassLoader(classLoader);
  -            } catch (Throwable e) {
  -                replyWithFatalError(out, e, "Failed to set the correct 
classloader");
  -                return;
  -            }
  -        }
  -
           try {
  -            switch (req.getRequestMethod()) {
  -                case JNDI_LOOKUP:
  -                    doLookup(req, res);
  -                    break;
  -                case JNDI_LIST:
  -                    doList(req, res);
  -                    break;
  -                case JNDI_LIST_BINDINGS:
  -                    doListBindings(req, res);
  -                    break;
  -                default: throw new UnsupportedOperationException("Request 
method not supported: "+req.getRequestMethod());
  +            if (req.getClientModuleID() != null) {
  +                contextClassLoader = thread.getContextClassLoader();
  +                try {
  +                    ObjectName objectName = new 
ObjectName(req.getClientModuleID());
  +                    ClassLoader classLoader = 
(ClassLoader)KernelRegistry.getSingleKernel().getAttribute(objectName, 
"classLoader");
  +                    thread.setContextClassLoader(classLoader);
  +                } catch (Throwable e) {
  +                    replyWithFatalError(out, e, "Failed to set the correct 
classloader");
  +                    return;
  +                }
               }
  -        } catch (Exception e) {
  -            log.error("JNDI request error", e);
  -            res.setResponseCode(JNDI_ERROR);
  -            res.setResult(e);
  -        } finally {
  +
               try {
  -                res.writeExternal(out);
  -            } catch (Throwable t) {
  -                log.error("Failed to write to JNDIResponse", t);
  -            }
  -            if (req.getClientModuleID() != null) {
  -                thread.setContextClassLoader(contextClassLoader);
  +                switch (req.getRequestMethod()) {
  +                    case JNDI_LOOKUP:
  +                        doLookup(req, res);
  +                        break;
  +                    case JNDI_LIST:
  +                        doList(req, res);
  +                        break;
  +                    case JNDI_LIST_BINDINGS:
  +                        doListBindings(req, res);
  +                        break;
  +                    default: throw new 
UnsupportedOperationException("Request method not supported: 
"+req.getRequestMethod());
  +                }
  +            } catch (Exception e) {
  +                log.error("JNDI request error", e);
  +                res.setResponseCode(JNDI_ERROR);
  +                res.setResult(e);
  +            } finally {
  +                try {
  +                    res.writeExternal(out);
  +                } catch (Throwable t) {
  +                    log.error("Failed to write to JNDIResponse", t);
  +                }
  +                if (req.getClientModuleID() != null) {
  +                    thread.setContextClassLoader(contextClassLoader);
  +                }
               }
  +        } finally {
  +            thread.setContextClassLoader(contextClassLoader);
           }
  -
       }
   
       private void doListBindings(JNDIRequest req, JNDIResponse res) {
  
  
  

Reply via email to