- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
Here is my sample non-working project .
它包含2个模块:
Wrap
注解的定义。Wrap
注释的主类。目录结构如下:
.
├── README.md
├── aop-app
│ ├── pom.xml
│ └── src
│ └── main
│ └── java
│ └── com
│ └── aop
│ └── app
│ ├── DynamicLoad.java
│ └── Main.java
└── aop-lib
├── pom.xml
└── src
└── main
└── java
└── com
└── aop
└── app
└── lib
├── Wrap.java
└── WrapDef.java
我正在尝试通过加载时间编织 (LTW) 通过动态加载official docs中提到的javaagent .但它不起作用。
以下是Wrap.java的内容
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Wrap { }
以下是WrapDef.java的内容
@Aspect
public class WrapDef {
private static final Logger logger = LoggerFactory.getLogger(WrapDef.class);
public static boolean loaded = false;
@Around("@annotation( wrapAnnotation ) && execution(* *(..))")
public Object processSystemRequest(final ProceedingJoinPoint pjp, Wrap wrapAnnotation)
throws Throwable {
logger.debug("before wrap");
Object o = pjp.proceed();
logger.debug("after wrap");
return o;
}
static {
System.out.println("Loading");
WrapDef.loaded = true;
}
public static void reportLoaded() {
System.out.println("loaded : " + loaded);
}
}
以下是Main.java的内容:
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
@Wrap
public void myFunc(){
logger.debug("inside myFunc");
}
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
boolean dynamicLoad = Boolean.getBoolean("dynamicLoad");
if(dynamicLoad){
Main.isAdviceClassLoaded(); //To see if WrapDef.java is loaded or not.
if(!DynamicLoad.isAspectJAgentLoaded()) {
logger.error("AspectJ Not Loaded. Existing.");
System.exit(0);
}
Main.isAdviceClassLoaded(); //To see if WrapDef.java is loaded or not.
}
new Main().myFunc();
}
private static void isAdviceClassLoaded() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class);
m.setAccessible(true);
ClassLoader cl = ClassLoader.getSystemClassLoader();
Object test1 = m.invoke(cl, "com.aop.app.lib.WrapDef");
boolean loaded = test1 != null;
System.out.println("com.aop.app.lib.WrapDef Loaded : " + loaded);
}
}
使用 javaagent
作为 cmd line arg,它工作得很好:
$ java -javaagent:deploy/lib/aspectjweaver-1.9.1.jar -classpath aop-app-1.0.jar:deploy/lib/* com.aop.app.Main
14:02:45.384 [main] DEBUG com.aop.app.lib.WrapDef - before wrap
14:02:45.391 [main] DEBUG com.aop.app.Main - inside myFunc
14:02:45.391 [main] DEBUG com.aop.app.lib.WrapDef - after wrap
但是,通过 javaagent
的动态加载,它会给出以下输出:
$ java -DdynamicLoad=true -DAGENT_PATH=deploy/lib/aspectjweaver-1.9.1.jar -classpath aop-app-1.0.jar:deploy/lib/* com.aop.app.Main
com.aop.app.lib.WrapDef Loaded : false //The WrapDef is NOT loaded before JAVAAGENT is Loaded - which is correct
java.lang.UnsupportedOperationException: AspectJ weaving agent was neither started via '-javaagent' (preMain) nor attached via 'VirtualMachine.loadAgent' (agentMain)
loading javaAgent deploy/lib/aspectjweaver-1.9.1.jar
loaded javaAgent deploy/lib/aspectjweaver-1.9.1.jar //The JAVAAGENT is Dynamically Loaded - which is correct
com.aop.app.lib.WrapDef Loaded : false //The WrapDef is STILL NOT loaded even AFTER JAVAAGENT is Loaded - THIS IS THE ISSUE
15:53:08.543 [main] DEBUG com.aop.app.Main - inside myFunc
official docs确实说在附件之前加载的任何类都不会被编织
。但是,恰恰相反,正如您在上面的输出中看到的那样,根本没有加载 WrapDef
类。
另外,请注意我在我的 aop-lib/pom.xml 中使用了 aspectj-maven-plugin
,具有以下选项:
<outxml>true</outxml> //creates META-INF/aop-ajc.xml
<showWeaveInfo>true</showWeaveInfo> //supposed to create <weaver options="-showWeaveInfo"/> BUT DOES NOT WORK
<verbose>true</verbose> //supposed to create <weaver options="-verbose"/> BUT DOES NOT WORK
因此,它在 aop-lib-1.0.jar
中创建了 META-INF/aop-ajc.xml
,内容如下:
<aspectj>
<aspects>
<aspect name="com.aop.app.lib.WrapDef"/>
</aspects>
</aspectj>
但是 showWeaveInfo
和 verbose
对应的其他标签没有在 META-INF/aop-ajc.xml
中创建。这是另一件在这里不起作用的事情。
如果您需要任何其他信息 - 我会提供。
感谢任何帮助。
最佳答案
解释很简单:您正在 Main
类中直接测试编织代理,该类在从该类附加该代理之前已经加载。所以你必须避免你喜欢编织的类过早加载。我建议您将方法 myFunc()
(顺便说一下,这个名字很糟糕)放到另一个类中。怎么样?
package com.aop.app;
import com.aop.app.lib.Wrap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Application {
private static final Logger logger = LoggerFactory.getLogger(Application.class);
@Wrap
public void myFunc(){
logger.debug("inside myFunc");
}
public static void main(String[] args) {
new Application().myFunc();
}
}
然后在 Main.main(..)
的最后一行启动您想要编织的实际应用程序:
Application.main(null);
这将产生以下输出:
com.aop.app.lib.WrapDef Loaded : false
java.lang.UnsupportedOperationException: AspectJ weaving agent was neither started via '-javaagent' (preMain) nor attached via 'VirtualMachine.loadAgent' (agentMain)
loading javaAgent aop-app/target/deploy/lib/aspectjweaver-1.9.1.jar
loaded javaAgent aop-app/target/deploy/lib/aspectjweaver-1.9.1.jar
com.aop.app.lib.WrapDef Loaded : false
Loading
07:56:21.703 [main] DEBUG com.aop.app.lib.WrapDef - before wrap
07:56:21.716 [main] DEBUG com.aop.app.Application - inside myFunc
07:56:21.716 [main] DEBUG com.aop.app.lib.WrapDef - after wrap
P.S.:您真的认为方面库的用户在 JVM 命令行上指定两个属性比仅使用 -javaagent:/path/to/aspectweaver.jar
更容易吗?无论如何,您可能有理由使用动态编织器附件。在某种程度上,我很高兴有人使用我刚才自己添加到 AspectJ 的功能。 ;-)
关于java - AspectJ AOP LTW 不适用于 javaagent 的动态加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51693552/
我想将aspectj与LTW一起使用,但我不想使用代理 我做了一些搜索,并没有找到什么,只有在下面的文章中,提到了一些东西https://www.eclipse.org/aspectj/doc/rel
我正在尝试将 AspectJ(直到昨天我才知道)与 LTW 一起使用,以了解如何 an existing framework作品。简而言之,我对如何解析框架的输入 XML 文件感兴趣。 我写了以下方面
我尝试完成 AspectJ Cookbook 中的 LTW 示例,但它不起作用。我创建并编译了 Java 类: public class MyClass{ public void foo(int nu
我正在尝试使用 LTW 在这里创建一个周围的建议。 com.sample.core.Task 位于不同的库 jar 中。当我尝试编译时,我收到警告 "advice defined in com.ao
我们如何使用 aop.xml 在纯 java 代码中定义切入点?这是一个示例代码,我试图在 aop.xml-> 中定义切入点1)这是java类 package testAOP; public clas
我有一个 Aspect 类,它定义了一个切入点表达式,如下所示 @Pointcut("execution(* com.vg.pw.tasks.shared.*.executeTasks(..))")
我在我的 guice 应用程序中使用 aspectj LTW,我正在尝试为从配置文件控制的方面创建切入点定义。例如: pointcut publicOperation() : execution(**
我已将我的 aspectJ 方面捆绑到一个 War (aspectsWar.war) 文件中,并将其部署到具有现有正在运行的应用程序的应用程序服务器,并在 tomcat 服务器上使用 LTW 编织和
我尝试用简单的方面来做一个简单的项目(hello world)。我使用 Maven 来构建这个项目,LTW 用于方面,logback 用于日志。当我使用时,方面是编织的: "C:\Program Fi
我正在使用 Spring LoadTimeWeaving 功能在 ddd 架构中开发应用程序。问题是我可以使用 Eclipse 但不能通过 Maven 运行我的 Junit 测试。我已经尝试了各种网站
我使用 AspectJ 设置了 LTW,并且 spring 非常快速且成功。这是设置:beans.xml: 我的服务将自动连接到一个类: @Service public class MySe
我试图将我的方面定义为具体方面,以便能够在 aop.xml 中定义切入点而无需编译代码。我正在使用 LTW。 当我在方面类本身中定义切入点 exp 并将方面定义为简单方面 ( ) 时,它工作得很好。但
Here is my sample non-working project . 它包含2个模块: aop-lib - 用作库的方面。它包含以下类 Wrap.java - 这是用于附加建议的注解 Wra
我正在使用 Spring 3.0 RC1 中的缓存抽象机制:我已经设置了字节码(基于 AspectJ)weawing,以便缓存机制可以应用于从类本身调用的方法。值得一提的是,首先我使用的是基于代理的方
我一直在努力让它在我这边发挥作用。我想要实现的是启动我的 spring-boot 项目,当我运行没有任何 Java 代理参数的“java -jar app.jar”(使用 Tomcat 8 嵌入式)时
我在 Tomcat 6 webapp 中使用 Spring 进行加载时编织时遇到了一些问题。我只想将它用于事务(以便自调用尊重事务注释,而 AOP 代理则不这样做)。似乎编织器正在加载,但我的带注释的
我见过许多与 @Cacheable 相关的 Spring 功能示例。 , @Transactional , @Async等,每次都重复相同的选项: 通过 ApplicationContext.getB
作为迁移到 Java 8 和 Spring 4 的一部分,我想我会升级到所有 64 位代码。此应用程序在 32 位上完美运行,但加载时间编织在 64 位上不起作用(事实上什至不加载)。 架构细节: J
我有一个配置了aspectJ LTW的spring tomcat项目,我想用AspectJ LTW运行单元测试。根据为独立 JVM 使用 LTW 运行的 spring 文档需要传入 JVM 代理的参数
我经历了所有尝试使我的项目在 Tomcat 上运行的可能性,并切入模型( setter/getter )并使用 AspectJ Load Time Weaver 编织它们。基本上,我遵循了 Sprin
我是一名优秀的程序员,十分优秀!