portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tay...@apache.org
Subject svn commit: r1610038 - in /portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE: components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/ jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/ jetspeed-commons/...
Date Sat, 12 Jul 2014 20:06:37 GMT
Author: taylor
Date: Sat Jul 12 20:06:36 2014
New Revision: 1610038

URL: http://svn.apache.org/r1610038
Log:
JS2-1283: backporting changes to 2.2.3 from trunk

Modified:
    portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/CommonjWorkerMonitorImpl.java
    portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java
    portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java
    portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerMonitorImpl.java
    portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/RenderingJob.java
    portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/Worker.java
    portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-commons/src/main/java/org/apache/jetspeed/util/ServletRequestCleanupService.java

Modified: portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/CommonjWorkerMonitorImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/CommonjWorkerMonitorImpl.java?rev=1610038&r1=1610037&r2=1610038&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/CommonjWorkerMonitorImpl.java (original)
+++ portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/CommonjWorkerMonitorImpl.java Sat Jul 12 20:06:36 2014
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,27 +19,26 @@ package org.apache.jetspeed.aggregator.i
 
 import java.security.AccessControlContext;
 import java.security.AccessController;
-import java.util.List;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.Collections;
-import java.util.Map;
 import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.jetspeed.aggregator.PortletContent;
 import org.apache.jetspeed.aggregator.RenderingJob;
 import org.apache.jetspeed.aggregator.Worker;
 import org.apache.jetspeed.aggregator.WorkerMonitor;
-import org.apache.jetspeed.aggregator.PortletContent;
-
 import org.apache.jetspeed.container.PortletWindow;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-import commonj.work.WorkManager;
 import commonj.work.Work;
+import commonj.work.WorkEvent;
 import commonj.work.WorkItem;
 import commonj.work.WorkListener;
-import commonj.work.WorkEvent;
+import commonj.work.WorkManager;
 
 /**
  * The CommonjWorkerMonitorImpl is responsible for dispatching jobs to workers
@@ -51,45 +50,49 @@ import commonj.work.WorkEvent;
 public class CommonjWorkerMonitorImpl implements WorkerMonitor, WorkListener
 {
 
-    public static final String ACCESS_CONTROL_CONTEXT_WORKER_ATTR = AccessControlContext.class.getName();
+    /**
+     * @deprecated Use {@link RenderingJob#ACCESS_CONTROL_CONTEXT_WORKER_ATTR} instead.
+     */
+    public static final String ACCESS_CONTROL_CONTEXT_WORKER_ATTR = RenderingJob.ACCESS_CONTROL_CONTEXT_WORKER_ATTR;
+
     public static final String COMMONJ_WORK_ITEM_ATTR = WorkItem.class.getName();
     public static final String WORKER_THREAD_ATTR = Worker.class.getName();
-    
+
     /** CommonJ Work Manamger provided by JavaEE container */
     protected WorkManager workManager;
 
     /** If true, invoke interrupt() on the worker thread when the job is timeout. */
     protected boolean interruptOnTimeout = true;
-    
+
     /** Enable rendering job works monitor thread for timeout checking */
     protected boolean jobWorksMonitorEnabled = true;
-    
+
     /** Rendering job works to be monitored for timeout checking */
     protected Map<WorkItem,RenderingJobCommonjWork> jobWorksMonitored = Collections.synchronizedMap(new HashMap<WorkItem,RenderingJobCommonjWork>());
-    
+
     public CommonjWorkerMonitorImpl(WorkManager workManager)
     {
         this(workManager, true);
     }
-    
+
     public CommonjWorkerMonitorImpl(WorkManager workManager, boolean jobWorksMonitorEnabled)
     {
         this(workManager, jobWorksMonitorEnabled, true);
     }
-    
+
     public CommonjWorkerMonitorImpl(WorkManager workManager, boolean jobWorksMonitorEnabled, boolean interruptOnTimeout)
     {
         this.workManager = workManager;
         this.jobWorksMonitorEnabled = jobWorksMonitorEnabled;
         this.interruptOnTimeout = interruptOnTimeout;
     }
-    
+
     /** Commons logging */
     protected final static Logger log = LoggerFactory.getLogger(CommonjWorkerMonitorImpl.class);
-    
+
     /** Renering Job Timeout monitor */
     protected CommonjWorkerRenderingJobTimeoutMonitor jobMonitor = null;
-    
+
     public void start()
     {
         if (this.jobWorksMonitorEnabled)
@@ -108,7 +111,7 @@ public class CommonjWorkerMonitorImpl im
 
         jobMonitor = null;
     }
-    
+
     /**
      * Assign a job to a worker and execute it or queue the job if no
      * worker is available.
@@ -118,14 +121,14 @@ public class CommonjWorkerMonitorImpl im
     public void process(RenderingJob job)
     {
         AccessControlContext context = AccessController.getContext();
-        job.setWorkerAttribute(ACCESS_CONTROL_CONTEXT_WORKER_ATTR, context);
-        
+        job.setWorkerAttribute(RenderingJob.ACCESS_CONTROL_CONTEXT_WORKER_ATTR, context);
+
         try
         {
             RenderingJobCommonjWork jobWork = new RenderingJobCommonjWork(job);
             WorkItem workItem = this.workManager.schedule(jobWork, this);
             job.setWorkerAttribute(COMMONJ_WORK_ITEM_ATTR, workItem);
-            
+
             if (this.jobWorksMonitorEnabled)
             {
                 this.jobWorksMonitored.put(workItem, jobWork);
@@ -141,24 +144,24 @@ public class CommonjWorkerMonitorImpl im
     {
         return 0;
     }
-    
+
     /**
-     * Wait for all rendering jobs in the collection to finish successfully or otherwise. 
+     * Wait for all rendering jobs in the collection to finish successfully or otherwise.
      * @param renderingJobs the Collection of rendering job objects to wait for.
      */
     public void waitForRenderingJobs(List<RenderingJob> renderingJobs)
     {
         if (this.jobWorksMonitorEnabled)
         {
-            try 
+            try
             {
                 for (RenderingJob job : renderingJobs)
                 {
                     PortletContent portletContent = job.getPortletContent();
-                    
-                    synchronized (portletContent) 
+
+                    synchronized (portletContent)
                     {
-                        if (!portletContent.isComplete()) 
+                        if (!portletContent.isComplete())
                         {
                             portletContent.wait();
                         }
@@ -174,14 +177,14 @@ public class CommonjWorkerMonitorImpl im
         {
             // We cannot use WorkingManager#waitForAll(workitems, timeout_ms) for timeout.
             // The second argument could be either WorkManager.IMMEDIATE or WorkManager.INDEFINITE.
-            
+
             try
             {
                 if (!renderingJobs.isEmpty())
                 {
                     Object lock = new Object();
                     MonitoringJobCommonjWork monitoringWork = new MonitoringJobCommonjWork(lock, renderingJobs);
-                    
+
                     synchronized (lock)
                     {
                         this.workManager.schedule(monitoringWork, this);
@@ -195,7 +198,7 @@ public class CommonjWorkerMonitorImpl im
             }
         }
     }
-    
+
     /**
      * Returns a snapshot of the available jobs
      * @return available jobs
@@ -204,14 +207,14 @@ public class CommonjWorkerMonitorImpl im
     {
         return 0;
     }
-    
+
     public int getRunningJobsCount()
     {
         return 0;
     }
-    
+
     // commonj.work.WorkListener implementations
-    
+
     public void workAccepted(WorkEvent we)
     {
         WorkItem workItem = we.getWorkItem();
@@ -228,7 +231,7 @@ public class CommonjWorkerMonitorImpl im
         {
             log.debug("[CommonjWorkMonitorImpl] workRejected: " + workItem);
         }
-        
+
         if (this.jobWorksMonitorEnabled)
         {
             removeMonitoredJobWork(workItem);
@@ -251,18 +254,18 @@ public class CommonjWorkerMonitorImpl im
         {
             log.debug("[CommonjWorkMonitorImpl] workCompleted: " + workItem);
         }
-        
+
         if (this.jobWorksMonitorEnabled)
         {
             removeMonitoredJobWork(workItem);
         }
     }
-    
+
     protected Object removeMonitoredJobWork(WorkItem workItem)
     {
         return this.jobWorksMonitored.remove(workItem);
     }
-    
+
     class RenderingJobCommonjWork implements Work
     {
 
@@ -277,21 +280,21 @@ public class CommonjWorkerMonitorImpl im
         {
             return false;
         }
-        
+
         public void run()
         {
             if (jobWorksMonitorEnabled || interruptOnTimeout)
             {
                 this.job.setWorkerAttribute(WORKER_THREAD_ATTR, Thread.currentThread());
             }
-            
+
             this.job.run();
         }
-        
+
         public void release()
         {
         }
-        
+
         public RenderingJob getRenderingJob()
         {
             return this.job;
@@ -300,7 +303,7 @@ public class CommonjWorkerMonitorImpl im
 
     class MonitoringJobCommonjWork implements Work
     {
-        
+
         protected Object lock;
         protected List<RenderingJob> renderingJobs;
 
@@ -309,12 +312,12 @@ public class CommonjWorkerMonitorImpl im
             this.lock = lock;
             this.renderingJobs = new ArrayList<RenderingJob>(jobs);
         }
-        
+
         public boolean isDaemon()
         {
             return false;
         }
-        
+
         public void run()
         {
             try
@@ -326,22 +329,22 @@ public class CommonjWorkerMonitorImpl im
                         RenderingJob job = it.next();
                         WorkItem workItem = (WorkItem) job.getWorkerAttribute(COMMONJ_WORK_ITEM_ATTR);
                         int status = WorkEvent.WORK_ACCEPTED;
-                        
+
                         if (workItem != null)
                         {
                             status = workItem.getStatus();
                         }
-                        
+
                         boolean isTimeout = job.isTimeout();
-                        
+
                         if (isTimeout)
                         {
                             PortletContent content = job.getPortletContent();
-                            
+
                             if (interruptOnTimeout)
                             {
                                 Thread worker = (Thread) job.getWorkerAttribute(WORKER_THREAD_ATTR);
-                                
+
                                 if (worker != null)
                                 {
                                     synchronized (content)
@@ -362,13 +365,13 @@ public class CommonjWorkerMonitorImpl im
                                 }
                             }
                         }
-                        
+
                         if (status == WorkEvent.WORK_COMPLETED || status == WorkEvent.WORK_REJECTED || isTimeout)
                         {
                             it.remove();
-                        }                    
+                        }
                     }
-                    
+
                     if (!this.renderingJobs.isEmpty())
                     {
                         synchronized (this)
@@ -377,7 +380,7 @@ public class CommonjWorkerMonitorImpl im
                         }
                     }
                 }
-                
+
                 synchronized (this.lock)
                 {
                     this.lock.notify();
@@ -388,31 +391,31 @@ public class CommonjWorkerMonitorImpl im
                 log.error("Exceptiong during job timeout monitoring.", e);
             }
         }
-        
+
         public void release()
         {
         }
-        
+
     }
 
     class CommonjWorkerRenderingJobTimeoutMonitor extends Thread {
 
         long interval = 1000;
         boolean shouldRun = true;
-        
-        CommonjWorkerRenderingJobTimeoutMonitor(long interval) 
+
+        CommonjWorkerRenderingJobTimeoutMonitor(long interval)
         {
             super("CommonjWorkerRenderingJobTimeoutMonitor");
             setDaemon(true);
 
-            if (interval > 0) 
+            if (interval > 0)
             {
                 this.interval = interval;
             }
         }
         /**
          * Thread.stop() is deprecated.
-         * This method achieves the same by setting the run varaible "shouldRun" to false and interrupting the Thread, 
+         * This method achieves the same by setting the run varaible "shouldRun" to false and interrupting the Thread,
          * effectively causing the thread to shutdown correctly.
          *
          */
@@ -421,25 +424,25 @@ public class CommonjWorkerMonitorImpl im
         	shouldRun = false;
         	this.interrupt();
         }
-        
+
         public void run()
         {
             while (shouldRun)
             {
-                try 
+                try
                 {
                     List<RenderingJobCommonjWork> timeoutJobWorks = new ArrayList<RenderingJobCommonjWork>();
-                    
+
                     for (RenderingJobCommonjWork jobWork : jobWorksMonitored.values() )
                     {
                         RenderingJob job = jobWork.getRenderingJob();
-                        
+
                         if (job.isTimeout())
                         {
                             timeoutJobWorks.add(jobWork);
                         }
                     }
-                    
+
                     // Now, we can kill the timeout worker(s).
                     for (RenderingJobCommonjWork jobWork : timeoutJobWorks )
                     {
@@ -451,30 +454,30 @@ public class CommonjWorkerMonitorImpl im
                             killJobWork(jobWork);
                         }
                     }
-                } 
-                catch (Exception e) 
+                }
+                catch (Exception e)
                 {
                     log.error("Exception during job monitoring.", e);
                 }
-               
-                try 
+
+                try
                 {
-                    synchronized (this) 
+                    synchronized (this)
                     {
                         wait(this.interval);
                     }
-                } 
-                catch (InterruptedException e) 
+                }
+                catch (InterruptedException e)
                 {
                     ;
                 }
             }
         }
-        
+
         public void killJobWork(RenderingJobCommonjWork jobWork)
         {
             RenderingJob job = jobWork.getRenderingJob();
-            
+
             try
             {
                 if (log.isWarnEnabled())
@@ -485,7 +488,7 @@ public class CommonjWorkerMonitorImpl im
 
                 PortletContent content = job.getPortletContent();
                 Thread worker = (Thread) job.getWorkerAttribute(WORKER_THREAD_ATTR);
-                
+
                 if (worker != null)
                 {
                     synchronized (content)
@@ -497,15 +500,15 @@ public class CommonjWorkerMonitorImpl im
                         }
                     }
                 }
-            } 
+            }
             catch (Exception e)
             {
                 log.error("Exceptiong during job killing.", e);
-            } 
-            finally 
+            }
+            finally
             {
                 WorkItem workItem = (WorkItem) job.getWorkerAttribute(COMMONJ_WORK_ITEM_ATTR);
-                
+
                 if (workItem != null)
                 {
                     removeMonitoredJobWork(workItem);

Modified: portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java?rev=1610038&r1=1610037&r2=1610038&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java (original)
+++ portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java Sat Jul 12 20:06:36 2014
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,27 +17,32 @@
 
 package org.apache.jetspeed.aggregator.impl;
 
-import java.util.Map;
-import java.util.HashMap;
+import java.security.AccessControlContext;
+import java.security.PrivilegedAction;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 
 import javax.portlet.UnavailableException;
+import javax.security.auth.Subject;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.jetspeed.aggregator.PortletContent;
 import org.apache.jetspeed.aggregator.PortletRenderer;
 import org.apache.jetspeed.aggregator.PortletTrackingManager;
 import org.apache.jetspeed.aggregator.RenderingJob;
+import org.apache.jetspeed.container.PortletWindow;
 import org.apache.jetspeed.om.page.ContentFragment;
 import org.apache.jetspeed.om.page.Fragment;
+import org.apache.jetspeed.om.portlet.PortletDefinition;
 import org.apache.jetspeed.request.RequestContext;
+import org.apache.jetspeed.security.JSSubject;
 import org.apache.jetspeed.statistics.PortalStatistics;
+import org.apache.jetspeed.util.ServletRequestCleanupService;
 import org.apache.pluto.container.PortletContainer;
-import org.apache.jetspeed.om.portlet.PortletDefinition;
-import org.apache.jetspeed.container.PortletWindow;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * The RenderingJob is responsible for storing all necessary objets for
@@ -58,7 +63,7 @@ public class RenderingJobImpl implements
     protected PortletWindow window = null;
     protected HttpServletRequest request = null;
     protected HttpServletResponse response = null;
-    
+
     protected PortletContainer container = null;
     protected PortletRenderer renderer = null;
     protected RequestContext requestContext = null;
@@ -66,38 +71,38 @@ public class RenderingJobImpl implements
 
     protected PortletDefinition portletDefinition;
     protected PortalStatistics statistics;
-    
+
     protected int expirationCache = 0;
-    
+
     protected Map<String, Object> workerAttributes;
 
     protected boolean parallel;
 
     protected long startTimeMillis = 0;
     protected long timeout;
-    
+
     public RenderingJobImpl(PortletContainer container,
                             PortletRenderer renderer,
                             PortletDefinition portletDefinition,
-                            HttpServletRequest request, 
-                            HttpServletResponse response, 
-                            RequestContext requestContext, 
+                            HttpServletRequest request,
+                            HttpServletResponse response,
+                            RequestContext requestContext,
                             PortletWindow window,
                             PortalStatistics statistics,
                             int expirationCache)
     {
         this.container = container;
         this.renderer = renderer;
-        this.portletTracking = renderer.getPortletTrackingManager();        
+        this.portletTracking = renderer.getPortletTrackingManager();
         this.statistics = statistics;
         this.portletDefinition = portletDefinition;
         this.request = request;
         this.response = response;
-        this.requestContext = requestContext; 
+        this.requestContext = requestContext;
         this.window = window;
         this.expirationCache = expirationCache;
     }
-    
+
     public PortletRenderer getRenderer()
     {
         return renderer;
@@ -132,20 +137,21 @@ public class RenderingJobImpl implements
     }
 
     /**
-     * Checks if queue is empty, if not try to empty it by calling
-     * the WorkerMonitor. When done, pause until next scheduled scan.
+     * Job execution entry point method.
      */
     public void run()
-    {      
+    {
         parallel = true;
         boolean clearContext = requestContext.ensureThreadContext();
+
         try
         {
-            if (this.timeout > 0) 
+            if (this.timeout > 0)
             {
                 this.startTimeMillis = System.currentTimeMillis();
             }
-            execute();                     
+
+            ServletRequestCleanupService.executeNestedRenderJob(this);
         }
         finally
         {
@@ -153,34 +159,90 @@ public class RenderingJobImpl implements
             {
                 requestContext.clearThreadContext();
             }
+
             parallel = false;
+
             synchronized (window.getFragment().getPortletContent())
             {
-               if (log.isDebugEnabled()) log.debug("Notifying completion of rendering job for portlet window " + this.window.getId());                
+               if (log.isDebugEnabled())
+               {
+                   log.debug("Notifying completion of rendering job for portlet window " + this.window.getId());
+               }
+
                window.getFragment().getPortletContent().notifyAll();
             }
         }
     }
-    
+
     /**
-     * <p>
-     * execute
-     * </p>
-     *
-     * 
+     * The rendering job execution method.
+     * This method tries to find the underlying access control context, and execute it as a privileged action if found.
+     * This method is invoked back by {@link ServletRequestCleanupService} which is called in the {@link #run()} call.
      */
     public void execute()
     {
+        // We should try to retrieve the subject in context when this job is executed in a worker thread.
+        // If it is being executed in the normal http request processing thread, not in a separate worker thread,
+        // then we don't have to find the subject in context and run it with the context.
+        Subject subject = null;
+
+        // The ACCESS_CONTROL_CONTEXT_WORKER_ATTR attribute is available only when this job is executed in a worker thread.
+        AccessControlContext context = (AccessControlContext) getWorkerAttribute(ACCESS_CONTROL_CONTEXT_WORKER_ATTR);
+
+        if (context != null)
+        {
+            subject = JSSubject.getSubject(context);
+        }
+
+        // If a subject found from the the ACCESS_CONTROL_CONTEXT_WORKER_ATTR attribute from the worker executing job.
+        if (subject != null)
+        {
+            JSSubject.doAsPrivileged(subject, new PrivilegedAction<Object>()
+                {
+                    public Object run()
+                    {
+                        try
+                        {
+                            executeInternal();
+                        }
+                        catch (Throwable t)
+                        {
+                            log.error("Job execution error", t);
+                        }
+                        return null;
+                    }
+                }, context);
+        }
+        // Otherwise, just execute it without doing a privileged action.
+        else
+        {
+            try
+            {
+                executeInternal();
+            }
+            catch (Throwable t)
+            {
+                log.error("Job execution error", t);
+            }
+        }
+
+    }
+
+    /**
+     * The internal rendering job execution method called by {@link #execute()}.
+     */
+    private void executeInternal()
+    {
         long start = System.currentTimeMillis();
         ContentFragment fragment = this.window.getFragment();
-        
+
         try
         {
             if (log.isDebugEnabled())
             {
                 log.debug("Rendering OID "+this.window.getId()+" "+ this.request +" "+this.response);
             }
-            container.doRender(this.window, this.request, this.response);               
+            container.doRender(this.window, this.request, this.response);
         }
         catch (Throwable t)
         {
@@ -203,7 +265,7 @@ public class RenderingJobImpl implements
                 {
                     long end = System.currentTimeMillis();
                     boolean exceededTimeout = portletTracking.exceededTimeout(end - start, window);
-                    
+
                     if (statistics != null)
                     {
                         statistics.logPortletAccess(requestContext, fragment.getName(), PortalStatistics.HTTP_OK, end - start);
@@ -233,9 +295,9 @@ public class RenderingJobImpl implements
             }
         }
     }
- 
+
     /**
-     * 
+     *
      * <p>
      * getWindow
      * </p>
@@ -248,7 +310,7 @@ public class RenderingJobImpl implements
     }
 
     /**
-     * 
+     *
      * <p>
      * getPortletContent
      * </p>
@@ -296,7 +358,7 @@ public class RenderingJobImpl implements
         {
             this.workerAttributes = Collections.synchronizedMap(new HashMap<String, Object>());
         }
-        
+
         if (value != null)
         {
             this.workerAttributes.put(name, value);
@@ -306,19 +368,19 @@ public class RenderingJobImpl implements
             this.workerAttributes.remove(name);
         }
     }
-    
+
     public Object getWorkerAttribute(String name)
     {
         Object value = null;
-        
+
         if (this.workerAttributes != null)
         {
             value = this.workerAttributes.get(name);
         }
-        
+
         return value;
     }
-    
+
     public void removeWorkerAttribute(String name)
     {
         if (this.workerAttributes != null)

Modified: portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java?rev=1610038&r1=1610037&r2=1610038&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java (original)
+++ portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java Sat Jul 12 20:06:36 2014
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,16 +18,12 @@
 package org.apache.jetspeed.aggregator.impl;
 
 import java.security.AccessControlContext;
-import java.security.PrivilegedAction;
-
-import javax.security.auth.Subject;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.jetspeed.aggregator.RenderingJob;
 import org.apache.jetspeed.aggregator.Worker;
 import org.apache.jetspeed.aggregator.WorkerMonitor;
-import org.apache.jetspeed.security.JSSubject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Worker thread processes jobs and notify its WorkerMonitor when completed.
@@ -53,7 +49,11 @@ public class WorkerImpl extends Thread i
     /** Job to process */
     Runnable job = null;
 
-    /** Context to process job within */
+    /**
+     * Context to process job within
+     *
+     * @deprecated AccessControlContext must not be directly accessed by a worker thread.
+     */
     private AccessControlContext context = null;
 
     /** Monitor for this Worker */
@@ -109,6 +109,11 @@ public class WorkerImpl extends Thread i
 
     /**
      * Sets the job to execute in security context
+     *
+     * @deprecated Use only {@link #setJob(Runnable)} because AccessControlContext must not be directly accessed by
+     * a worker thread. Instead AccessControlContext must be accessed directly by the job implementation in order
+     * to use the AccessControlContext instance safely regardless of the physical worker thread implementation
+     * (e.g, WorkerImpl or container managed thread by commonj worker monitor).
      */
     public void setJob(Runnable job, AccessControlContext context)
     {
@@ -162,39 +167,14 @@ public class WorkerImpl extends Thread i
             if (this.job != null)
             {
                 log.debug("Processing job for window :" + ((RenderingJob)job).getWindow().getId());
-                Subject subject = null;
-                if (this.context != null)
+
+                try
                 {
-                    subject = JSSubject.getSubject(this.context);
+                    this.job.run();
                 }
-                if (subject != null)
+                catch (Throwable t)
                 {
-                    JSSubject.doAsPrivileged(subject, new PrivilegedAction<Object>()
-                        {
-                            public Object run()
-                            {
-                                try 
-                                {
-                                    WorkerImpl.this.job.run();
-                                }
-                                catch (Throwable t)
-                                {                        
-                                    log.error("Thread error", t);
-                                }
-                                return null;                    
-                            }
-                        }, this.context);
-                }
-                else
-                {
-                    try
-                    {
-                        this.job.run();
-                    }
-                    catch (Throwable t)
-                    {
-                        log.error("Thread error", t);
-                    }
+                    log.error("Thread error", t);
                 }
             }
 
@@ -210,5 +190,5 @@ public class WorkerImpl extends Thread i
     	this.running = false;
     	super.interrupt();
     }
-    
+
 }

Modified: portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerMonitorImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerMonitorImpl.java?rev=1610038&r1=1610037&r2=1610038&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerMonitorImpl.java (original)
+++ portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerMonitorImpl.java Sat Jul 12 20:06:36 2014
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,21 +20,20 @@ package org.apache.jetspeed.aggregator.i
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Stack;
-import java.util.LinkedList;
-import java.util.Collections;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.jetspeed.aggregator.PortletContent;
 import org.apache.jetspeed.aggregator.RenderingJob;
 import org.apache.jetspeed.aggregator.WorkerMonitor;
-import org.apache.jetspeed.aggregator.PortletContent;
-import org.apache.jetspeed.util.Queue;
-import org.apache.jetspeed.util.FIFOQueue;
-
 import org.apache.jetspeed.container.PortletWindow;
 import org.apache.jetspeed.container.PortletWindowID;
+import org.apache.jetspeed.util.FIFOQueue;
+import org.apache.jetspeed.util.Queue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * The WorkerMonitor is responsible for dispatching jobs to workers
@@ -49,7 +48,10 @@ import org.apache.jetspeed.container.Por
  */
 public class WorkerMonitorImpl implements WorkerMonitor
 {
-    public static final String ACCESS_CONTROL_CONTEXT_WORKER_ATTR = AccessControlContext.class.getName();
+    /**
+     * @deprecated Use {@link RenderingJob#ACCESS_CONTROL_CONTEXT_WORKER_ATTR} instead.
+     */
+    public static final String ACCESS_CONTROL_CONTEXT_WORKER_ATTR = RenderingJob.ACCESS_CONTROL_CONTEXT_WORKER_ATTR;
 
     public WorkerMonitorImpl(int minWorkers, int maxWorkers, int spareWorkers, int maxJobsPerWorker)
     {
@@ -58,7 +60,7 @@ public class WorkerMonitorImpl implement
         this.spareWorkers = spareWorkers;
         this.maxJobsPerWorker = maxJobsPerWorker;
     }
-    
+
     /** Commons logging */
     protected final static Logger log = LoggerFactory.getLogger(WorkerMonitorImpl.class);
 
@@ -67,7 +69,7 @@ public class WorkerMonitorImpl implement
 
     /** Count of running jobs **/
     protected int runningJobs = 0;
-    
+
     /** Minimum number of wokers to create */
     protected int minWorkers = 5;
 
@@ -107,14 +109,14 @@ public class WorkerMonitorImpl implement
     public void stop()
     {
         synchronized (workers)
-        {        
+        {
             for (WorkerImpl worker : new ArrayList<WorkerImpl>(workers))
             {
                 worker.interrupt();
             }
         }
         synchronized (workersMonitored)
-        {        
+        {
             for (WorkerImpl worker : new ArrayList<WorkerImpl>(workersMonitored))
             {
                 worker.interrupt();
@@ -189,8 +191,8 @@ public class WorkerMonitorImpl implement
         WorkerImpl worker = this.getWorker();
 
         AccessControlContext context = AccessController.getContext();
-        job.setWorkerAttribute(ACCESS_CONTROL_CONTEXT_WORKER_ATTR, context);
-        
+        job.setWorkerAttribute(RenderingJob.ACCESS_CONTROL_CONTEXT_WORKER_ATTR, context);
+
         if (worker==null)
         {
             queue.push(job);
@@ -201,7 +203,7 @@ public class WorkerMonitorImpl implement
             {
                 synchronized (worker)
                 {
-                    worker.setJob(job, context);
+                    worker.setJob(job);
 
                     if (job.getTimeout() > 0)
                     {
@@ -218,22 +220,22 @@ public class WorkerMonitorImpl implement
             }
         }
     }
-    
+
     /**
-     * Wait for all rendering jobs in the collection to finish successfully or otherwise. 
+     * Wait for all rendering jobs in the collection to finish successfully or otherwise.
      * @param renderingJobs the Collection of rendering job objects to wait for.
      */
     public void waitForRenderingJobs(List<RenderingJob> renderingJobs)
     {
-        try 
+        try
         {
             for (RenderingJob job : renderingJobs)
             {
                 PortletContent portletContent = job.getPortletContent();
-                
-                synchronized (portletContent) 
+
+                synchronized (portletContent)
                 {
-                    if (!portletContent.isComplete()) 
+                    if (!portletContent.isComplete())
                     {
                         portletContent.wait();
                     }
@@ -267,20 +269,19 @@ public class WorkerMonitorImpl implement
         synchronized (worker)
         {
             RenderingJob job = null;
-            
+
             if (worker.getJobCount() < this.maxJobsPerWorker)
             {
                 job = (RenderingJob) queue.pop();
-                
+
                 if (job != null)
                 {
-                    AccessControlContext context = (AccessControlContext) job.getWorkerAttribute(ACCESS_CONTROL_CONTEXT_WORKER_ATTR);
-                    worker.setJob(job, context);
+                    worker.setJob(job);
                     runningJobs--;
                     return;
                 }
             }
-            
+
             worker.setJob(null);
             worker.resetJobCount();
             runningJobs--;
@@ -301,7 +302,7 @@ public class WorkerMonitorImpl implement
     {
         return queue.size();
     }
-    
+
     /**
      * Returns a snapshot of the available jobs
      * @return available jobs
@@ -310,17 +311,17 @@ public class WorkerMonitorImpl implement
     {
         return workers.size();
     }
-    
+
     public int getRunningJobsCount()
     {
         return this.tg.activeCount();
     }
-    
+
     class RenderingJobTimeoutMonitor extends Thread
     {
         long interval = 1000;
         boolean shouldRun = true;
-        
+
         RenderingJobTimeoutMonitor(long interval)
         {
             super("RenderingJobTimeoutMonitor");
@@ -333,7 +334,7 @@ public class WorkerMonitorImpl implement
         }
         /**
          * Thread.stop() is deprecated.
-         * This method achieves the same by setting the run varaible "shouldRun" to false and interrupting the Thread, 
+         * This method achieves the same by setting the run varaible "shouldRun" to false and interrupting the Thread,
          * effectively causing the thread to shutdown correctly.
          *
          */
@@ -342,25 +343,25 @@ public class WorkerMonitorImpl implement
         	shouldRun = false;
         	this.interrupt();
         }
-        
+
         public void run()
         {
             while (shouldRun)
             {
-                try 
+                try
                 {
-                    // Because a timeout worker can be removed 
+                    // Because a timeout worker can be removed
                     // in the workersMonitored collection during iterating,
                     // copy timeout workers in the following collection to kill later.
 
                     List<WorkerImpl> timeoutWorkers = new ArrayList<WorkerImpl>();
 
-                    synchronized (workersMonitored) 
+                    synchronized (workersMonitored)
                     {
                         for (WorkerImpl worker : workersMonitored)
                         {
                             RenderingJob job = (RenderingJob) worker.getJob();
-                            
+
                             if ((null != job) && (job.isTimeout()))
                             {
                                 timeoutWorkers.add(worker);
@@ -379,21 +380,21 @@ public class WorkerMonitorImpl implement
                             killJob(worker, job);
                         }
                     }
-                } 
-                catch (Exception e) 
+                }
+                catch (Exception e)
                 {
                     log.error("Exception during job monitoring.", e);
                 }
-               
-                try 
+
+                try
                 {
-                    synchronized (this) 
+                    synchronized (this)
                     {
                         wait(this.interval);
                     }
-                }   
-                catch (InterruptedException e) 
-                {   
+                }
+                catch (InterruptedException e)
+                {
                 }
             }
         }
@@ -410,7 +411,7 @@ public class WorkerMonitorImpl implement
                 }
 
                 PortletContent content = job.getPortletContent();
-                
+
                 synchronized (content)
                 {
                     if (!content.isComplete())
@@ -419,7 +420,7 @@ public class WorkerMonitorImpl implement
                         content.wait();
                     }
                 }
-                
+
             } catch (Exception e)
             {
                 log.error("Exceptiong during job killing.", e);

Modified: portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/RenderingJob.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/RenderingJob.java?rev=1610038&r1=1610037&r2=1610038&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/RenderingJob.java (original)
+++ portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/RenderingJob.java Sat Jul 12 20:06:36 2014
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,13 +16,15 @@
  */
 package org.apache.jetspeed.aggregator;
 
+import java.security.AccessControlContext;
+
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.jetspeed.container.PortletWindow;
 import org.apache.jetspeed.om.page.ContentFragment;
-import org.apache.jetspeed.request.RequestContext;
 import org.apache.jetspeed.om.portlet.PortletDefinition;
-import org.apache.jetspeed.container.PortletWindow;
+import org.apache.jetspeed.request.RequestContext;
 
 /**
  * Worker thread processes jobs and notify its WorkerMonitor when completed.
@@ -34,11 +36,17 @@ import org.apache.jetspeed.container.Por
  */
 public interface RenderingJob extends Runnable
 {
+
+    /**
+     * Worker attribute name of AccessControlContext object in the current request processing context.
+     */
+    String ACCESS_CONTROL_CONTEXT_WORKER_ATTR = AccessControlContext.class.getName();
+
     void execute();
-    
+
     PortletRenderer getRenderer();
-    
-    PortletWindow getWindow(); 
+
+    PortletWindow getWindow();
 
     PortletContent getPortletContent();
 
@@ -47,7 +55,7 @@ public interface RenderingJob extends Ru
     long getTimeout();
 
     boolean isTimeout();
-    
+
     PortletDefinition getPortletDefinition();
 
     HttpServletRequest getRequest();
@@ -61,9 +69,9 @@ public interface RenderingJob extends Ru
     int getExpirationCache();
 
     void setWorkerAttribute(String name, Object value);
-    
+
     Object getWorkerAttribute(String name);
-    
+
     void removeWorkerAttribute(String name);
 }
 

Modified: portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/Worker.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/Worker.java?rev=1610038&r1=1610037&r2=1610038&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/Worker.java (original)
+++ portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/Worker.java Sat Jul 12 20:06:36 2014
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -26,7 +26,7 @@ import java.security.AccessControlContex
  * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
  * @version $Id: $
  */
-public interface Worker 
+public interface Worker
 {
      int getJobCount();
 
@@ -40,14 +40,19 @@ public interface Worker 
      * stop after processing its current job.
      */
      void setRunning(boolean status);
-     
+
     /**
      * Sets the moitor of this worker
      */
      void setMonitor(WorkerMonitor monitor);
-     
+
     /**
      * Sets the job to execute in security context
+     *
+     * @deprecated Use only {@link #setJob(Runnable)} because AccessControlContext must not be directly accessed by
+     * a worker thread. Instead AccessControlContext must be accessed directly by the job implementation in order
+     * to use the AccessControlContext instance safely regardless of the physical worker thread implementation
+     * (e.g, WorkerImpl or container managed thread by commonj worker monitor).
      */
      void setJob(Runnable job, AccessControlContext context);
 
@@ -60,6 +65,6 @@ public interface Worker 
      * Retrieves the job to execute
      */
      Runnable getJob();
-     
+
      void start();
 }

Modified: portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-commons/src/main/java/org/apache/jetspeed/util/ServletRequestCleanupService.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-commons/src/main/java/org/apache/jetspeed/util/ServletRequestCleanupService.java?rev=1610038&r1=1610037&r2=1610038&view=diff
==============================================================================
--- portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-commons/src/main/java/org/apache/jetspeed/util/ServletRequestCleanupService.java (original)
+++ portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-commons/src/main/java/org/apache/jetspeed/util/ServletRequestCleanupService.java Sat Jul 12 20:06:36 2014
@@ -26,6 +26,8 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.jetspeed.aggregator.RenderingJob;
+
 /**
  * @version $Id$
  *
@@ -44,12 +46,12 @@ public class ServletRequestCleanupServic
         }
         return list;
     }
-    
+
     public static void addCleanupCallback(ServletRequestCleanupCallback callback)
     {
         List<ServletRequestCleanupCallback> callbacks = getCallbacks(false);
         if (callbacks == null)
-        {            
+        {
             callbacks = getCallbacks(true);
             try
             {
@@ -64,7 +66,61 @@ public class ServletRequestCleanupServic
         }
         callbacks.add(callback);
     }
-    
+
+    public static void executeNestedRenderJob(RenderingJob job)
+    {
+        if (getCallbacks(false) == null)
+        {
+            List<ServletRequestCleanupCallback> callbacks = getCallbacks(true);
+            Throwable jobException = null;
+
+            try
+            {
+                job.execute();
+            }
+            catch (Throwable t)
+            {
+                jobException = t;
+                t.fillInStackTrace();
+            }
+
+            for (ServletRequestCleanupCallback callback : callbacks)
+            {
+                try
+                {
+                    callback.cleanup(job.getWindow().getPortletRequestContext().getServletContext(), job.getRequest(), job.getResponse());
+                }
+                catch (Throwable tc)
+                {
+                    try
+                    {
+                        JetspeedLoggerUtil.getSharedLogger(ServletRequestCleanupService.class).error("Cleanup callback execution failed", tc);
+                    }
+                    catch (Throwable tl)
+                    {
+                        // ignore
+                    }
+                }
+            }
+
+            ServletRequestCleanupService.callbacks.remove();
+
+            if (jobException != null)
+            {
+                if (jobException instanceof RuntimeException)
+                {
+                    throw (RuntimeException) jobException;
+                }
+
+                throw new RuntimeException(jobException);
+            }
+        }
+        else
+        {
+            job.execute();
+        }
+    }
+
     /**
      * Servlet Filter doFilter delegate method which will execute registered ServletRequestCleanupCallbacks
      * after the filterChain, if any.
@@ -94,7 +150,7 @@ public class ServletRequestCleanupServic
         {
             filterException = tf;
             tf.fillInStackTrace();
-        }        
+        }
         for (ServletRequestCleanupCallback callback : callbacks)
         {
             try



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org


Mime
View raw message