Java 检测:阻止 class 加载引用 class

Java Instrumentation: Prevent class reference from loading class

你好 Whosebug 社区,

我最近发现了 Java 工具以及你可以用它做些什么,所以我决定为我写一个小库来简化其中的一些事情。

我有以下方法(简化):

public static void editClass(Class<*> clazz) {
   ...
}

它通过 Instrumentation 添加了一个转换器,它转换名为 clazz.getName() 的已加载 classes 的字节码。

所以在我的 premain 方法中,我可以说

editClass(Foo.class);

我的问题是,通过引用指定 class (.class),这个 class 在添加转换器之前加载,所以在那之后,我必须重新转换 class 这会阻止我使用 adding/removing 方法等等。

那么,有没有办法在使用这个 class 引用时不加载 class?或者其他实现方式?我知道我可以将 class 名称作为参数传递,但我真的很想使整个库类型安全并使重构更容易。

提前致谢!

如果您只想从 premain 调用 editClass 方法,我们假设 Java Agent 本身不使用 class,否则, class editClass 调用中的文字将是唯一的触发器,您可以执行以下操作:

  • 提供两种方法,editClass(Class<?> clazz)editClass(String qualifiedName)
  • 使用 editClass(Class<?>) 编写 premain 方法(或一般的代理 classes)并享受编译时安全关于通过引用的 classes 的存在文字
  • 执行代理 classes 的静态代码转换,将 editClass(Class<?>) 的所有调用替换为 editClass(String)
    这应该不会太难,因为您只需将 ldc packagename/Foo.classinvokestatic (Ljava/lang/Class;)V 的所有序列替换为 ldc "packagename.Foo"invokestatic (Ljava/lang/String;)V.
    当方法 editClass(String qualifiedName) 可以处理内部 class 名称(使用斜线而不是点)时,它可能会变得更加容易。
    既然你说你“最近发现了 Java Instrumentation”,这可能是 class 文件转换
  • 中的一个很好的练习
  • 使用不再引用 classes 的转换代理 classes 进行转换,以执行加载时间转换