2017-02-02 18 views
0

Я использую Java 1.8.Прокси-объект бросает NullPointerException

Вот мой интерфейс, который расширяет ExecutorService:


public interface ConsumerExecutor extends ExecutorService{ 

    boolean closed(); 

} 

Вот мой InvocationHandler класс:


public class ExecutorInvocationHandler implements InvocationHandler { 

    private boolean close = false; 
    private ExecutorService executor; 

    public ExecutorInvocationHandler(ExecutorService exec) { 
     this.executor = exec; 
    } 

    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 

     if (method.getName().equals("closed")) { 
      return closed(); 
     } else if (method.getName().equals("shutdown")) { 
      _close(); 
      executor.shutdown(); 
     } else if (method.getName().equals("shutdownNow")) { 
      _close(); 
      executor.shutdownNow(); 
     } else { 
      method.invoke(executor, args); 
     } 

     return null; 
    } 

    public synchronized void _close() { 
     close = true; 
    } 

    public synchronized boolean closed() { 
     return close; 
    } 
} 

Теперь, следующий код, работающий из теста JUnit:


     ConsumerExecutor exec = ConsumerFactory.newInstance(ExecutorInvocationHandler.class, 
       Executors.newCachedThreadPool()); 
     //do something here 
     while (!exec.isTerminated()) {//line 52 
     } 
     //do soemthing 

выбрасывает это исключение:


java.lang.NullPointerException 
    at com.sun.proxy.$Proxy3.isTerminated(Unknown Source) 
    at test.de.edigrid.util.upgrade_test.tasks.ContextsCollectorTest.collectorTest(ContextsCollectorTest.java:52) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189) 
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165) 
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85) 
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115) 
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75) 

прокси фабричный метод здесь:


    public static ConsumerExecutor newInstance(Class clazz, ExecutorService exec) { 
     if (clazz == ExecutorInvocationHandler.class) { 
      return (ConsumerExecutor) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), 
        new Class[] { ConsumerExecutor.class }, new ExecutorInvocationHandler(exec)); 
     } 
     return null; 
    } 

Может кто-нибудь дать мне подсказку, почему это исключение?

ответ

0

Проблема была связана с возвратом функции. Я забыл поставить method.invoke(...) после заявления return. Это должно было быть примерно так:


    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 

     if (method.getName().equals("closed")) { 
      return closed(); 
     } else if (method.getName().equals("shutdown")) { 
      _close(); 
      executor.shutdown(); 
     } else if (method.getName().equals("shutdownNow")) { 
      _close(); 
      return executor.shutdownNow(); 
     } else { 
      return method.invoke(executor, args); 
     } 

     return null; 
    }