开始研究Java字节码工具。
就像很多时候一样,“你好世界”是我开始讲的。
短版本:我构建了一个打印Hello World的项目,现在我想对该类进行测试,这样它就可以打印Hello ASM。为此,我实现了一个虚拟代理,我以后打算修改它,使它能够进行必要的更改。如何对build.gradle文件进行调制,以便能够使用/测试它?
编辑:git clone https://bitbucket.org/RKor/helloasm.git
长版本
package helloasm;
import helloasm.instrumentation_targets.HelloWorld;
public class Main {
public static void main(String[] args) {
new HelloWorld().doSomething();
}
}哪里
package helloasm.instrumentation_targets;
public class HelloWorld {
public String doSomething(){
String output = "Hello World";
System.out.println(output);
return output;
}
}我让它返回输出字符串,这样我们就可以在JUnit中将它与简单的测试用例进行比较。
package helloasm.instrumentation_targets;
import org.junit.Test;
import static org.junit.Assert.*;
public class HelloWorldTest {
@Test
public void doSomething() throws Exception {
assertEquals("Hello ASM",new HelloWorld().doSomething());
}
}显然,测试将失败,程序将顽固地打印Hello World。让我们改变一下。
Java字节码检测需要提供一个.jar格式的代理。在使用Intellij时,我创建了一个新模块"HelloWorldAgent",并在中添加了 build.gradle文件
implementation "org.ow2.asm:asm:5.2"作为一种依赖。
现在我们添加一个代理
package helloasm.agents
import java.lang.instrument.Instrumentation;
public class Agent {
public static void premain(String args, Instrumentation instrumentation){
HelloWorldInterceptor transformer = new HelloWorldInterceptor();
instrumentation.addTransformer(transformer);
}
}变压器
package helloasm.agents
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
public class HelloWorldInterceptor implements ClassFileTransformer{
@Override
public byte[] transform(
ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer
) throws IllegalClassFormatException {
System.out.println(className + " loaded");
return classfileBuffer;
}
}还没有做任何令人兴奋的事情,但我想在我继续之前,先把所有的事情都做好。
我们将子模块的build.gradle添加到
jar {
archiveName = "${rootProject.name}-${rootProject.version}-agent.jar"
manifest {
attributes(
'Premain-Class': 'ch.ethz.koradir.helloasm.agents.Agent',
'Can-Redefine-Classes': 'true',
'Can-Retransform-Classes': 'true',
'Can-Set-Native-Method-Prefix': 'true',
'Implementation-Title': "HelloWorldInterceptor",
'Implementation-Version': rootProject.version
)
}
}这次又是什么?回到根项目的build.gradle中,我需要以某种方式指定
HelloWorldAgent编译到jar中。-javaagents标志运行(或者有一个选项来运行),提供jar我该怎么做?
发布于 2017-09-27 13:25:27
settings.gradle文件中删除HelloWorldAgent文件include 'HelloWorldAgent'添加到根settings.gradle文件中,使构建成为多项目生成。HelloWorldAgent/build.gradle中的三个HelloWorldAgent/build.gradle更改为projectbuild.gradle中evaluationDependsOn 'HelloWorldAgent'
test {
def jarTask = project('HelloWorldAgent').tasks.jar
dependsOn jarTask
afterEvaluate {
jvmArgs "-javaagent:$jarTask.archivePath"
}
}您的测试仍将失败,但您将看到您的变压器输出。
https://stackoverflow.com/questions/46445908
复制相似问题