Tag: 字节码

在try-finally块中嵌入方法的现有代码(2)

前段时间,我在try-finally块中嵌入了一个方法的现有代码,如何使用ASM将方法的主体包装在try-finally块中。 解决方案是在visitCode()中visitCode()方法体开头的try块的标签,并在visitCode()访问带有返回操作码的指令时完成try-finally块。 我知道如果方法没有返回指令,如果方法总是离开并且exception,则解决方案将不起作用。 虽然,我发现前一种解决方案有时也不适用于带有返回指令的方法。 如果方法有多个返回指令,它将无法工作。 原因是它生成了无效的字节码,因为在方法的开头添加了一个try-finally块,但是完成了多个try-finally块。 通常(但可能取决于javac编译器),字节码方法包含单个返回指令,并且所有返回路径通过跳转在该指令处结束。 但是,使用Eclipse编译以下代码将导致字节代码带有两个返回指令: public boolean isEven(int x) { return x % 2 == 0; } 用Eclipse编译的字节代码: 0: iload_1 1: iconst_2 2: irem 3: ifne 8 6: iconst_1 7: ireturn // javac compilation: goto 9 8: iconst_0 9: ireturn 因此,我想知道包装方法代码的整个代码的正确方法是什么。

Java中如何使用Byte Buddy分配字段?

我很难理解Byte Buddy的文档。 为了帮助我学习API,我想生成与此Java相当的字节代码: public final class GeneratedByByteBuddy { private final int a; public GeneratedByByteBuddy(final int a) { this.a = a; } } 我很难找到使用Instrumentation创建字段分配的正确方法。

我可以使用Byte Buddy重新定义私有方法吗?

是否可以使用Byte Buddy来重新定义类的私有方法? 似乎使用Byte Buddy的入口点总是对现有类进行子类化。 这样做时,显然不可能重新定义父类的私有方法(至少不能以在父类中使用重新定义的方法的方式)。 请考虑以下示例: public class Foo { public void sayHello() { System.out.println(getHello()); } private String getHello() { return “Hello World!”; } } Foo foo = new ByteBuddy() .subclass(Foo.class) .method(named(“getHello”)).intercept(FixedValue.value(“Byte Buddy!”)) .make() .load(Main.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded() .newInstance(); foo.sayHello(); 输出将是“Hello World!”。 有没有机会得到“Byte Buddy!” 作为输出?

如何使用Java检测替换新类?

我需要创建一个java代理,当启用它时,它获取jar文件的路径作为参数,然后它将任何加载的类替换为jar文件中的一个,如果它们的名称匹配。 例如,我们有一个名为com.something.ClassTest的类的应用程序。 现在,如果提到的jar(不在类路径中)有一个与com.something.ClassTest完全相同的类,我想用jar中的那个替换它。 我有这类变压器,但不确定这是否正确。 我收到IOException,找不到消息Class。 @Override public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if(classNames.contains(className.replace(“/”, “.”))) { System.out.format(“\n==> Found %s \n”, className); try { Class c = urlClassLoader.loadClass(className.replace(“/”, “.”)); InputStream is = urlClassLoader.getResourceAsStream(className.replace(“/”, “.”)); System.out.println(“Loaded class ” + c); ClassReader reader = new ClassReader(is); ClassWriter writer = new […]

字节码以无证方式随时间变化

今天我在openjdk 7上用javaagent和instrumentation来探索大型应用程序(比如带有应用程序的jboss服务器)的类。我每隔10秒就调用所有类的重新转换,所以它们的字节码在我的ClassFileTransformer实现中得到了。 我的实现只是跟踪类的字节码如何随时间变化。 首先,我很惊讶,字段和方法的顺序,方法访问修饰符,常量池的内容和其他类似的东西因检查而异。 但是,它仍然记录在案 。 没有记录的内容 – 某些项目可以在类中创建常量池并注入到方法中。 现在我注意到数字值(Longs,Doubles,Floats等)会发生。 这是它在javap中的样子; 之前: pool: … #17 Float NaNf method: #1 fload #17 //NaNf … 在运行时更改类之后: pool: … #17 Float NaNf #18 Float NaNf method: #1 fload #18 //NaNf <- look, it loads #18 now 我仔细检查过,没有附加任何其他变压器或代理商。 为什么JVM不能让我的字节码保持不变? 我在哪里可以阅读有关此类优化/转换(或其他什么)? 我读过JVM源代码,但这些只让我更加困惑。 我只是想创建一种实时字节码validation器 – 一种安全工具。

JVM上的所有“Magic”方法都标记为Native吗?

“魔术”是指具有不用纯Java表达的语义的方法。 我知道所有native方法都很神奇,因为它们的实现是由底层运行时提供的,而不是由Java字节码提供的。 反之亦然吗? 所有魔法方法都是native ,还是有一些神奇的方法显然是用纯Java实现的,但是有一些JVM特殊shell的额外帮助? 用例是我想通过检测其字节码来修改Java的语义。 所有这些神奇的方法都是特殊情况,我将不得不以某种方式处理。 native的都很明显,但我想知道是否有任何无标记的魔术方法我需要注意和特殊情况。

如何识别Java字节码中的覆盖方法?

我现在专注于需要深入了解Java字节代码的项目。 在bcel的帮助下,我现在可以完成大部分工作。 我现在不清楚的一点是如何识别子类方法覆盖其基本代码? .class文件中是否记录了与指示此重写关系的方法相关联的属性,还是应该向后返回其基类可以比较方法签名? 任何提示将受到高度赞赏。

如何计算java中执行的字节码数量

我要参加麻省理工学院的电竞比赛。 参赛者编写的程序可以控制相互对抗的机器人。 问题在于你的机器人只能在一个回合中执行一定数量的字节码(去年每回合10000次)。 现在,简单的循环就像 (int i=0; i<100; i++){ // do nothing } 根据他们的软件,使用大约400字节码(大概是这样的(用于递增i的2字节码加上用于检查i <100的2字节码)* 100 = 400字节码)因此我们必须编写非常紧密的代码。 因此,当我尝试一些不同的导航算法时,重要的是我能够弄清楚我的代码使用了多少字节码 – 我该怎么做? (这是可能的 – 他们这样做,我只是不确定如何!而且,他们必须阻止JIT以某种方式进入游戏。我知道每个机器人都在一个单独的线程中运行,所以我肯定答案涉及某些我不知道的线程技巧。)

Java字节码DUP

我想知道为什么以下字节码中的exception(用于抛出exception)是重复的。 NEW java/lang/IllegalArgumentException DUP INVOKESPECIAL java/lang/IllegalArgumentException ()V ATHROW

如何生成字节码并保存到.class文件?

我有以下奇怪的要求。 我给了: 一些方法名称的列表。 上述方法的名称和参数类型。 上述方法的function。 具体如下:对于每个参数,该方法使用toString将其转换为字符串并获取字符串数组。 对于该数组,该方法应用函数foo 。 函数foo将String []类型作为输入,并输出String 。 这些方法返回foo返回的内容。 foo的代码在Java对象中给出,并作为黑盒子进行访问。 1.和2.中的信息可以是文本或XML文件。 为此,我们可以认为它以我们选择的任何方式在Java对象中可用。 任务是创建一个实现这些方法的.class文件(即字节码),并且可以在JVM上运行。 我认为这个汇编程序库是一种方法。 有人能建议一个更简单的方法吗 [编辑:]我可以想到另一种方式:首先生成.java文件,然后编译它以获取.class文件。 [上下文:]我必须为数百种方法执行此操作。 我想要快捷方式,这样我就可以自动完成工作,而不是手动编写代码。