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(