You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by oc...@apache.org on 2010/05/20 15:11:52 UTC
svn commit: r946618 -
/archiva/branches/archiva-1.3.x/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ArchivaStartup.java
Author: oching
Date: Thu May 20 13:11:51 2010
New Revision: 946618
URL: http://svn.apache.org/viewvc?rev=946618&view=rev
Log:
[MRM-1066] Shutdown of Tomcat causes Exception when running Archiva Project
submitted by Marcus Dimand
o kill the executors and the archiva scheduler when context is destroyed
additional changes in the patch:
o removed system.out logs
o moved out stopping of the task queue executors to its own method
Modified:
archiva/branches/archiva-1.3.x/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ArchivaStartup.java
Modified: archiva/branches/archiva-1.3.x/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ArchivaStartup.java
URL: http://svn.apache.org/viewvc/archiva/branches/archiva-1.3.x/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ArchivaStartup.java?rev=946618&r1=946617&r2=946618&view=diff
==============================================================================
--- archiva/branches/archiva-1.3.x/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ArchivaStartup.java (original)
+++ archiva/branches/archiva-1.3.x/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ArchivaStartup.java Thu May 20 13:11:51 2010
@@ -19,18 +19,27 @@ package org.apache.maven.archiva.web.sta
* under the License.
*/
+import java.lang.reflect.Field;
+
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.maven.archiva.common.ArchivaException;
import org.apache.maven.archiva.scheduled.ArchivaTaskScheduler;
+import org.apache.maven.archiva.scheduled.DefaultArchivaTaskScheduler;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.StoppingException;
+import org.codehaus.plexus.scheduler.DefaultScheduler;
import org.codehaus.plexus.spring.PlexusToSpringUtils;
+import org.codehaus.plexus.spring.PlexusWebApplicationContext;
+import org.codehaus.plexus.taskqueue.Task;
import org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor;
-import org.springframework.context.ApplicationContext;
+import org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
+import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;
+
/**
* ArchivaStartup - the startup of all archiva features in a deterministic order.
*
@@ -39,6 +48,14 @@ import org.springframework.web.context.s
public class ArchivaStartup
implements ServletContextListener
{
+ private ThreadedTaskQueueExecutor tqeDbScanning;
+
+ private ThreadedTaskQueueExecutor tqeRepoScanning;
+
+ private ThreadedTaskQueueExecutor tqeIndexing;
+
+ private ArchivaTaskScheduler taskScheduler;
+
public void contextInitialized( ServletContextEvent contextEvent )
{
WebApplicationContext wac =
@@ -48,11 +65,19 @@ public class ArchivaStartup
(SecuritySynchronization) wac.getBean( PlexusToSpringUtils.buildSpringId( SecuritySynchronization.class ) );
ResolverFactoryInit resolverFactory =
(ResolverFactoryInit) wac.getBean( PlexusToSpringUtils.buildSpringId( ResolverFactoryInit.class ) );
- ArchivaTaskScheduler taskScheduler =
+
+ taskScheduler =
(ArchivaTaskScheduler) wac.getBean( PlexusToSpringUtils.buildSpringId( ArchivaTaskScheduler.class ) );
- wac.getBean( PlexusToSpringUtils.buildSpringId( TaskQueueExecutor.class, "database-update" ) );
- wac.getBean( PlexusToSpringUtils.buildSpringId( TaskQueueExecutor.class, "repository-scanning" ) );
- wac.getBean( PlexusToSpringUtils.buildSpringId( TaskQueueExecutor.class, "indexing" ) );
+
+ tqeDbScanning =
+ (ThreadedTaskQueueExecutor) wac.getBean( PlexusToSpringUtils.buildSpringId( TaskQueueExecutor.class,
+ "database-update" ) );
+ tqeRepoScanning =
+ (ThreadedTaskQueueExecutor) wac.getBean( PlexusToSpringUtils.buildSpringId( TaskQueueExecutor.class,
+ "repository-scanning" ) );
+ tqeIndexing =
+ (ThreadedTaskQueueExecutor) wac.getBean( PlexusToSpringUtils.buildSpringId( TaskQueueExecutor.class,
+ "indexing" ) );
try
{
@@ -69,11 +94,91 @@ public class ArchivaStartup
public void contextDestroyed( ServletContextEvent contextEvent )
{
- ApplicationContext applicationContext =
+ WebApplicationContext applicationContext =
WebApplicationContextUtils.getRequiredWebApplicationContext( contextEvent.getServletContext() );
if ( applicationContext != null && applicationContext instanceof ClassPathXmlApplicationContext )
{
( (ClassPathXmlApplicationContext) applicationContext ).close();
}
+
+ if ( applicationContext != null && applicationContext instanceof PlexusWebApplicationContext )
+ {
+ // stop task queue executors
+ stopTaskQueueExecutor( tqeDbScanning );
+ stopTaskQueueExecutor( tqeRepoScanning );
+ stopTaskQueueExecutor( tqeIndexing );
+
+ // stop the DefaultArchivaTaskScheduler and its scheduler
+ if ( taskScheduler != null && taskScheduler instanceof DefaultArchivaTaskScheduler )
+ {
+ try
+ {
+ ( (DefaultArchivaTaskScheduler) taskScheduler ).stop();
+ }
+ catch ( StoppingException e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ try
+ {
+ // shutdown the scheduler, otherwise Quartz scheduler and Threads still exists
+ Field schedulerField = taskScheduler.getClass().getDeclaredField( "scheduler" );
+ schedulerField.setAccessible( true );
+
+ DefaultScheduler scheduler = (DefaultScheduler) schedulerField.get( taskScheduler );
+ scheduler.stop();
+ }
+ catch ( Exception e )
+ {
+ e.printStackTrace();
+ }
+
+ // close the application context
+ ( (PlexusWebApplicationContext) applicationContext ).close();
+ }
+ }
+
+ private void stopTaskQueueExecutor( ThreadedTaskQueueExecutor taskQueueExecutor )
+ {
+ if ( taskQueueExecutor != null )
+ {
+ Task currentTask = taskQueueExecutor.getCurrentTask();
+ if ( currentTask != null )
+ {
+ taskQueueExecutor.cancelTask( currentTask );
+ }
+
+ try
+ {
+ taskQueueExecutor.stop();
+ ExecutorService service = getExecutorServiceForTTQE( taskQueueExecutor );
+ if ( service != null )
+ {
+ service.shutdown();
+ }
+ }
+ catch ( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private ExecutorService getExecutorServiceForTTQE( ThreadedTaskQueueExecutor ttqe )
+ {
+ ExecutorService service = null;
+ try
+ {
+ Field executorServiceField = ttqe.getClass().getDeclaredField( "executorService" );
+ executorServiceField.setAccessible( true );
+ service = (ExecutorService) executorServiceField.get( ttqe );
+ }
+ catch ( Exception e )
+ {
+ e.printStackTrace();
+ }
+ return service;
}
}
Re: svn commit: r946618 - /archiva/branches/archiva-1.3.x/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ArchivaStartup.java
Posted by Brett Porter <br...@apache.org>.
On 09/06/2010, at 11:59 AM, Deng Ching wrote:
> On Wed, Jun 9, 2010 at 6:07 AM, Brett Porter <br...@apache.org> wrote:
>
>> A couple of questions:
>> - do we need to explicitly call all the stop() methods given that the
>> close() is now there? I thought that would stop all stoppables
>>
>
> That's what I thought too, but unfortunately, it doesn't. The running tasks
> were still executing as well as the schedulers even when Tomcat was
> shutdown. Before the stop() methods were added, when I ran "ps aux" after
> shutting down Tomcat, the process would keep on running until you force kill
> it.
>
>
>> - can the e.printStackTrace be changed to something else?
>>
>
> I'm not sure what else we can change it to? Log the exception instead?
true, while we could use a logger it's probably irrelevant at that point.
>
>
>>
>> Also, the code can be a bit cleaner if the fields are assigned the required
>> values from the start :) Maybe they could just be pushed into a list of
>> Stoppables that need to be stopped.
>>
>
> Ok, I'll fix this up :)
>
> Thanks,
> Deng
--
Brett Porter
brett@apache.org
http://brettporter.wordpress.com/
Re: svn commit: r946618 - /archiva/branches/archiva-1.3.x/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ArchivaStartup.java
Posted by Deng Ching <od...@gmail.com>.
On Wed, Jun 9, 2010 at 6:07 AM, Brett Porter <br...@apache.org> wrote:
> A couple of questions:
> - do we need to explicitly call all the stop() methods given that the
> close() is now there? I thought that would stop all stoppables
>
That's what I thought too, but unfortunately, it doesn't. The running tasks
were still executing as well as the schedulers even when Tomcat was
shutdown. Before the stop() methods were added, when I ran "ps aux" after
shutting down Tomcat, the process would keep on running until you force kill
it.
> - can the e.printStackTrace be changed to something else?
>
I'm not sure what else we can change it to? Log the exception instead?
>
> Also, the code can be a bit cleaner if the fields are assigned the required
> values from the start :) Maybe they could just be pushed into a list of
> Stoppables that need to be stopped.
>
Ok, I'll fix this up :)
Thanks,
Deng
Re: svn commit: r946618 - /archiva/branches/archiva-1.3.x/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ArchivaStartup.java
Posted by Brett Porter <br...@apache.org>.
A couple of questions:
- do we need to explicitly call all the stop() methods given that the close() is now there? I thought that would stop all stoppables
- can the e.printStackTrace be changed to something else?
Also, the code can be a bit cleaner if the fields are assigned the required values from the start :) Maybe they could just be pushed into a list of Stoppables that need to be stopped.
- Brett
On 20/05/2010, at 11:11 PM, oching@apache.org wrote:
> Author: oching
> Date: Thu May 20 13:11:51 2010
> New Revision: 946618
>
> URL: http://svn.apache.org/viewvc?rev=946618&view=rev
> Log:
> [MRM-1066] Shutdown of Tomcat causes Exception when running Archiva Project
> submitted by Marcus Dimand
> o kill the executors and the archiva scheduler when context is destroyed
>
> additional changes in the patch:
> o removed system.out logs
> o moved out stopping of the task queue executors to its own method
>
> Modified:
> archiva/branches/archiva-1.3.x/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ArchivaStartup.java
>
> Modified: archiva/branches/archiva-1.3.x/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ArchivaStartup.java
> URL: http://svn.apache.org/viewvc/archiva/branches/archiva-1.3.x/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ArchivaStartup.java?rev=946618&r1=946617&r2=946618&view=diff
> ==============================================================================
> --- archiva/branches/archiva-1.3.x/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ArchivaStartup.java (original)
> +++ archiva/branches/archiva-1.3.x/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ArchivaStartup.java Thu May 20 13:11:51 2010
> @@ -19,18 +19,27 @@ package org.apache.maven.archiva.web.sta
> * under the License.
> */
>
> +import java.lang.reflect.Field;
> +
> import javax.servlet.ServletContextEvent;
> import javax.servlet.ServletContextListener;
>
> import org.apache.maven.archiva.common.ArchivaException;
> import org.apache.maven.archiva.scheduled.ArchivaTaskScheduler;
> +import org.apache.maven.archiva.scheduled.DefaultArchivaTaskScheduler;
> +import org.codehaus.plexus.personality.plexus.lifecycle.phase.StoppingException;
> +import org.codehaus.plexus.scheduler.DefaultScheduler;
> import org.codehaus.plexus.spring.PlexusToSpringUtils;
> +import org.codehaus.plexus.spring.PlexusWebApplicationContext;
> +import org.codehaus.plexus.taskqueue.Task;
> import org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor;
> -import org.springframework.context.ApplicationContext;
> +import org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor;
> import org.springframework.context.support.ClassPathXmlApplicationContext;
> import org.springframework.web.context.WebApplicationContext;
> import org.springframework.web.context.support.WebApplicationContextUtils;
>
> +import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;
> +
> /**
> * ArchivaStartup - the startup of all archiva features in a deterministic order.
> *
> @@ -39,6 +48,14 @@ import org.springframework.web.context.s
> public class ArchivaStartup
> implements ServletContextListener
> {
> + private ThreadedTaskQueueExecutor tqeDbScanning;
> +
> + private ThreadedTaskQueueExecutor tqeRepoScanning;
> +
> + private ThreadedTaskQueueExecutor tqeIndexing;
> +
> + private ArchivaTaskScheduler taskScheduler;
> +
> public void contextInitialized( ServletContextEvent contextEvent )
> {
> WebApplicationContext wac =
> @@ -48,11 +65,19 @@ public class ArchivaStartup
> (SecuritySynchronization) wac.getBean( PlexusToSpringUtils.buildSpringId( SecuritySynchronization.class ) );
> ResolverFactoryInit resolverFactory =
> (ResolverFactoryInit) wac.getBean( PlexusToSpringUtils.buildSpringId( ResolverFactoryInit.class ) );
> - ArchivaTaskScheduler taskScheduler =
> +
> + taskScheduler =
> (ArchivaTaskScheduler) wac.getBean( PlexusToSpringUtils.buildSpringId( ArchivaTaskScheduler.class ) );
> - wac.getBean( PlexusToSpringUtils.buildSpringId( TaskQueueExecutor.class, "database-update" ) );
> - wac.getBean( PlexusToSpringUtils.buildSpringId( TaskQueueExecutor.class, "repository-scanning" ) );
> - wac.getBean( PlexusToSpringUtils.buildSpringId( TaskQueueExecutor.class, "indexing" ) );
> +
> + tqeDbScanning =
> + (ThreadedTaskQueueExecutor) wac.getBean( PlexusToSpringUtils.buildSpringId( TaskQueueExecutor.class,
> + "database-update" ) );
> + tqeRepoScanning =
> + (ThreadedTaskQueueExecutor) wac.getBean( PlexusToSpringUtils.buildSpringId( TaskQueueExecutor.class,
> + "repository-scanning" ) );
> + tqeIndexing =
> + (ThreadedTaskQueueExecutor) wac.getBean( PlexusToSpringUtils.buildSpringId( TaskQueueExecutor.class,
> + "indexing" ) );
>
> try
> {
> @@ -69,11 +94,91 @@ public class ArchivaStartup
>
> public void contextDestroyed( ServletContextEvent contextEvent )
> {
> - ApplicationContext applicationContext =
> + WebApplicationContext applicationContext =
> WebApplicationContextUtils.getRequiredWebApplicationContext( contextEvent.getServletContext() );
> if ( applicationContext != null && applicationContext instanceof ClassPathXmlApplicationContext )
> {
> ( (ClassPathXmlApplicationContext) applicationContext ).close();
> }
> +
> + if ( applicationContext != null && applicationContext instanceof PlexusWebApplicationContext )
> + {
> + // stop task queue executors
> + stopTaskQueueExecutor( tqeDbScanning );
> + stopTaskQueueExecutor( tqeRepoScanning );
> + stopTaskQueueExecutor( tqeIndexing );
> +
> + // stop the DefaultArchivaTaskScheduler and its scheduler
> + if ( taskScheduler != null && taskScheduler instanceof DefaultArchivaTaskScheduler )
> + {
> + try
> + {
> + ( (DefaultArchivaTaskScheduler) taskScheduler ).stop();
> + }
> + catch ( StoppingException e )
> + {
> + e.printStackTrace();
> + }
> + }
> +
> + try
> + {
> + // shutdown the scheduler, otherwise Quartz scheduler and Threads still exists
> + Field schedulerField = taskScheduler.getClass().getDeclaredField( "scheduler" );
> + schedulerField.setAccessible( true );
> +
> + DefaultScheduler scheduler = (DefaultScheduler) schedulerField.get( taskScheduler );
> + scheduler.stop();
> + }
> + catch ( Exception e )
> + {
> + e.printStackTrace();
> + }
> +
> + // close the application context
> + ( (PlexusWebApplicationContext) applicationContext ).close();
> + }
> + }
> +
> + private void stopTaskQueueExecutor( ThreadedTaskQueueExecutor taskQueueExecutor )
> + {
> + if ( taskQueueExecutor != null )
> + {
> + Task currentTask = taskQueueExecutor.getCurrentTask();
> + if ( currentTask != null )
> + {
> + taskQueueExecutor.cancelTask( currentTask );
> + }
> +
> + try
> + {
> + taskQueueExecutor.stop();
> + ExecutorService service = getExecutorServiceForTTQE( taskQueueExecutor );
> + if ( service != null )
> + {
> + service.shutdown();
> + }
> + }
> + catch ( Exception e )
> + {
> + e.printStackTrace();
> + }
> + }
> + }
> +
> + private ExecutorService getExecutorServiceForTTQE( ThreadedTaskQueueExecutor ttqe )
> + {
> + ExecutorService service = null;
> + try
> + {
> + Field executorServiceField = ttqe.getClass().getDeclaredField( "executorService" );
> + executorServiceField.setAccessible( true );
> + service = (ExecutorService) executorServiceField.get( ttqe );
> + }
> + catch ( Exception e )
> + {
> + e.printStackTrace();
> + }
> + return service;
> }
> }
>
>
--
Brett Porter
brett@apache.org
http://brettporter.wordpress.com/