diff --git a/pom.xml b/pom.xml index adcba97fe..0bb53abf4 100644 --- a/pom.xml +++ b/pom.xml @@ -95,6 +95,12 @@ 3.23.1-GA true + + com.google.code.findbugs + jsr305 + 3.0.2 + true + junit diff --git a/pom4ide.xml b/pom4ide.xml index fd84125ab..b48bb166e 100644 --- a/pom4ide.xml +++ b/pom4ide.xml @@ -95,6 +95,12 @@ 3.23.1-GA true + + com.google.code.findbugs + jsr305 + 3.0.2 + true + junit diff --git a/src/main/java/com/alibaba/ttl/TransmittableThreadLocal.java b/src/main/java/com/alibaba/ttl/TransmittableThreadLocal.java index 8fe745fdc..3a30f5221 100644 --- a/src/main/java/com/alibaba/ttl/TransmittableThreadLocal.java +++ b/src/main/java/com/alibaba/ttl/TransmittableThreadLocal.java @@ -1,5 +1,7 @@ package com.alibaba.ttl; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -145,7 +147,7 @@ private static void doExecuteCallback(boolean isBefore) { /** * Debug only method! */ - static void dump(String title) { + static void dump(@Nullable String title) { if (title != null && title.length() > 0) { System.out.printf("Start TransmittableThreadLocal[%s] Dump...\n", title); } else { @@ -248,6 +250,7 @@ public static class Transmitter { * @return the captured {@link TransmittableThreadLocal} values * @since 2.3.0 */ + @Nonnull public static Object capture() { Map, Object> captured = new HashMap, Object>(); for (TransmittableThreadLocal threadLocal : holder.get().keySet()) { @@ -265,7 +268,8 @@ public static Object capture() { * @see #capture() * @since 2.3.0 */ - public static Object replay(Object captured) { + @Nonnull + public static Object replay(@Nonnull Object captured) { @SuppressWarnings("unchecked") Map, Object> capturedMap = (Map, Object>) captured; Map, Object> backup = new HashMap, Object>(); @@ -301,7 +305,7 @@ public static Object replay(Object captured) { * @param backup the backup {@link TransmittableThreadLocal} values from {@link Transmitter#replay(Object)} * @since 2.3.0 */ - public static void restore(Object backup) { + public static void restore(@Nonnull Object backup) { @SuppressWarnings("unchecked") Map, Object> backupMap = (Map, Object>) backup; // call afterExecute callback @@ -324,7 +328,7 @@ public static void restore(Object backup) { setTtlValuesTo(backupMap); } - private static void setTtlValuesTo(Map, Object> ttlValues) { + private static void setTtlValuesTo(@Nonnull Map, Object> ttlValues) { for (Map.Entry, Object> entry : ttlValues.entrySet()) { @SuppressWarnings("unchecked") TransmittableThreadLocal threadLocal = (TransmittableThreadLocal) entry.getKey(); @@ -344,7 +348,7 @@ private static void setTtlValuesTo(Map, Object> ttlV * @see #restore(Object) * @since 2.3.1 */ - public static R runSupplierWithCaptured(Object captured, Supplier bizLogic) { + public static R runSupplierWithCaptured(@Nonnull Object captured, Supplier bizLogic) { Object backup = replay(captured); try { return bizLogic.get(); diff --git a/src/main/java/com/alibaba/ttl/TtlCallable.java b/src/main/java/com/alibaba/ttl/TtlCallable.java index 01f4a7e32..09876c55a 100644 --- a/src/main/java/com/alibaba/ttl/TtlCallable.java +++ b/src/main/java/com/alibaba/ttl/TtlCallable.java @@ -1,5 +1,6 @@ package com.alibaba.ttl; +import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -31,7 +32,7 @@ public final class TtlCallable implements Callable { private final Callable callable; private final boolean releaseTtlValueReferenceAfterCall; - private TtlCallable(Callable callable, boolean releaseTtlValueReferenceAfterCall) { + private TtlCallable(@Nonnull Callable callable, boolean releaseTtlValueReferenceAfterCall) { this.capturedRef = new AtomicReference(capture()); this.callable = callable; this.releaseTtlValueReferenceAfterCall = releaseTtlValueReferenceAfterCall; @@ -55,6 +56,7 @@ public V call() throws Exception { } } + @Nonnull public Callable getCallable() { return callable; } diff --git a/src/main/java/com/alibaba/ttl/TtlRunnable.java b/src/main/java/com/alibaba/ttl/TtlRunnable.java index f718b6790..3132f2f35 100644 --- a/src/main/java/com/alibaba/ttl/TtlRunnable.java +++ b/src/main/java/com/alibaba/ttl/TtlRunnable.java @@ -1,5 +1,7 @@ package com.alibaba.ttl; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -28,7 +30,7 @@ public final class TtlRunnable implements Runnable { private final Runnable runnable; private final boolean releaseTtlValueReferenceAfterRun; - private TtlRunnable(Runnable runnable, boolean releaseTtlValueReferenceAfterRun) { + private TtlRunnable(@Nonnull Runnable runnable, boolean releaseTtlValueReferenceAfterRun) { this.capturedRef = new AtomicReference(capture()); this.runnable = runnable; this.releaseTtlValueReferenceAfterRun = releaseTtlValueReferenceAfterRun; @@ -55,6 +57,7 @@ public void run() { /** * return original/unwrapped {@link Runnable}. */ + @Nonnull public Runnable getRunnable() { return runnable; } @@ -86,7 +89,8 @@ public String toString() { * @return Wrapped {@link Runnable} * @throws IllegalStateException when input is {@link TtlRunnable} already. */ - public static TtlRunnable get(Runnable runnable) { + @Nullable + public static TtlRunnable get(@Nullable Runnable runnable) { return get(runnable, false, false); } @@ -98,7 +102,8 @@ public static TtlRunnable get(Runnable runnable) { * @return Wrapped {@link Runnable} * @throws IllegalStateException when input is {@link TtlRunnable} already. */ - public static TtlRunnable get(Runnable runnable, boolean releaseTtlValueReferenceAfterRun) { + @Nullable + public static TtlRunnable get(@Nullable Runnable runnable, boolean releaseTtlValueReferenceAfterRun) { return get(runnable, releaseTtlValueReferenceAfterRun, false); } @@ -113,7 +118,8 @@ public static TtlRunnable get(Runnable runnable, boolean releaseTtlValueReferenc * @return Wrapped {@link Runnable} * @throws IllegalStateException when input is {@link TtlRunnable} already and not idempotent. */ - public static TtlRunnable get(Runnable runnable, boolean releaseTtlValueReferenceAfterRun, boolean idempotent) { + @Nullable + public static TtlRunnable get(@Nullable Runnable runnable, boolean releaseTtlValueReferenceAfterRun, boolean idempotent) { if (null == runnable) { return null; } @@ -136,7 +142,8 @@ public static TtlRunnable get(Runnable runnable, boolean releaseTtlValueReferenc * @return wrapped tasks * @throws IllegalStateException when input is {@link TtlRunnable} already. */ - public static List gets(Collection tasks) { + @Nonnull + public static List gets(@Nullable Collection tasks) { return gets(tasks, false, false); } @@ -148,7 +155,8 @@ public static List gets(Collection tasks) { * @return wrapped tasks * @throws IllegalStateException when input is {@link TtlRunnable} already. */ - public static List gets(Collection tasks, boolean releaseTtlValueReferenceAfterRun) { + @Nonnull + public static List gets(@Nullable Collection tasks, boolean releaseTtlValueReferenceAfterRun) { return gets(tasks, releaseTtlValueReferenceAfterRun, false); } @@ -163,7 +171,8 @@ public static List gets(Collection tasks, boole * @return wrapped tasks * @throws IllegalStateException when input is {@link TtlRunnable} already and not idempotent. */ - public static List gets(Collection tasks, boolean releaseTtlValueReferenceAfterRun, boolean idempotent) { + @Nonnull + public static List gets(@Nullable Collection tasks, boolean releaseTtlValueReferenceAfterRun, boolean idempotent) { if (null == tasks) { return Collections.emptyList(); } diff --git a/src/main/java/com/alibaba/ttl/threadpool/ExecutorServiceTtlWrapper.java b/src/main/java/com/alibaba/ttl/threadpool/ExecutorServiceTtlWrapper.java index 881adb62e..554843873 100644 --- a/src/main/java/com/alibaba/ttl/threadpool/ExecutorServiceTtlWrapper.java +++ b/src/main/java/com/alibaba/ttl/threadpool/ExecutorServiceTtlWrapper.java @@ -4,6 +4,7 @@ import com.alibaba.ttl.TtlCallable; import com.alibaba.ttl.TtlRunnable; +import javax.annotation.Nonnull; import java.util.Collection; import java.util.List; import java.util.concurrent.*; @@ -19,7 +20,7 @@ class ExecutorServiceTtlWrapper extends ExecutorTtlWrapper implements ExecutorService { private final ExecutorService executorService; - ExecutorServiceTtlWrapper(ExecutorService executorService) { + ExecutorServiceTtlWrapper(@Nonnull ExecutorService executorService) { super(executorService); this.executorService = executorService; } @@ -84,6 +85,7 @@ public T invokeAny(Collection> tasks, long timeout, Ti return executorService.invokeAny(TtlCallable.gets(tasks), timeout, unit); } + @Nonnull @Override public ExecutorService unwrap() { return executorService; diff --git a/src/main/java/com/alibaba/ttl/threadpool/ExecutorTtlWrapper.java b/src/main/java/com/alibaba/ttl/threadpool/ExecutorTtlWrapper.java index d926925c6..7244077bb 100644 --- a/src/main/java/com/alibaba/ttl/threadpool/ExecutorTtlWrapper.java +++ b/src/main/java/com/alibaba/ttl/threadpool/ExecutorTtlWrapper.java @@ -3,6 +3,7 @@ import com.alibaba.ttl.TransmittableThreadLocal; import com.alibaba.ttl.TtlRunnable; +import javax.annotation.Nonnull; import java.util.concurrent.Executor; /** @@ -16,7 +17,7 @@ class ExecutorTtlWrapper implements Executor { private final Executor executor; - ExecutorTtlWrapper(Executor executor) { + ExecutorTtlWrapper(@Nonnull Executor executor) { this.executor = executor; } @@ -25,6 +26,7 @@ public void execute(Runnable command) { executor.execute(TtlRunnable.get(command)); } + @Nonnull public Executor unwrap() { return executor; } diff --git a/src/main/java/com/alibaba/ttl/threadpool/ScheduledExecutorServiceTtlWrapper.java b/src/main/java/com/alibaba/ttl/threadpool/ScheduledExecutorServiceTtlWrapper.java index 6c2641ca7..eca56634f 100644 --- a/src/main/java/com/alibaba/ttl/threadpool/ScheduledExecutorServiceTtlWrapper.java +++ b/src/main/java/com/alibaba/ttl/threadpool/ScheduledExecutorServiceTtlWrapper.java @@ -4,6 +4,7 @@ import com.alibaba.ttl.TtlCallable; import com.alibaba.ttl.TtlRunnable; +import javax.annotation.Nonnull; import java.util.concurrent.*; /** @@ -17,7 +18,7 @@ class ScheduledExecutorServiceTtlWrapper extends ExecutorServiceTtlWrapper implements ScheduledExecutorService { final ScheduledExecutorService scheduledExecutorService; - public ScheduledExecutorServiceTtlWrapper(ScheduledExecutorService scheduledExecutorService) { + public ScheduledExecutorServiceTtlWrapper(@Nonnull ScheduledExecutorService scheduledExecutorService) { super(scheduledExecutorService); this.scheduledExecutorService = scheduledExecutorService; } @@ -43,6 +44,7 @@ public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialD } @Override + @Nonnull public ScheduledExecutorService unwrap() { return scheduledExecutorService; } diff --git a/src/main/java/com/alibaba/ttl/threadpool/TtlExecutors.java b/src/main/java/com/alibaba/ttl/threadpool/TtlExecutors.java index d82b689c8..4c0e9ed8a 100644 --- a/src/main/java/com/alibaba/ttl/threadpool/TtlExecutors.java +++ b/src/main/java/com/alibaba/ttl/threadpool/TtlExecutors.java @@ -2,6 +2,7 @@ import com.alibaba.ttl.TransmittableThreadLocal; +import javax.annotation.Nullable; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; @@ -25,7 +26,8 @@ public final class TtlExecutors { * transmit the {@link TransmittableThreadLocal} from the task submit time of {@link Runnable} * to the execution time of {@link Runnable}. */ - public static Executor getTtlExecutor(Executor executor) { + @Nullable + public static Executor getTtlExecutor(@Nullable Executor executor) { if (null == executor || executor instanceof ExecutorTtlWrapper) { return executor; } @@ -37,7 +39,8 @@ public static Executor getTtlExecutor(Executor executor) { * transmit the {@link TransmittableThreadLocal} from the task submit time of {@link Runnable} or {@link java.util.concurrent.Callable} * to the execution time of {@link Runnable} or {@link java.util.concurrent.Callable}. */ - public static ExecutorService getTtlExecutorService(ExecutorService executorService) { + @Nullable + public static ExecutorService getTtlExecutorService(@Nullable ExecutorService executorService) { if (executorService == null || executorService instanceof ExecutorServiceTtlWrapper) { return executorService; } @@ -49,7 +52,8 @@ public static ExecutorService getTtlExecutorService(ExecutorService executorServ * transmit the {@link TransmittableThreadLocal} from the task submit time of {@link Runnable} or {@link java.util.concurrent.Callable} * to the execution time of {@link Runnable} or {@link java.util.concurrent.Callable}. */ - public static ScheduledExecutorService getTtlScheduledExecutorService(ScheduledExecutorService scheduledExecutorService) { + @Nullable + public static ScheduledExecutorService getTtlScheduledExecutorService(@Nullable ScheduledExecutorService scheduledExecutorService) { if (scheduledExecutorService == null || scheduledExecutorService instanceof ScheduledExecutorServiceTtlWrapper) { return scheduledExecutorService; } @@ -71,7 +75,7 @@ public static ScheduledExecutorService getTtlScheduledExecutorService(ScheduledE * @see #unwrap(Executor) * @since 2.8.0 */ - public static boolean isTtlWrapper(T executor) { + public static boolean isTtlWrapper(@Nullable T executor) { return (executor instanceof ExecutorTtlWrapper); } @@ -91,8 +95,9 @@ public static boolean isTtlWrapper(T executor) { * @see #isTtlWrapper(Executor) * @since 2.8.0 */ + @Nullable @SuppressWarnings("unchecked") - public static T unwrap(T executor) { + public static T unwrap(@Nullable T executor) { if (!isTtlWrapper(executor)) return executor; return (T) ((ExecutorTtlWrapper) executor).unwrap(); diff --git a/src/test/java/com/alibaba/demo/distributed_tracer/refcount/DistributedTracerUseDemo.kt b/src/test/java/com/alibaba/demo/distributed_tracer/refcount/DistributedTracerUseDemo.kt index c57662a1e..095f3c146 100644 --- a/src/test/java/com/alibaba/demo/distributed_tracer/refcount/DistributedTracerUseDemo.kt +++ b/src/test/java/com/alibaba/demo/distributed_tracer/refcount/DistributedTracerUseDemo.kt @@ -43,11 +43,9 @@ private fun rpcInvokeIn() { decreaseSpanIdRefCount() } -private val executorService = TtlExecutors.getTtlExecutorService( - Executors.newFixedThreadPool(1) { r: Runnable -> - Thread(r, "Executors").apply { isDaemon = true } - } -) +private val executorService = Executors.newFixedThreadPool(1) { r: Runnable -> + Thread(r, "Executors").apply { isDaemon = true } +}.let { TtlExecutors.getTtlExecutorService(it) }!! private fun syncMethod() { // async call by TTL Executor, Test OK! diff --git a/src/test/java/com/alibaba/demo/distributed_tracer/weakref/DistributedTracerUseDemo_WeakReferenceInsteadOfRefCounter.kt b/src/test/java/com/alibaba/demo/distributed_tracer/weakref/DistributedTracerUseDemo_WeakReferenceInsteadOfRefCounter.kt index 66ee80aa6..4439a4e4b 100644 --- a/src/test/java/com/alibaba/demo/distributed_tracer/weakref/DistributedTracerUseDemo_WeakReferenceInsteadOfRefCounter.kt +++ b/src/test/java/com/alibaba/demo/distributed_tracer/weakref/DistributedTracerUseDemo_WeakReferenceInsteadOfRefCounter.kt @@ -17,7 +17,7 @@ private val executorService: ExecutorService = Executors.newFixedThreadPool(1) { // ensure threads in pool is pre-created. expandThreadPool(it) TtlExecutors.getTtlExecutorService(it) -} +}!! /** * DistributedTracer(DT) use demo. diff --git a/src/test/java/com/alibaba/ttl/TtlRunnableTest.kt b/src/test/java/com/alibaba/ttl/TtlRunnableTest.kt index 6603a2b1b..dd3404667 100644 --- a/src/test/java/com/alibaba/ttl/TtlRunnableTest.kt +++ b/src/test/java/com/alibaba/ttl/TtlRunnableTest.kt @@ -24,7 +24,7 @@ class TtlRunnableTest { val ttlInstances = createParentTtlInstances() val task = Task("1", ttlInstances) - val ttlRunnable = TtlRunnable.get(task) + val ttlRunnable = TtlRunnable.get(task)!! // create after new Task, won't see parent value in in task! createParentTtlInstancesAfterCreateChild(ttlInstances) @@ -204,7 +204,7 @@ class TtlRunnableTest { @Test fun test_get_same() { val task = Task("1") - val ttlRunnable = TtlRunnable.get(task) + val ttlRunnable = TtlRunnable.get(task)!! assertSame(task, ttlRunnable.runnable) } diff --git a/src/test/java/com/alibaba/ttl/threadpool/ScheduledExecutorServiceTtlWrapperTest.kt b/src/test/java/com/alibaba/ttl/threadpool/ScheduledExecutorServiceTtlWrapperTest.kt index 1f1e705dc..c54b159ae 100644 --- a/src/test/java/com/alibaba/ttl/threadpool/ScheduledExecutorServiceTtlWrapperTest.kt +++ b/src/test/java/com/alibaba/ttl/threadpool/ScheduledExecutorServiceTtlWrapperTest.kt @@ -235,7 +235,7 @@ class ScheduledExecutorServiceTtlWrapperTest { it.setKeepAliveTime(10, TimeUnit.SECONDS) expandThreadPool(it) TtlExecutors.getTtlScheduledExecutorService(it) - } + }!! @AfterClass @Suppress("unused")