NoSuchMethodError aspectOf() во время выполнения при сборке с помощью iajc

Мы использовали аспект J, чтобы получить некоторую метрику для существующего приложения. При сборке и плетении с помощью AJDT в eclipse все работает отлично. Но в среде интеграции. мы используем сценарий ant для сборки и развертывания приложения.

Проблема возникает в ExceptionHandler, который я сделал, чтобы убедиться, что наш аспект не вызовет исключение и не сломает приложение.

@Aspect
public class ExceptionHandlerAspect {

    /**
     * Pointcut
     */
    @Pointcut("within(com.xxx.yyy.aop.aspect.*..*)")
    public void allMethodInAspectPackage() {}

    /**
     *  Pointcut
     */
    @Pointcut("!within(com.xxx.yyy.aop.aspect.ExceptionHandlerAspect)")
    public void notInExceptionHandlerAspectClass() {}
    /**
     *  Pointcut
     */
    @Pointcut("call(* *(..))")
    public void allClassAndMethod() {}

    /**
    @Around("allClassAndMethod() && allMethodInAspectPackage() && notInExceptionHandlerAspectClass()")
    public Object logException(ProceedingJoinPoint joinPoint) throws Throwable{
        Object ret = null;
        try {
            ret = joinPoint.proceed();
        }catch (Throwable exception) {
            if (joinPoint.getSignature().getDeclaringTypeName().equalsIgnoreCase("org.aspectj.lang.ProceedingJoinPoint")) {
                throw exception;
            }
            this.logException.info("Exception in " + joinPoint.getSignature().getDeclaringTypeName(),exception);
        }finally {
            return ret; 
        }

    }

}

По сути, я хочу перехватывать каждый вызов в моем пакете аспектов, кроме самого ExceptionHandler.

сборка муравья выглядит так:

<iajc inpath="${classes.dir}" destDir="${classes.dir}" fork="true" maxmem="${aspectj.maxmem}" verbose="true" showWeaveInfo="true" debug="true">
    <classpath refid="ajclasspath"/>
</iajc>

${classes.dir} — это каталог классов, в котором задача javac создала приложение и аспекты.

Из результата,

Exception in thread "main" java.lang.NoSuchMethodError: com.xxx.yyy.aop.aspect.ExceptionHandlerAspect.aspectOf()Lcom/xxx/yyy/aop/aspect/ExceptionHandlerAspect;
    at com.xxx.yyy.aop.aspect.ecs.AspectBaseEcs.inspectLoginInfo(AspectBaseEcs.java:65)
    at com.xxx.yyy.app.es.security.Security.loadApplications(Security.java:172)
    at com.xxx.yyy.app.es.gui.VSDlgLogin.loadSecurity(VSDlgLogin.java:346)
    at com.xx.yyy.app.es.ApplicationSuite.start(ApplicationSuite.java:839)
    at com.xxx.yyy.app.es.ApplicationSuite.main(ApplicationSuite.java:501)

похоже ExceptionHandler не сплели!!!

Я надеюсь, что кто-то может помочь мне в этом ;-)


person Cygnusx1    schedule 12.07.2011    source источник
comment
Существует более распространенная причина этой ошибки здесь   -  person Vlastimil Ovčáčík    schedule 21.08.2015
comment
нужно плести и аспекты и аспекты вызова клиентов!   -  person Gaurav    schedule 22.03.2018


Ответы (4)


Наконец нашел проблему. Наше приложение имело зависимость от общего модуля jar, который также содержал аспект.

Имя базового пакета было таким же: com.xxx.aop и базовый класс, который мы использовали для наших аспектов, имел то же имя. Итак, 2 com.xxx.aop.AspectBase.class были загружены.

Поскольку мы использовали флаг в нашем файле сборки Ant, чтобы включить переплетение во время компиляции при да/нет, один из наших AspectBase.class не был переплетен, а другой был.

person Cygnusx1    schedule 23.08.2011

у меня была очень похожая проблема

java.lang.NoSuchMethodError: ....aspectOf()...

Я использую Spring 3.1.2 + Maven 3.0.4 + Tomcat 7.0.29, и иногда случается, что при запуске Tomcat я получаю это исключение.

Я понятия не имею, почему это происходит. Я использую Spring Tool Suit IDE, но когда я выполняю mvn clean install из командной строки (не в IDE), это каким-то образом исправляется, может быть, это кому-то поможет.

person Betlista    schedule 09.10.2012
comment
Серьезно, мужик ... Я искал эту проблему почти 2 часа ... но только ваше решение сработало для меня ... так что ставлю вам палец вверх. - person Gurinder; 19.02.2019

похоже, вы забыли объявить путь аспекта. Все, что вам нужно сделать, это скомпилировать, а не сплести. И это приводит к java.lang.NoSuchMethodError

Ниже приведен пример, показывающий, как использовать задачу iajc с переплетением:

<iajc outjar="demo.jar">
    <sourceroots>
        <pathelement location=”src” />
        <pathelement location=".." />
    </sourceroots>
    <aspectpath>
        <pathelement location="org.springframework.aspects-3.0.0.RC1.jar" />
    </aspectpath>
</iajc>

Надеюсь, это поможет!

person Espen    schedule 13.07.2011
comment
Спасибо за ответ. На самом деле, я вижу, что мои аспекты переплетены. Так как, когда я их декомпилирую, я вижу, что в декомпилированном коде моего ExceptionHandler видны аспекты aspectOf() и hasAspect(). Все эти аспекты находятся в пакете внутри проекта. Все они включены в inpath. Что мы должны поместить в путь аспекта? aspecjrt.jar? - person Cygnusx1; 13.07.2011
comment
Аспект, который вы хотите вплести в свой код. В приведенном выше примере содержится аспект транзакции, который вплетает логику транзакции во все методы, отмеченные @Transactional. Если у вас есть свой аспект во входном пути, он также должен работать. - person Espen; 14.07.2011
comment
Еще раз спасибо, что нашли время ответить. На самом деле вы отвечаете на другой вопрос, который я задавал об аспекте ;-) Но, к сожалению, он все еще не работает. Мои аспекты находятся в том же проекте, что и базовый код приложения. так что они на самом деле находятся в пути. но все же не повезло с ExceptionHandler, имеющим NoSuchMethodError во время выполнения. Если я прокомментирую точки ExceptionHandler, все работает отлично. Итак, причина в ExceptionHandler... но почему^ я до сих пор не знаю :-( - person Cygnusx1; 14.07.2011

У меня было это исключение, когда я использовал Spring Boot, но моя конфигурация AspectJ была выполнена «по-старому».

Если вы используете Spring Boot, убедитесь, что у вас есть только зависимость org.springframework.boot:spring-boot-starter-aop в pom.xml/build.gradle. Тогда вам не нужны никакие дополнительные @Configuration для аспектов, вы можете просто сделать:

@Aspect
@Component
public class LogEntityChangesAspect {

    @Autowired
    private ChangeLogDao changeLogDao;
person Piotr Sagalara    schedule 30.10.2019