问题标签 [bcel]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 使用 BCEL 在现有方法中注入代码
对于我的论文研究,我需要将一段代码注入到我没有源代码的测试套件中的可定义方法(在本例中为 DaCapo 基准测试套件,http: //dacapobench.org/ )。我论文的这一部分所基于的先前研究为此使用了字节码注入,这导致我也这样做。
我使用 Apache 的 BCEL 库 ( http://commons.apache.org/proper/commons-bcel/ ) 构建了一个小程序,使我能够在其他语句之前将斐波那契算法注入方法体中。
现在,我做了这个,但它不能正常工作。我注入的一些方法运行良好(因为斐波那契代码它们速度较慢),并且运行 DaCapo 框架运行良好,而其他注入的方法会破坏代码。
问题是,我不知道为什么,即使我知道哪些方法发生故障以及哪些方法成功了,我也无法在损坏的方法中找到重复出现的模式。
- 字节码似乎很好,到目前为止我可以看到,但我离专家还很远。当我比较注入前后的字节码时,我看到斐波那契算法后面跟着其余的方法,唯一的区别是增加的堆栈位置(因为注入的代码也使用堆栈空间)。
- 成功的方法包含公共方法和私有方法。带参数和不带参数。
- 一些失败的方法包含异常,而另一些则没有。有些人尝试过,有些人没有。等等等等
我可以粘贴一些失败的方法,但这会使这篇文章比现在更长。所以我想知道,有什么我没有考虑或忽略的事情吗?
下面你会找到一个示例 java 文件,它的结果和我编写的 BCEL 程序。
一个简单的例子,我有一个名为 DemoClass.java 的 java 文件:
在我的 shell 中调用以下 java 命令后:
javac DemoClass.java; java -cp bcel-5.2.jar:. InjectCodeBCEL DemoClass test 123456789 ; java DemoClass
(bcel-5.2.jar文件可以在前面提到的apache网站上找到)
该程序将如下所示:
这是 InjectCodeBCEL.java 的代码:
更新
下面你可以看到 net.sourceforge.pmd.AbstractRuleChainVisitor 中的 visitAll 方法注入失败后的完整错误
该方法的代码(由JD-GUI生成):
这是一个与我的代码错过“insertCodeInMethod”中的堆栈位置增加部分时得到的错误相当的错误。这导致参数和非静态时 this 与斐波那契代码中定义的变量发生冲突。
java - BCEL 更新异常表
我想更改使用 BCEL 的方法。但我不知道如何更新异常表。这是简化的代码:
正确修改此字节码后,异常表未更改并导致ClassFormatError
因为异常表指向不存在PC
。知道如何处理吗?
java - 是否可以直接从java类文件的Constant_Method_REF中获取java.lang.reflection.Method?
我正在使用 BCEL 转换方法字节码来实现匿名内部类风格的方法拦截器,在拦截方法的同时,我需要对被拦截的方法进行一些注解。我使用 BCEL 来拦截除 java 反射之外的方法访问。
现在我的代码可以很好地与没有原始类型的方法一起使用。由于我不知道如何将 Class.getDeclaredMethod 与原始参数类型列表一起使用,因为 getDeclaredMethod 接受 methodName 和 Class[] 数组作为参数。
所以第一个问题是如何做到这一点。
然后我发现在JDK7中,可以通过java类文件中的ldc_w字节码通过CONSTANT_MethodHandle直接获取MethodHandle引用。就像使用 ldc 引用 Java 类一样,如果我可以直接用 ldc_w 引用 java.lang.reflection.Method ,那么我将节省我做反射的时间,并且不会被上面第一个问题中提到的原始类型所困扰. 我试过了,但我没有做到这一点。
所以第二个问题是我可以使用 ldc_w 来引用 java.lang.reflection.Method 吗?
第三个问题是我可以将 MethodHandle 转换为 java.lang.reflection.Method 或相应方法上的注释吗?
谢谢霍尔格,您的回答我几乎完全清楚,但以下问题。我可能会误解您的回答,现在我在运行时遇到异常:
代码如下 //2.5 为数组中的每个元素赋值
convertType2ClassName 如下:
java - BCEL 可以生成 LocalVariableTable 吗?
我遇到了一个无聊的错误:
我不太明白错误的意思。
我写了一个类并生成了一个类,它们看起来非常相似:
写道:
生成:
因为它说“方法 net.madz.lifecycle.demo.standalone.ServiceOrder.allocateResources(JJJ)V 在偏移量 27 中的操作数堆栈类型错误”
是“27 aastore”吗?是什么导致了这个异常?在编写的版本类中,我的意思是我编写了一个 java 文件并将其编译为类文件。我使用 this.getClass() 来加载类引用,所以在编写的版本中,“偏移量”13 和 14 是“aload_0;” 和“调用虚拟 5;” 但是在生成的版本中,我在偏移量 13 处使用“ldc”直接引用该类,因此两个版本无法精确对齐。
通常如何诊断这些问题以及如何在运行时监控操作数堆栈,BCEL可以将LocalVariableTable生成到类文件中吗?
java - 在字节码中,使用 BCEL 将方法添加到类中的特定行
我是 BCEL 操作 Java 字节码的新手。我需要使用 BCEL 在 .class 文件的特定行中插入一个新方法。结果应该是一个新的 .class 文件,其中包含具有新插入方法的类。
我在网上搜索了很多,但找不到合适的代码。你能帮我解决这个问题吗?
提前致谢!
java - 未找到符号:抽象类 (BCEL) 中的静态方法
我有点坚持这一点。我无法编译,因为 java 声称找不到该方法setRepository()
,该方法是为以下代码中的抽象类定义的Repository
:
请注意,clearCache 函数链接得很好......
这是尝试使用此功能的代码
请注意,有一个烦人的复杂情况,即在 BCEL 中既有一个抽象类 Repository,又有一个接口 Repository (org.apache.bcel.util.Repository)。我不知道这是否与问题有关。
完整的错误输出:
谢谢各位!
java - 当我打开任务控制飞行记录文件时出现异常
当我在 java 任务控制中为我的应用程序开始飞行记录时,它会正常记录并打开 .jrf 文件,但出现如下异常:
*无法从 flight_recording_2013-12-11_11_28_09.jfr java.lang.IllegalArgumentException 加载事件:com.sun.org.apache.bcel.internal.generic.ClassGenException:检测到非法操作码。*
java - 使用 BCEL 从类的 ConstantPool 替换 ConstantUtf8
我有一个 java 类文件,其常量池包含一些 ConstantUtf8 数据,因为
75. CONSTANT_Utf8 : SampleString
95. CONSTANT_Utf8 : SampleString
不同索引上的数据相同,我编写了以下代码:
上面的代码在索引 95 处用“OtherString”替换了“SampleString”,但我想替换所有出现的,所以我添加了一个这样的循环,
这样它将通过索引,即 75 和 95 并替换为新值,但不幸的是,它产生与上述相同的结果意味着只替换一个出现,即 75。可以做些什么来替换所有?
java - 如何在 bcel 的 if 指令之前添加 if 指令
我想使用BCEL在我的方法中的特定 if_instruction 之前添加/插入一些 if_instruction。
这是我的方法:
java - 读取我想要的代码块的 BCEL 指令是什么
我正在使用 Bcel 开发一个调用方法。但我无法访问 getTweets 函数。它在 ActionListener 之后停止。它的指令是什么?
这是我阅读说明的方式:
这是我用 BCEL 阅读的代码: