7
votes

Comment ré-jeter une exception dans AspectJ autour de conseiller

J'ai des méthodes qui jettent une exception à une exception et je souhaite utiliser AspectJ autour de vous conseiller pour calculer le temps d'exécution et si une exception est lancée et de vous connecter à un journal des erreurs et de continuer le flux en rétablissant l'exception.

J'ai essayé d'y parvenir en suivant, mais Eclipse dit "Type d'exception non confondu". P>

Code - contre lequel AspectJ est utilisé: - P>

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;
}
}


0 commentaires

3 Réponses :


6
votes

Je crains que vous ne puissiez pas écrire des conseils pour lancer des exceptions qui ne sont pas déclarées à être jetées au point de jointure assorti. Per: http://www.eclipse.org/aspectj/doc /Releed/Progguide/semantics-advice.html : "Une déclaration de conseil doit inclure une clause de lancers énumérant les exceptions vérifies que le corps peut lancer. Cette liste des exceptions vérifiées doit être compatible avec chaque point de jointure cible de l'avis ou une erreur est signalée par le compilateur."

Il y a Discussion sur la liste de diffusion de la LOPEJ sur l'amélioration de cette situation - voir les threads comme celui-ci: http://dev.eclipse.org/mhonarc/lists/aspecj-dev/msg01412.html

Mais essentiellement ce que vous devrez faire est des conseils différents pour chaque variante de déclaration d'exception. Par exemple: xxx

qui conseille partout qui a ces 3 exceptions.


0 commentaires

12
votes

Vous pouvez éviter de saisir les exceptions et utilisez simplement un blocage / enfin sans capture. Et si vous avez vraiment besoin de vous connecter à l'exception, vous pouvez utiliser un conseil après avoir lancé un conseil, comme celui-ci:

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 commentaires

3
votes

Il y a une solution de contournement "laide" - je les ai trouvées dans Spring4 AbstractTransactionAspect Code>

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);
    }
}


0 commentaires