【问题标题】:adviceDidNotMatch warning and execution stops without giving any erroradviceDidNotMatch 警告和执行停止而不给出任何错误
【发布时间】:2014-07-01 03:04:58
【问题描述】:

我正在使用 aspectj 来跟踪 Java 应用程序中的状态变化。这是我的建议:

public aspect TrackStateChanges
{
    after( Stateful stateful, StateTracker stateTracker ):
            @annotation(stateful)
                    && target(stateTracker)

                    && !cflow(execution(@PrivilegedAccessor * StateTracker+.*(..)))

                    && (set(@Stateful * StateTracker+.*)
                                || get(@Stateful * StateTracker+.*))

                    && withincode(@StateWriter private * StateTracker+.*(..))
            {
                stateTracker.onStateChanged( stateful.value() );
            }
}

这是我的注释类:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Stateful
{
    ChangedPart value ();
}

当我构建它时,会出现以下警告:

警告:ajc:在 aspect.TrackStateChanges 中定义的建议尚未应用 [Xlint:adviceDidNotMatch]

我的进口很稳定,我认为这不是问题。我问是因为 ajc 在某些情况下表现得很奇怪。大多数时候它工作正常,但对于特定的状态字段它不能正常工作。问题是它运行stateTracker.onStateChanged(stateful.value()) 然后执行停止,线程在执行finally 块后被杀死。我没有得到任何例外或什么都没有。这个问题与警告有关吗?还是别的什么?

我正在使用 aspectj-maven-plugin v1.6 和 aspectjrt v1.7.3

【问题讨论】:

    标签: aspectj


    【解决方案1】:

    这听起来有点像 stackoverflow 案例,其中通知调用最终循环回通知的内容。堆栈溢出被吞没而不是打印。但这与adviceDidNotMatch 消息有些矛盾。如果您分两个阶段进行编译,我只会期望该消息:

    (1) 仅编译方面,而不在同一步骤中编译方面的目标

    (2) 编译目标代码,应用方面。

    在第 (1) 步,您将收到adviceDidNotMatch,因为目标代码不存在。

    您可以通过仅注释掉通知正文来确认它是否是堆栈溢出,或者将其替换为System.out.println("in advice!")。如果这有效并且没有锁定,您可以尝试在建议中打印堆栈,这可能会告诉您导致溢出的原因。因此,将建议正文更改为 Thread.currentThread().dumpStack() 之类的内容(可能会打印很多!)。

    如果是这个问题,你可以引入一个子句!cflow(adviceexecution()),它会阻止因为advice而触发advice。

    虽然如果这有帮助,那么可能是!cflow 的问题 - 实现类似!cflow(execution(...)) AspectJ 需要能够看到所有... 位置才能标记它们。如果 AspectJ 无法检测所有这些位置,则 cflow 检查将失败,并且即使未满足您表达的条件,也会运行建议。如果没有为 AspectJ 提供所有要编织的代码,AspectJ 将无法检测所有位置。例如,如果您指的是类路径上的代码,而不是 inpath 或使用 ajc 编译那些 cflow() 切入点目标的源代码。

    【讨论】:

    • 提前致谢。我发现了这个问题,它与aspectj无关,我的错。但是我仍然收到警告,我的建议有什么问题还是像你说的那样编译?
    • 如果编译是单独发生的(在应用到主代码之前的方面),警告是完全可以预料的。 IIRC,您可以在建议上添加@SuppressAjWarnings for adviceDidNotMatch 以避免警告,如果您想删除它。如果您将所有源代码(包括方面)一起构建并且仍然得到这个,那么您的切入点有问题。在这种情况下,将其分解成碎片,看看是哪个导致它不匹配。
    猜你喜欢
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2013-11-11
    • 2019-01-28
    • 1970-01-01
    相关资源
    最近更新 更多