我使用Java代理(Agent.class)来转换程序(Program.class)中的方法,其中包括对代理类的调用。
public Program.getMultiplier()F:
ALOAD 1
ALOAD 2
FDIV
+ INVOKESTATIC Agent.getCustomMultiplier(F)F
FRETURN
我已经检查了Agent和Program类的类加载器及其父类,它们的层次结构如下:
AppClassLoader
当程序执行添加的INVOKESTATIC
指令时,它会抛出一个ClassNotFoundExcture它找不到Agent类,因为它是由不同的类加载器加载的。
作为一个临时解决方案,我尝试强制AppClassLoader
成为带有反射的URLClassLoader
的父级,反射在较旧的Java版本中工作,但自Java 12以来已被删除。
是否有更可靠的方法确保我的代理类在任何类装入器中都可见?
您可能能够执行一些特定的操作,这些操作适用于URLClassLoader
,但并非所有类都由URLClassLoader的实例加载。任何OSGi项目都不会,大多数web服务器也使用自己的类加载器来支持热重新加载等。
据我所知,没有办法随便更新一些“所有类加载器的全局父类”或注入一个;没有这样的父级,即使有,类加载器也可以完全忽略它的父级。
因此,一般的答案是:不,你不能那样做。
但是,让我们戴上黑客帽吧!
你已经是特工了。作为代理,您要做的事情之一是在类被加载时“见证”它们。只需调用. addTransator
在您的agentmain
中获得的仪表实例并注册一个。
当您注意到正在加载程序
类时,请执行以下操作:
编程方法
或诸如此类的类作为容器——里面的一切都是为程序使用/为您的将代理人“注入”到那个程序中。编程方法
,并使其成为目标类的完全限定名称。 这100%保证您不可能遇到任何模块或类路径边界问题,并且它将适用于任何类加载器抽象,保证,但有一些警告:
IdentityHashMap
创建假实例字段(例如静态IdentityHashMap
这都是非常复杂的事情,但您似乎已经解决了如何注入INVOKESTATIC调用,所以,我认为您知道如何做到这一点。
这正是lombok在eclipse中“修补”某些方法所做的,以确保保存操作、自动格式化、,语法突出显示不中断-lombok在适当的地方注入生成注释的知识,并以这种精确的方式进行,因为eclipse使用了一个名为Equinox的类加载器平台,这使得任何其他解决方案都有问题。你可以从中寻找灵感或指导方针,尽管它并没有很好的文档记录。您特别关注:
lombok。日食代理
eclipseent中的包
sourceroot
请注意,您可能还会对下一个方法感兴趣:lombok.patcher的“插入”不会移动方法——它直接在那里注入方法的主体(“内联”)。这需要对堆栈进行一些严重的欺骗,并且只建议用于极其简单的一行式方法,并且对于这个问题可能是过度和不必要的火力。
免责声明:大部分是我写的。
让代理监听新ClassLoaders的创建,然后将它们的实例附加到新ClassLoaders。
通过这种方式,您可以保留“代理侦听类加载器”接口,即使它现在扩展到您希望代理侦听的一个平台类加载器之外。
问题内容: 我是Java UI编程的新手。 如何在Java中从主类调用UI类 基本上 运行程序时如何加载GUI。目前,当我运行代码时什么也没有发生。 GUI CLass 根据评论中的要求,我已经上传了GUI类代码 问题答案:
如果我有一个内部类声明,例如: 其次是: A$B内部类也会加载吗?如果B内部类没有被声明为“静态”呢?
因此,我有一个类加载器加载一个类,如下所示: 类在运行时位于另一个jar中。以及是在主jar中生成的,然后我取消了它的归档,所以依赖项就在那里。 如何从外部访问其他依赖项。我加载的类文件? 例外情况:
问题内容: 我正在使用一些第三方代码,这些代码在给定“ -classpath”命令行参数时不会设置java.class.path,而是仅创建一个类加载器,将命令行中指定的类路径中所有项的所有url添加到类加载器,然后将其设置为上下文类加载器。在我编写的此代码的插件类中,我获得了该类加载器的实例,并且需要以某种方式使用它来获取基础类路径,以便可以在JavaCompiler.getTask(… ),并
问题内容: 有谁知道如何以编程方式找出java类加载器实际从何处加载类? 我经常在大型项目中使用类路径,并且手动搜索并不是一个好的选择。我最近遇到了一个问题,其中类加载器正在加载不正确的类版本,因为它位于两个不同位置的类路径上。 那么,如何让类加载器告诉我实际的类文件来自磁盘上的什么地方呢? 编辑:如果类加载器由于版本不匹配(或其他原因)而实际上无法加载该类,该怎么办,在读取它之前我们是否能找出它
我一直在Java玩简单的自定义类加载器,到目前为止,对于非模块相关的类来说,一切都按照预期工作。但是,我似乎找不到任何方法来使用我的类加载器从模块加载类,即使与模块相关的方法已经被重载。我尝试做的是从模块“HelloModularWorld”加载一个类,并运行它的main。然而,当我指定包所在的目录时,它将“正常”加载,并报告为在未命名模块中。我错过了什么? 类加载器只是从文件系统的其他地方加载类