2012-04-27 11 views
5

いくつかの例外をスローするメソッドがあります。実行時間を計算したり、例外がスローされたり、エラーログにログインして、例外を再スローすることによってフローします。アドバイスを使用してAspectJで例外を再スローする方法

私はこれを次のように実行しようとしましたが、eclipseは "未処理の例外タイプ"と言います。

者コード-に対してAspectJの使用にある: -

public interface Iface { 
    public void reload() throws TException; 

    public TUser getUserFromUserId(int userId, String serverId) throws ResumeNotFoundException, TException; 

    public TUser getUserFromUsername(String username, String serverId) throws ResumeNotFoundException, TException; 

    public TResume getPartialActiveProfileFromUserId(int userId, int sectionsBitField, String serverId) throws ResumeNotFoundException, UserNotFoundException; 

    public TResume getPartialActiveProfileFromUsername(String username, int sectionsBitField, String serverId) throws ResumeNotFoundException, UserNotFoundException, TException; 
} 

コードにAspectJ: -

public aspect AspectServerLog { 

public static final Logger ERR_LOG = LoggerFactory.getLogger("error"); 

Object around() : call (* com.abc.Iface.* (..)) { 
    Object ret; 
    Throwable ex = null; 

    StopWatch watch = new Slf4JStopWatch(); 

    try { 
    ret = proceed(); 
    }catch (UserNotFoundException e) { 
    ex = e ; 
    throw e ; 
    } catch (ResumeNotFoundException e) { 
    ex = e ; 
    throw e ; 
    } catch (Throwable e) { 
    ex = e ; 
    throw new RuntimeException(e); 
    }finally{ 

    watch.stop(thisJoinPoint.toShortString()); 

    if(ex!=null){ 
     StringBuilder mesg = new StringBuilder("Exception in "); 
     mesg.append(thisJoinPoint.toShortString()).append('('); 
     for(Object o : thisJoinPoint.getArgs()) { 
     mesg.append(o).append(','); 
     } 
     mesg.append(')'); 

     ERR_LOG.error(mesg.toString(), ex); 
     numEx++; 
    } 

    } 
return ret; 
} 
} 

このAspectJのが動作しない理由を助けてください。

答えて

10

例外をキャッチするのを避けることができ、キャッチなしでtry/finallyブロックを使用することができます。 そして、あなたは本当にこのようなあなたがアドバイスを投げた後、使用することができます例外をログに記録する必要がある場合:「醜い」の回避策はあり

public aspect AspectServerLog { 

    public static final Logger ERR_LOG = LoggerFactory.getLogger("error"); 

    Object around() : call (* com.abc.Iface.* (..)) { 

     StopWatch watch = new Slf4JStopWatch(); 

     try { 
      return proceed(); 
     } finally { 
      watch.stop(thisJoinPoint.toShortString()); 
     } 
    } 

    after() throwing (Exception ex) : call (* com.abc.Iface.* (..)) { 
     StringBuilder mesg = new StringBuilder("Exception in "); 
     mesg.append(thisJoinPoint.toShortString()).append('('); 
     for (Object o : thisJoinPoint.getArgs()) { 
      mesg.append(o).append(','); 
     } 
     mesg.append(')'); 

     ERR_LOG.error(mesg.toString(), ex); 
    } 

} 
+0

おかげでそれらを見つけ、これは素晴らしい簡単な解決策です。 –

6

マッチしたジョインポイントでスローされると宣言されていない例外をスローするためのアドバイスを書くことはできません。 Per:http://www.eclipse.org/aspectj/doc/released/progguide/semantics-advice.html: "アドバイス宣言には、ボディがスローする可能性のある例外をリストするthrows節を含める必要があります。このチェック例外のリストは、アドバイスの各ターゲットジョインポイントと互換性がなければなりません。 http://dev.eclipse.org/mhonarc/lists/aspectj-dev/msg01412.html

が、基本的に何を行う必要がありますが、例外宣言の各バリエーションごとに異なるアドバイスです:このようなスレッドを参照してください -

このような状況を改善する程度AspectJのメーリングリストでの議論がなされてきました。例:

Object around() throws ResumeServiceException, ResumeNotFoundException, TException: 
    call (* Iface.* (..) throws ResumeServiceException, ResumeNotFoundException, TException) { 

これらの3つの例外を除いてすべてのアドバイスを行います。

1

- 私はSpring4 AbstractTransactionAspect

Object around(...): ... { 
    try { 
     return proceed(...); 
    } 
    catch (RuntimeException ex) { 
     throw ex; 
    } 
    catch (Error err) { 
     throw err; 
    } 
    catch (Throwable thr) { 
     Rethrower.rethrow(thr); 
     throw new IllegalStateException("Should never get here", thr); 
    } 
} 

/** 
* Ugly but safe workaround: We need to be able to propagate checked exceptions, 
* despite AspectJ around advice supporting specifically declared exceptions only. 
*/ 
private static class Rethrower { 

    public static void rethrow(final Throwable exception) { 
     class CheckedExceptionRethrower<T extends Throwable> { 
      @SuppressWarnings("unchecked") 
      private void rethrow(Throwable exception) throws T { 
       throw (T) exception; 
      } 
     } 
     new CheckedExceptionRethrower<RuntimeException>().rethrow(exception); 
    } 
} 
関連する問題