尝试使用ByteBuddy

时间:2017-08-04 22:25:18

标签: java byte-buddy

在我说什么之前,我要感谢开发人员花时间为Byte Buddy做文档。我知道这可能是多么乏味,我很感激。

但是我仍然在进行转换时遇到一些麻烦。我做了很多搜索,但那里没有很多。

目前我使用的是javassist。该系统可以工作,但它只缺少某些区域并产生大量开销。我认为字节伙伴可能是解决方案。但是我正在处理的项目必须是运行时代码转换。它需要在现场环境中保持稳定,因此热交换器不是我想要的(但我发现在测试环境中使用相同的系统非常棒)。

问题是我需要在某些时候抓取类,并加载几个,这样我就可以在加载过程中的适当时刻注入我的插件。

在javassist中,(注意这只是非常开始)它开始时是这样的:

public static void main(String[] args) {
    try {

        initLogger();

        Loader loader = HookManager.getInstance().getLoader();
        loader.delegateLoadingOf("javafx.");
        loader.delegateLoadingOf("com.sun.");
        loader.delegateLoadingOf("org.controlsfx.");
        loader.delegateLoadingOf("impl.org.controlsfx");
        loader.delegateLoadingOf("com.mysql.");
        loader.delegateLoadingOf("org.sqlite.");
        loader.delegateLoadingOf("com.xyp.modloader.classhooks.");
        loader.delegateLoadingOf("javassist.");

        Thread.currentThread().setContextClassLoader(loader);

        loader.run("net.xyp.modloader.DelegatedLauncher", args);
    } catch (Throwable e) {
        Logger.getLogger(ServerLauncher.class.getName()).log(Level.SEVERE, e.getMessage(), e);
        e.printStackTrace();
        System.exit(-1);
    }

}

然后代码继续进入插件注入系统中的其他类。这会调用更多的类,并在适当的时刻触发注入系统中的方法,这些方法调用需要在那些时刻插入的插件。

示例2类进入系统此方法被称为public void

public void fireOnServerStarted() {
    ModComm.serverStarted();
    serverStarted.fire(listener -> listener.onServerStarted());
}

当它触发系统具有插件所针对的接口时,告诉系统它是注入这些插件的正确时机。这发生在几个不同的状态,并且它们在正确的时间发射是非常重要的。出于某种原因,我只是没有理解如何用Byte Buddy来做这件事,我认为这是因为所有的例子只是一个方法或字段被加载。

我仔细阅读了这篇文章,因为有人可能会找到一个我没有遇到过的解决方案。但是在这个时候做了更多的研究,我觉得Byte Buddy并没有包含我从Javassist那里用来做我想要转换的最重要的功能。愿意听取其他选择!

1 个答案:

答案 0 :(得分:0)

我不清楚我是否理解你的问题但是根据我的理解,你试图委托给几个类加载器作为父类加载器?

Byte Buddy为此目的提供MultipleParentClassLoader。您发布的示例代码不包含Javassist代码,因此我无法向您提供更具体的建议。