Skip to content

Commit e003d21

Browse files
committed
Defensively use setRemoveOnCancelPolicy for JDK 6 compatibility
Issue: SPR-12238
1 parent e52f041 commit e003d21

File tree

2 files changed

+36
-10
lines changed

2 files changed

+36
-10
lines changed

spring-context/src/main/java/org/springframework/scheduling/concurrent/ScheduledExecutorFactoryBean.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable;
2929
import org.springframework.scheduling.support.TaskUtils;
3030
import org.springframework.util.Assert;
31+
import org.springframework.util.ClassUtils;
3132
import org.springframework.util.ObjectUtils;
3233

3334
/**
@@ -67,9 +68,14 @@
6768
public class ScheduledExecutorFactoryBean extends ExecutorConfigurationSupport
6869
implements FactoryBean<ScheduledExecutorService> {
6970

71+
// ScheduledThreadPoolExecutor.setRemoveOnCancelPolicy(boolean) only available on JDK 1.7+
72+
private static final boolean setRemoveOnCancelPolicyAvailable =
73+
ClassUtils.hasMethod(ScheduledThreadPoolExecutor.class, "setRemoveOnCancelPolicy", boolean.class);
74+
75+
7076
private int poolSize = 1;
7177

72-
private Boolean removeOnCancelPolicy;
78+
private boolean removeOnCancelPolicy;
7379

7480
private ScheduledExecutorTask[] scheduledExecutorTasks;
7581

@@ -143,8 +149,13 @@ protected ExecutorService initializeExecutor(
143149
ScheduledExecutorService executor =
144150
createExecutor(this.poolSize, threadFactory, rejectedExecutionHandler);
145151

146-
if (executor instanceof ScheduledThreadPoolExecutor && this.removeOnCancelPolicy != null) {
147-
((ScheduledThreadPoolExecutor) executor).setRemoveOnCancelPolicy(this.removeOnCancelPolicy);
152+
if (this.removeOnCancelPolicy) {
153+
if (setRemoveOnCancelPolicyAvailable && executor instanceof ScheduledThreadPoolExecutor) {
154+
((ScheduledThreadPoolExecutor) executor).setRemoveOnCancelPolicy(true);
155+
}
156+
else {
157+
logger.info("Could not apply remove-on-cancel policy - not a Java 7+ ScheduledThreadPoolExecutor");
158+
}
148159
}
149160

150161
// Register specified ScheduledExecutorTasks, if necessary.
@@ -216,6 +227,7 @@ protected Runnable getRunnableToSchedule(ScheduledExecutorTask task) {
216227
new DelegatingErrorHandlingRunnable(task.getRunnable(), TaskUtils.LOG_AND_PROPAGATE_ERROR_HANDLER));
217228
}
218229

230+
219231
@Override
220232
public ScheduledExecutorService getObject() {
221233
return this.exposedExecutor;

spring-context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.springframework.scheduling.Trigger;
3838
import org.springframework.scheduling.support.TaskUtils;
3939
import org.springframework.util.Assert;
40+
import org.springframework.util.ClassUtils;
4041
import org.springframework.util.ErrorHandler;
4142
import org.springframework.util.concurrent.ListenableFuture;
4243
import org.springframework.util.concurrent.ListenableFutureTask;
@@ -57,9 +58,14 @@
5758
public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
5859
implements AsyncListenableTaskExecutor, SchedulingTaskExecutor, TaskScheduler {
5960

61+
// ScheduledThreadPoolExecutor.setRemoveOnCancelPolicy(boolean) only available on JDK 1.7+
62+
private static final boolean setRemoveOnCancelPolicyAvailable =
63+
ClassUtils.hasMethod(ScheduledThreadPoolExecutor.class, "setRemoveOnCancelPolicy", boolean.class);
64+
65+
6066
private volatile int poolSize = 1;
6167

62-
private volatile Boolean removeOnCancelPolicy;
68+
private volatile boolean removeOnCancelPolicy;
6369

6470
private volatile ScheduledExecutorService scheduledExecutor;
6571

@@ -87,28 +93,36 @@ public void setPoolSize(int poolSize) {
8793
@UsesJava7
8894
public void setRemoveOnCancelPolicy(boolean removeOnCancelPolicy) {
8995
this.removeOnCancelPolicy = removeOnCancelPolicy;
90-
if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) {
96+
if (setRemoveOnCancelPolicyAvailable && this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) {
9197
((ScheduledThreadPoolExecutor) this.scheduledExecutor).setRemoveOnCancelPolicy(removeOnCancelPolicy);
9298
}
99+
else if (removeOnCancelPolicy && this.scheduledExecutor != null) {
100+
logger.info("Could not apply remove-on-cancel policy - not a Java 7+ ScheduledThreadPoolExecutor");
101+
}
93102
}
94103

95104
/**
96105
* Set a custom {@link ErrorHandler} strategy.
97106
*/
98107
public void setErrorHandler(ErrorHandler errorHandler) {
99-
Assert.notNull(errorHandler, "'errorHandler' must not be null");
100108
this.errorHandler = errorHandler;
101109
}
102110

111+
103112
@UsesJava7
104113
@Override
105114
protected ExecutorService initializeExecutor(
106115
ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
107116

108117
this.scheduledExecutor = createExecutor(this.poolSize, threadFactory, rejectedExecutionHandler);
109118

110-
if (this.scheduledExecutor instanceof ScheduledThreadPoolExecutor && this.removeOnCancelPolicy != null) {
111-
((ScheduledThreadPoolExecutor) this.scheduledExecutor).setRemoveOnCancelPolicy(this.removeOnCancelPolicy);
119+
if (this.removeOnCancelPolicy) {
120+
if (setRemoveOnCancelPolicyAvailable && this.scheduledExecutor instanceof ScheduledThreadPoolExecutor) {
121+
((ScheduledThreadPoolExecutor) this.scheduledExecutor).setRemoveOnCancelPolicy(true);
122+
}
123+
else {
124+
logger.info("Could not apply remove-on-cancel policy - not a Java 7+ ScheduledThreadPoolExecutor");
125+
}
112126
}
113127

114128
return this.scheduledExecutor;
@@ -175,8 +189,8 @@ public int getPoolSize() {
175189
@UsesJava7
176190
public boolean isRemoveOnCancelPolicy() {
177191
if (this.scheduledExecutor == null) {
178-
// Not initialized yet: return false (the default of the executor)
179-
return false;
192+
// Not initialized yet: return our setting for the time being.
193+
return (setRemoveOnCancelPolicyAvailable && this.removeOnCancelPolicy);
180194
}
181195
return getScheduledThreadPoolExecutor().getRemoveOnCancelPolicy();
182196
}

0 commit comments

Comments
 (0)