package com.proofpoint.concurrent;

import com.google.common.annotations.Beta;
import com.proofpoint.units.Duration;
import org.weakref.jmx.Managed;

import java.util.concurrent.ThreadPoolExecutor;

import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.TimeUnit.NANOSECONDS;

@Beta
public class ThreadPoolExecutorMBean
{
    private final ThreadPoolExecutor threadPoolExecutor;

    public ThreadPoolExecutorMBean(ThreadPoolExecutor threadPoolExecutor)
    {
        this.threadPoolExecutor = threadPoolExecutor;
    }

    @Managed
    public boolean isShutdown()
    {
        return threadPoolExecutor.isShutdown();
    }

    @Managed
    public boolean isTerminating()
    {
        return threadPoolExecutor.isTerminating();
    }

    @Managed
    public boolean isTerminated()
    {
        return threadPoolExecutor.isTerminated();
    }

    @Managed
    public String getRejectedExecutionHandler()
    {
        return threadPoolExecutor.getRejectedExecutionHandler().getClass().getName();
    }

    @Managed
    public int getCorePoolSize()
    {
        return threadPoolExecutor.getCorePoolSize();
    }

    @Managed
    public void setCorePoolSize(int corePoolSize)
    {
        threadPoolExecutor.setCorePoolSize(corePoolSize);
    }

    @Managed
    public int getMaximumPoolSize()
    {
        return threadPoolExecutor.getMaximumPoolSize();
    }

    @Managed
    public void setMaximumPoolSize(int maximumPoolSize)
    {
        threadPoolExecutor.setMaximumPoolSize(maximumPoolSize);
    }

    @Managed
    public int getPoolSize()
    {
        return threadPoolExecutor.getPoolSize();
    }

    @Managed
    public int getActiveCount()
    {
        return threadPoolExecutor.getActiveCount();
    }

    @Managed
    public int getLargestPoolSize()
    {
        return threadPoolExecutor.getLargestPoolSize();
    }

    @Managed
    public String getKeepAliveTime()
    {
        return new Duration(threadPoolExecutor.getKeepAliveTime(NANOSECONDS), NANOSECONDS)
                .convertToMostSuccinctTimeUnit()
                .toString();
    }

    @Managed
    public void setKeepAliveTime(String duration)
    {
        checkNotNull(duration, "duration is null");
        threadPoolExecutor.setKeepAliveTime(Duration.valueOf(duration).roundTo(NANOSECONDS), NANOSECONDS);
    }

    @Managed
    public boolean isAllowCoreThreadTimeOut()
    {
        return threadPoolExecutor.allowsCoreThreadTimeOut();
    }

    @Managed
    public void setAllowCoreThreadTimeOut(boolean allowsCoreThreadTimeOut)
    {
        threadPoolExecutor.allowCoreThreadTimeOut(allowsCoreThreadTimeOut);
    }

    @Managed
    public long getTaskCount()
    {
        return threadPoolExecutor.getTaskCount();
    }

    @Managed
    public long getCompletedTaskCount()
    {
        return threadPoolExecutor.getCompletedTaskCount();
    }

    @Managed
    public int getQueuedTaskCount()
    {
        return threadPoolExecutor.getQueue().size();
    }
}

@@ -532,16 +532,29 @@
 cutor = 
+checkNotNull(
 threadPo
@@ -563,16 +563,47 @@
 Executor
+, %22threadPoolExecutor is null%22)
 ;%0A    %7D%0A

Add null check to ThreadPoolExecutorMBean