我有一个相当大的Java代码库(~15k文件)我无法访问源代码,但是,我想在运行时修改某些类,并将代码注入某些方法以调用我的代码。
由于技术问题,我无法反编译/重新编译并从那里开始。类文件由本机代码加载,并从自定义存档格式中提取,并使用自定义类加载器加载。但是,我可以很容易地在它们的JVM实例的上下文中执行Java代码。
我的目标是做以下事情:
例如,在那里代码中有一个类:
class Theirs {
public Theirs() {
//....
}
public String getName() {
return "Theirs";
}
}
在我的代码中,我有:
class Mine
{
public static Theirs theirs_ = null;
public static void myMethod(Theirs theirs) {
theirs_ = theirs;
}
}
我想修改他们的每个实例,表现如下:
class Theirs {
public Theirs() {
Mine.myMethod(this);
}
}
这样我就可以这样做:
System.out.println(Mine.theirs_.getName());
我认为CGLib Proxies会实现这一点,但是对于Proxies,由于字符串比较可能被称为每秒数十万次的方法,所以开销很高,无论如何,我发现为了拥有一个实例增强对象,你需要自己实例化它们.IE:不是你增强的类的所有实例都实际上是增强的,例如:
public static void main( String[] args )
{
Object proxy = Enhancer.create(Object.class, new HashCodeAlwaysZeroMethodInterceptor());
System.out.println(new Object().hashCode());
System.out.println(proxy.hashCode());
}
第一个println打印一个真实对象哈希,而不是预期的0。
所以现在我想我需要做的就是编写我自己的(或修改他们的)ClassLoader,它寻找我有兴趣修改的类,注入我的修改并从那里使用像ASM这样的东西。 (我使用JVMTI和C ++做了类似的事情,但编译/调试过程非常耗时)
然而,在我这样做之前,我希望有一些类似于CGLib代理工作的东西,因为库负责所需的字节码修改,但这并不需要我实际实例化一个实例说增强课程。
答案 0 :(得分:0)
我不知道CGLIB
是否适合将Java代码注入Java类 - 但是有一些框架就像f.e. javassist available,提供以Java为中心的方式将代码注入非密封的Java类:http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/
例如,我曾经使用javassist为大学课程创建了一个插件机制。希望代码示例很有用:https://github.com/RovoMe/PluginApplication/blob/master/PluginFramework/PluginCore/src/main/java/at/rovo/core/classloader/InjectionLoaderStrategyDecorator.java