【发布时间】: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<MyBigObject>)并将结果发回。
值得注意的是,使用我的客户端库的一个限制是您不能在该 lambda 中使用 JDK 之外的任何东西并期望它能够工作(因为这些类可能不在服务器上的类路径上)......但我希望他们能够使用任何 JDK 类将自己的数据引入计算。
现在我不能只序列化 Function<MyBigObject, T> lambda,因为它像内部客户端一样序列化 lambda 存在于其中的任何类都不会在服务器上的类路径上。
所以我一直在研究 ASM,看看这是否可行。鉴于我以前从未做过字节码操作,我只是想检查一下我所说的是否正确:
- 我可以使用 ASM 转换为读取 lambda 所在的类。
- 使用方法访问器,获取方法字节,将它们发送到服务器
- 使用 ASM 从字节创建实例并执行它。
鉴于 lambda 就像一个匿名内部类,我猜我也必须在其中进行某种方法重命名..
这大致正确还是我完全搞错了?
【问题讨论】:
-
我不熟悉 lambda 实现,所以不确定是否需要重命名。但如果是这样,您需要在任何地方重命名 - 特别是在方法的字节码中 - 对重命名类的字段和方法的任何访问。也许不是那么难,但要牢记在心。有 Remapper 和 org.objectweb.asm.commons.RemappingClassAdapter 类,它们似乎能够处理重命名。
标签: java lambda java-bytecode-asm