我使用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:在aspects.TrackStateChanges中定义的建议尚未应用[Xlint:adviceDidNotMatch]
我的进口是稳固的,我不认为这是一个问题。我问,因为ajc在某些情况下表现得很奇怪。大部分时间它工作正常,但对于特定的州字段,它不能正常工作。问题是它运行stateTracker.onStateChanged(stateful.value())
然后执行停止,执行finally
块后线程被终止。我没有得到任何例外,也没有任何例外。这个问题与警告有关吗?或其他什么?
我使用了aspectj-maven-plugin v1.6和aspectjrt v1.7.3
答案 0 :(得分:1)
这听起来有点像stackoverflow案例,其中建议调用最终循环回建议的东西。吞下堆栈溢出而不是打印。但这与adviceDidNotMatch消息有些矛盾。如果你在两个阶段进行编译,我只会期望这个消息:
(1)仅编译没有在同一步骤中编译方面的目标的方面
(2)编译目标代码,应用方面。
在步骤(1),您将获得adviceDidNotMatch,因为目标代码不在。
您可以通过仅注释建议正文来确认它是否是堆栈溢出,或者用System.out.println("in advice!")
替换它。如果这样做并且没有锁定,您可以尝试在建议中打印堆栈,这可能会显示导致溢出的原因。因此,将建议体更改为Thread.currentThread().dumpStack()
(可能打印很多!)。
如果是这个问题,你可以引入一个条款!cflow(adviceexecution())
,它会因为建议而阻止建议触发。
虽然如果有帮助那么!cflow
可能会出现问题 - 实现类似!cflow(execution(...))
的问题,AspectJ需要能够看到所有...
个地方才能标记他们。如果AspectJ无法检测所有这些位置,则cflow检查将失败,即使您表达的条件未满足,也会运行建议。如果没有给出编织的所有代码,AspectJ将无法检测所有位置。例如,如果你在类路径上引用代码,而不是inpath或用ajc编译那些cflow()切入点目标的源代码。