【问题标题】:Remote execution client possible with ASM?ASM 可以远程执行客户端吗?
【发布时间】:2015-03-17 11:45:57
【问题描述】:

我希望为我的应用创建自定义远程执行客户端。客户端可能看起来像这样:

interface Client {

    <T> T computeRemotely(Function<List<MyBigObject>, T> consumer)
}

可能会这样使用:

Client client = new Client();
Integer remoteResult = client.computeRemotely(list -> {
    Integer result = -1;

    // do some computational work here.

    return result;
});

这意味着我需要以某种方式从客户端获取 lambda,将其发送到服务器,运行函数(传入真实的 List&lt;MyBigObject&gt;)并将结果发回。

值得注意的是,使用我的客户端库的一个限制是您不能在该 lambda 中使用 JDK 之外的任何东西并期望它能够工作(因为这些类可能不在服务器上的类路径上)......但我希望他们能够使用任何 JDK 类将自己的数据引入计算。

现在我不能只序列化 Function&lt;MyBigObject, T&gt; lambda,因为它像内部客户端一样序列化 lambda 存在于其中的任何类都不会在服务器上的类路径上。

所以我一直在研究 ASM,看看这是否可行。鉴于我以前从未做过字节码操作,我只是想检查一下我所说的是否正确:

  • 我可以使用 ASM 转换为读取 lambda 所在的类。
  • 使用方法访问器,获取方法字节,将它们发送到服务器
  • 使用 ASM 从字节创建实例并执行它。

鉴于 lambda 就像一个匿名内部类,我猜我也必须在其中进行某种方法重命名..

这大致正确还是我完全搞错了?

【问题讨论】:

  • 我不熟悉 lambda 实现,所以不确定是否需要重命名。但如果是这样,您需要在任何地方重命名 - 特别是在方法的字节码中 - 对重命名类的字段和方法的任何访问。也许不是那么难,但要牢记在心。有 Remapper 和 org.objectweb.asm.commons.RemappingClassAdapter 类,它们似乎能够处理重命名。

标签: java lambda java-bytecode-asm


【解决方案1】:

请注意,lambda 可以从其上下文中访问所有不可变值。因此,您需要禁止访问外部值(这将严重限制您的解决方案的有用性)或识别它们并发送这些值的表示(遇到您提到的问题;它们的实现可能在服务器类路径之外) .

因此,即使您发送方法表示(您甚至不需要 ASM;您可以直接从类加载器获取资源),它也不适用于一般情况。

编辑:根据您的评论,它可以工作。你需要用

合成一个类
  • 作为最终字段的上下文属性
  • 带有所有字段参数的构造函数(您将在构造函数中传递反序列化的值)
  • lambda 方法 — 见 this question for details

【讨论】:

  • 我打算做的是允许访问属于 JDK 的任何不可变值(即列表、集合等...),但不允许访问自定义类。
【解决方案2】:

分析运行时生成的 lambda 表达式类毫无意义。它们具有非常简单的结构,在序列化时会显示出来。在序列化期间,它们将被替换为 SerializedLambda 实例,其中包含您可以收集的所有信息,最值得注意的是:

关键是目标方法。对于 lambda 表达式(与方法引用不同),目标方法是一种合成方法,位于包含 lambda 表达式的类中。顺便说一下,那个方法是private,这就是为什么尝试复制调用该方法的类注定要失败的原因,需要特殊的 JVM 交互才能创建这样的类。但重要的一点是您需要远程端的 目标方法 来执行它,lambda 特定的运行时类是无关紧要的。如果你有目标方法,可以create the lambda instance without third party libraries

当然,您可以使用 ASM 分析目标方法的代码以将其(以及所有依赖项)传输到远程端,但请注意,这与传输任意 Function 实现没有区别;事实上,有一层通过 lambda 表达式创建的运行时生成的类对您没有任何帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-17
    • 2018-05-25
    • 2019-01-28
    • 2018-08-31
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多