ThreadGroup の uncaughtException をAOP

サブスレッドの例外を捕捉することができる ThreadGroup uncaughtExceptionインターセプトしたら、
try~catch で記述しない例外捕捉しないまたは、throw された例外を共通で記述できるのでは?
と思い立って書いてみる。

ThreadGroup の uncaughtException をインターセプトするクラス
MethodInvocation で org.aopalliance.intercept.Joinpoint の Object  proceed() を
実行しないで抽象メソッド void catchException(Thread thread,Throwable th)
を実行する。

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
 * OptionalThreagGroupInterceptor.java
 */

public abstract class OptionalThreagGroupInterceptor implements MethodInterceptor{

   public abstract void catchException(Thread thread,Throwable th);

   @Override
   public Object invoke(MethodInvocation m) throws Throwable{
      if (m.getMethod().getName().equals("uncaughtException")){
         Object[] args = m.getArguments();
         catchException*1;
               try{
binder().bind(ThreadGroup.class).toConstructor(ThreadGroup.class.getConstructor(String.class));
               }catch(Exception e){
               }
               binder().bindInterceptor(new AbstractMatcher<Class>(){
                  @Override
                  public boolean matches(Class cls){
                     return cls.equals(ThreadGroup.class);
                  }
               }

               ,new AbstractMatcher<Method>(){
                  @Override
                  public boolean matches(Method m){
                     return m.getName().equals("uncaughtException");
                  }
               }

               ,interceptor
            );
         }
      }).getInstance(ThreadGroup.class);
   }
}


実行のサンプルは、、、

ThreadGroup group = OptionalThreadGroup.get(new OptionalThreagGroupInterceptor(){
   @Override
   public void catchException(Thread thread,Throwable th){

      // サブスレッドで捕捉しない例外を捕捉した結果の処理
      System.out.println("Thread name = "+thread.getName());
      System.out.println("Throwable instance = "+th.getClass().getName());
      System.out.println("Throwable message = "+th.getMessage());

   }
   @Override
   public String getGroupName(){
      return "sample";
   }
}
);
Thread th = new Thread(group,new SampleThread());
th.start();

または、OptionalThreagGroupInterceptor 実装を共通のインタセプタを用意して

スレッドを実行するクラスで

@Inject OptionalThreagGroupInterceptor intercepter;

public void exec(){
   ThreadGroup group = OptionalThreadGroup.get(this.intercepter);
   Thread t = new Thread(group,new SampleThread());
   t.start();
   :
}

に対して、以下のように OptionalThreagGroupInterceptor に実装をインジェクトさせる方法でも
よいかもしれない。

Injector injector = Guice.createInjector(new AbstractModule(){
   @Override
   protected void configure(){
      binder().bind(OptionalThreagGroupInterceptor.class).toInstance(new SampleInterceptor());
   }
});

*1:Thread)args[0],(Throwable)args[1]);
      }
      return null;
   }
   // ThreadGroup name
   public String getGroupName(){
      return "";
   }
}

この OptionalThreagGroupInterceptor が働く ThreadGroup を Google guice + AOP で
生成する。static メソッドで生成する。
guice 3.0 からの機能、コンストラクタ-バインドを使用することにする。
@Inject が記述されてない ThreadGroup に対して、ThreadGroup 名をインジェクトしている。
ThreadGroup 名は、OptionalThreagGroupInterceptor の抽象メソッドを実行することで生成する。

import java.lang.reflect.Method;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.matcher.AbstractMatcher;
/**
 * OptionalThreadGroup.java
 */

public final class OptionalThreadGroup{
   private OptionalThreadGroup(){}

   public static ThreadGroup get(final OptionalThreagGroupInterceptor interceptor){
      return Guice.createInjector(new AbstractModule(){
         @Override
         protected void configure(){
            binder().bind(String.class).toInstance(interceptor.getGroupName(