首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何设置字节码检测的Intellij / jar清单?

如何设置字节码检测的Intellij / jar清单?
EN

Stack Overflow用户
提问于 2017-09-27 10:46:11
回答 1查看 609关注 0票数 2

开始研究Java字节码工具。

就像很多时候一样,“你好世界”是我开始讲的。

短版本:我构建了一个打印Hello World的项目,现在我想对该类进行测试,这样它就可以打印Hello ASM。为此,我实现了一个虚拟代理,我以后打算修改它,使它能够进行必要的更改。如何对build.gradle文件进行调制,以便能够使用/测试它?

编辑:git clone https://bitbucket.org/RKor/helloasm.git

长版本

代码语言:javascript
复制
package helloasm;

import helloasm.instrumentation_targets.HelloWorld;

public class Main {
    public static void main(String[] args) {
        new HelloWorld().doSomething();
    }
}

哪里

代码语言:javascript
复制
package helloasm.instrumentation_targets;

public class HelloWorld {
    public String doSomething(){
        String output = "Hello World";
        System.out.println(output);
        return output;
    }
}

我让它返回输出字符串,这样我们就可以在JUnit中将它与简单的测试用例进行比较。

代码语言:javascript
复制
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文件

代码语言:javascript
复制
implementation "org.ow2.asm:asm:5.2"

作为一种依赖。

现在我们添加一个代理

代码语言:javascript
复制
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);
    }
}

变压器

代码语言:javascript
复制
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添加到

代码语言:javascript
复制
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
  • 它应该使用工具化的代码执行测试(或者有一个选项来执行)。

我该怎么做?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-27 13:25:27

  • settings.gradle文件中删除HelloWorldAgent文件
  • 通过将include 'HelloWorldAgent'添加到根settings.gradle文件中,使构建成为多项目生成。
  • HelloWorldAgent/build.gradle中的三个HelloWorldAgent/build.gradle更改为project
  • 将以下内容添加到根build.gradle
代码语言:javascript
复制
evaluationDependsOn 'HelloWorldAgent'

test {
    def jarTask = project('HelloWorldAgent').tasks.jar
    dependsOn jarTask
    afterEvaluate {
        jvmArgs "-javaagent:$jarTask.archivePath"
    }
}

您的测试仍将失败,但您将看到您的变压器输出。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46445908

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档