Defensively use setRemoveOnCancelPolicy for JDK 6 compatibility

Issue: SPR-12238
This commit is contained in:
Juergen Hoeller 2014-09-25 01:24:13 +02:00
parent e52f041a78
commit e003d21726
2 changed files with 36 additions and 10 deletions

View File

@ -28,6 +28,7 @@ import org.springframework.lang.UsesJava7;
import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable; import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable;
import org.springframework.scheduling.support.TaskUtils; import org.springframework.scheduling.support.TaskUtils;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
/** /**
@ -67,9 +68,14 @@ import org.springframework.util.ObjectUtils;
public class ScheduledExecutorFactoryBean extends ExecutorConfigurationSupport public class ScheduledExecutorFactoryBean extends ExecutorConfigurationSupport
implements FactoryBean<ScheduledExecutorService> { implements FactoryBean<ScheduledExecutorService> {
// ScheduledThreadPoolExecutor.setRemoveOnCancelPolicy(boolean) only available on JDK 1.7+
private static final boolean setRemoveOnCancelPolicyAvailable =
ClassUtils.hasMethod(ScheduledThreadPoolExecutor.class, "setRemoveOnCancelPolicy", boolean.class);
private int poolSize = 1; private int poolSize = 1;
private Boolean removeOnCancelPolicy; private boolean removeOnCancelPolicy;
private ScheduledExecutorTask[] scheduledExecutorTasks; private ScheduledExecutorTask[] scheduledExecutorTasks;
@ -143,8 +149,13 @@ public class ScheduledExecutorFactoryBean extends ExecutorConfigurationSupport
ScheduledExecutorService executor = ScheduledExecutorService executor =
createExecutor(this.poolSize, threadFactory, rejectedExecutionHandler); createExecutor(this.poolSize, threadFactory, rejectedExecutionHandler);
if (executor instanceof ScheduledThreadPoolExecutor && this.removeOnCancelPolicy != null) { if (this.removeOnCancelPolicy) {
((ScheduledThreadPoolExecutor) executor).setRemoveOnCancelPolicy(this.removeOnCancelPolicy); if (setRemoveOnCancelPolicyAvailable && executor instanceof ScheduledThreadPoolExecutor) {
((ScheduledThreadPoolExecutor) executor).setRemoveOnCancelPolicy(true);
}
else {
logger.info("Could not apply remove-on-cancel policy - not a Java 7+ ScheduledThreadPoolExecutor");
}
} }
// Register specified ScheduledExecutorTasks, if necessary. // Register specified ScheduledExecutorTasks, if necessary.
@ -216,6 +227,7 @@ public class ScheduledExecutorFactoryBean extends ExecutorConfigurationSupport
new DelegatingErrorHandlingRunnable(task.getRunnable(), TaskUtils.LOG_AND_PROPAGATE_ERROR_HANDLER)); new DelegatingErrorHandlingRunnable(task.getRunnable(), TaskUtils.LOG_AND_PROPAGATE_ERROR_HANDLER));
} }
@Override @Override
public ScheduledExecutorService getObject() { public ScheduledExecutorService getObject() {
return this.exposedExecutor; return this.exposedExecutor;

View File

@ -37,6 +37,7 @@ import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.Trigger; import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.support.TaskUtils; import org.springframework.scheduling.support.TaskUtils;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ErrorHandler; import org.springframework.util.ErrorHandler;
import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureTask; import org.springframework.util.concurrent.ListenableFutureTask;
@ -57,9 +58,14 @@ import org.springframework.util.concurrent.ListenableFutureTask;
public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
implements AsyncListenableTaskExecutor, SchedulingTaskExecutor, TaskScheduler { implements AsyncListenableTaskExecutor, SchedulingTaskExecutor, TaskScheduler {
// ScheduledThreadPoolExecutor.setRemoveOnCancelPolicy(boolean) only available on JDK 1.7+
private static final boolean setRemoveOnCancelPolicyAvailable =
ClassUtils.hasMethod(ScheduledThreadPoolExecutor.class, "setRemoveOnCancelPolicy", boolean.class);
private volatile int poolSize = 1; private volatile int poolSize = 1;
private volatile Boolean removeOnCancelPolicy; private volatile boolean removeOnCancelPolicy;
private volatile ScheduledExecutorService scheduledExecutor; private volatile ScheduledExecutorService scheduledExecutor;
@ -87,19 +93,22 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
@UsesJava7 @UsesJava7
public void setRemoveOnCancelPolicy(boolean removeOnCancelPolicy) { public void setRemoveOnCancelPolicy(boolean removeOnCancelPolicy) {
this.removeOnCancelPolicy = removeOnCancelPolicy; this.removeOnCancelPolicy = removeOnCancelPolicy;
if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) { if (setRemoveOnCancelPolicyAvailable && this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) {
((ScheduledThreadPoolExecutor) this.scheduledExecutor).setRemoveOnCancelPolicy(removeOnCancelPolicy); ((ScheduledThreadPoolExecutor) this.scheduledExecutor).setRemoveOnCancelPolicy(removeOnCancelPolicy);
} }
else if (removeOnCancelPolicy && this.scheduledExecutor != null) {
logger.info("Could not apply remove-on-cancel policy - not a Java 7+ ScheduledThreadPoolExecutor");
}
} }
/** /**
* Set a custom {@link ErrorHandler} strategy. * Set a custom {@link ErrorHandler} strategy.
*/ */
public void setErrorHandler(ErrorHandler errorHandler) { public void setErrorHandler(ErrorHandler errorHandler) {
Assert.notNull(errorHandler, "'errorHandler' must not be null");
this.errorHandler = errorHandler; this.errorHandler = errorHandler;
} }
@UsesJava7 @UsesJava7
@Override @Override
protected ExecutorService initializeExecutor( protected ExecutorService initializeExecutor(
@ -107,8 +116,13 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
this.scheduledExecutor = createExecutor(this.poolSize, threadFactory, rejectedExecutionHandler); this.scheduledExecutor = createExecutor(this.poolSize, threadFactory, rejectedExecutionHandler);
if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor && this.removeOnCancelPolicy != null) { if (this.removeOnCancelPolicy) {
((ScheduledThreadPoolExecutor) this.scheduledExecutor).setRemoveOnCancelPolicy(this.removeOnCancelPolicy); if (setRemoveOnCancelPolicyAvailable && this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) {
((ScheduledThreadPoolExecutor) this.scheduledExecutor).setRemoveOnCancelPolicy(true);
}
else {
logger.info("Could not apply remove-on-cancel policy - not a Java 7+ ScheduledThreadPoolExecutor");
}
} }
return this.scheduledExecutor; return this.scheduledExecutor;
@ -175,8 +189,8 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
@UsesJava7 @UsesJava7
public boolean isRemoveOnCancelPolicy() { public boolean isRemoveOnCancelPolicy() {
if (this.scheduledExecutor == null) { if (this.scheduledExecutor == null) {
// Not initialized yet: return false (the default of the executor) // Not initialized yet: return our setting for the time being.
return false; return (setRemoveOnCancelPolicyAvailable && this.removeOnCancelPolicy);
} }
return getScheduledThreadPoolExecutor().getRemoveOnCancelPolicy(); return getScheduledThreadPoolExecutor().getRemoveOnCancelPolicy();
} }