好吧,我正在阅读ASM4字节码库中的PDF教程/文档/书籍(如果你愿意的话).我正在尝试这些例子并通过阅读,实际输入代码,执行,然后从输出中学习来学习.我遇到了这个部分:
public class ClassPrinter extends ClassVisitor {
public ClassPrinter() {
super(ASM4);
}
Run Code Online (Sandbox Code Playgroud)
链接在这里: http://download.forge.objectweb.org/asm/asm4-guide.pdf
我无法弄清楚在超级中传递什么.我的IDE也不是很有帮助.
如何检查类的字节码(使用诸如ASM之类的东西)来了解哪些初始值传递给方法?
例如:给定一些将值互相传递的方法:
void m1(Object o) {
Object v = o;
m2(v);
m2("box");
}
void m2(Object o) {
Object v = o;
m3(x);
}
void m3(Object o) {
}
Run Code Online (Sandbox Code Playgroud)
还有一些方法调用,都在同一个类中定义:
{
Object foo = "foo";
m1(foo);
m2("bar");
m3("baz");
}
Run Code Online (Sandbox Code Playgroud)
我怎么可以检查类的字节码得知m3将与值被称为4倍"foo","box","bar"和"baz"?
我想在一些耗时的方法上做一些工具,比如 org/json/JSONObject.toString()使用ASM Java框架.
public class JSONUsage {
public void callToString() {
JSONObject jsonObject = new JSONObject();
String a = jsonObject.toString();//original call
System.out.println(a);
}
}
Run Code Online (Sandbox Code Playgroud)
public class JSONUsage {
public void callToString() {
JSONObject jsonObject = new JSONObject();
// **important!**
//pass the instance as an param, replace the call to a static method
String a = JSONReplacement.jsonToString(jsonObject);
System.out.println(a);
}
}
public class JSONReplacement {
public static String jsonToString(JSONObject jsonObject) {
//do the time caculation
long before …Run Code Online (Sandbox Code Playgroud) 我想if在特定行上更新现有类中的语句而不更改整个方法.
这是目标代码(类,方法和一些代码的名称已更改,因为它们不相关):
public class Target extends Something {
public Target(){
super();
//some code...
}
public Result targetMethod(Data firstPar, Data secondPar){
if(someStatement()) {
return Result.FAIL;
} else {
if(firstPar.check()){ //here is the line I want to change
firstPar.doSomething()
}
secondPar.doSomething();
return Result.SUCCESS;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在这段代码中我想改成if(firstPar.check())这样的东西:
if(firstPar.check() && !Utilities.someOtherCheck(firstPar, secondPar))
Run Code Online (Sandbox Code Playgroud)
这是我试图解决这个问题的方法:
ClassNode node = new ClassNode();
ClassReader reader = new ClassReader(bytes); //bytes - original target class
reader.accept(node, 0);
ClassWriter cw = new ClassWriter(0);
node.accept(cw);
MethodVisitor visitor = …Run Code Online (Sandbox Code Playgroud) 在Java中,可以使用实现来创建动态代理InvocationHandler.尽管进行了JVM优化,但使用反射总是会有一些调用方法的开销.
为了尝试解决这个问题,我尝试使用ByteBuddy在运行时创建代理类,但文档在这方面似乎不够清晰.
如何创建一个MethodCallProxy方法以将方法调用转发到某个类实例?
编辑:
为了更好地澄清我的问题,我提供了一个我想要实现的例子:
我正在构建一个RPC系统.在方法调用的每一侧,我都有一个定义契约的接口(当调用者/被调用者都在JVM下运行时).
@Contract
interface ISomeService {
fun someMethod(arg0: String, arg1: SomePojo): PojoResult
}
Run Code Online (Sandbox Code Playgroud)
在调用站点,我注入一个代理,拦截所有方法调用并将它们转发给被调用者.
ByteBuddy()
.subclass(Any::class.java)
.implement(serviceClass)
// Service contract method delegation
.method(isDeclaredBy(serviceClass)).intercept(
MethodDelegation
.to(ServiceProxyInterceptor())
.filter(not(isDeclaredBy(Any::class.java)))
)
.make()
.load(this)
.loaded as Class<T>
Run Code Online (Sandbox Code Playgroud)
最后,在被调用者,我有几个处理程序,每个服务方法一个,负责解组调用参数并将它们转发到服务实现.
@Service
class SomeServiceImpl {
fun someMethod(arg0: String, arg1: SomePojo): PojoResult {
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
我可以使用代码生成来解决这个问题,但生成的jar文件会变得非常大.因此,我想创建这些处理程序的通用版本,并在每个实例中附加一个代理,该代理拦截每个方法调用ISomeService并转发它们SomeServiceImpl.
我想在Perl中检查和操作任意Perl程序的代码(由coderefs获取).有没有工具/模块/库?类似于B :: Concise的东西,除了B :: Concise在输出上打印代码,但我想以编程方式检查它.
我想像这样使用它.给定一个coderef F,例如.有10个参数:
$ret = &$F(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10);
Run Code Online (Sandbox Code Playgroud)
我想创建一个函数F1,st.
&$F(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) ==
&$F1(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)*
&$C(x2, x3, x4, x5, x6, x7, x8, x9, x10)
Run Code Online (Sandbox Code Playgroud)
那就是把它"分解"成两部分,第二部分不依赖于x1第一部分,第一部分尽可能简单(我假设它F是一个巨大的产品).
我想要的应用是Metropolis采样算法的优化 - 假设我正在对分布进行采样p(x1 | x2 = X1, x3 = X3, ...) = f(x1, x2, x3, ...).算法本身是不变的.乘法常数因子和其他变量不会通过算法改变,因此不依赖于x1 …
perl code-analysis abstract-syntax-tree bytecode-manipulation
我有一个SomeObject.java文件:
class SomeObject {
String name;
}
Run Code Online (Sandbox Code Playgroud)
编译它会创建一个包含字节码的SomeObject.class文件.
0xCAFEBABE...
Run Code Online (Sandbox Code Playgroud)
如果我们在JVM上使用SomeObject,它将由当前的类加载器加载,并且一切正常.
现在让我们假设我想要一些动态代码生成.我可以写我的自定义注释
@Target(ElementType.TYPE)
public @interface Data {
...
}
Run Code Online (Sandbox Code Playgroud)
并将其作为修饰符添加到类声明中:
@Data
class SomeObject {
String name;
}
Run Code Online (Sandbox Code Playgroud)
我也可以在运行时保留它@Retention(RetentionPolicy.RUNTIME):
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Data {
...
}
Run Code Online (Sandbox Code Playgroud)
用于字节码注入的注释在哪里?在使用适当的运行时保留注释加载类时,类加载器是否会注入字节码,如下图所示:
source -(compile)-> bytecode -(classloader bytecode injection)-> injected bytecode -(classloading)-> JVM loaded bytecode
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个带有.class文件的程序,并收集.class文件的所有方法以及每个方法的内容.这是我的代码
public class ClassReaderTest1 {
public static void main(String[] args) throws Exception{
InputStream in = new FileInputStream("*.class");
ClassReader reader = new ClassReader(in);
ClassNode classNode = new ClassNode();
reader.accept(classNode,0);
@SuppressWarnings("unchecked")
final List<MethodNode> methods = classNode.methods;
for(MethodNode m: methods){
InsnList inList = m.instructions;
System.out.println(m.name);
for(int i = 0; i< inList.size(); i++){
System.out.println(" " + Integer.toHexString(inList.get(i).getOpcode()));
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的输出
init>
ffffffff
ffffffff
19
b7
b1
ffffffff
main
ffffffff
ffffffff
b2
12
b6
ffffffff
ffffffff
3
36
ffffffff
ffffffff
b1
ffffffff
Run Code Online (Sandbox Code Playgroud)
最终我不想打印这些值,我只是希望能够在我的程序中引用它们(我正在尝试检查我是否得到了正确的值).我按预期得到方法,但方法的内容对我没有意义.我认为这些不是操作码; …
例如我可以做这样的事情吗
pythonCode = "print 'hello world'"
pyc = generate_bytecode(pythonCode)
Run Code Online (Sandbox Code Playgroud)
其中 pyc 将包含 pythonCode 的字节码?
编辑:我的目标本质上是准确获取将写入文件中的 .pyc 的内容到变量中。幻数、时间戳、十六进制版本的代码等等
目前,我参与了一个大型遗留项目,其中包含许多巨大的类和生成的代码。我希望找到所有字节码长度大于 8000 字节的方法(因为 OOTB java 不会优化它)。
我找到了这样的手动方式:How much bytes of bytecode has a certain method in Java? ,但是我的目标是自动扫描许多文件。
我尝试使用 jboss-javassist,但据我所知,获取字节码长度仅在类级别可用。
java ×7
bytecode ×4
jvm-bytecode ×2
annotations ×1
built-in ×1
byte-buddy ×1
classloader ×1
opcode ×1
perl ×1
proxy ×1
python ×1