在运行时修改库类 - java / maven

时间:2017-10-27 11:29:09

标签: java maven byte-buddy

我正在使用Maven插件,我需要修改一个外部jar类(在maven执行期间使用),添加:

  • 此课程的新字段
  • 该领域的吸气剂
  • 现有setter填充字段的一些行为

图书馆代码应该使用我的新版' class,我希望能够使用getter来检索一些额外的信息。

此类的实例是在库代码中创建的(我没有在我的代码中创建它们,我只需要访问它们)。 班级是非最终的公共班级。

你知道这是否可行,哪种方法最好?可以用ByteBuddy做到吗?

编辑:我无法包装该类,因为它没有在我自己的代码中实例化,让我详细说明一下。

有一个名为" Parser"的图书馆类。实例化并填充一些"元素"实例。我的代码如下:

List<library.Element> elements = new library.Parser(file).parse();

Parser.parse()方法调用&#34; Element.setProperties(List properties)&#34;在每个元素上。 我希望能够丰富setProperties方法来存储原始属性列表(否则将丢失)

由于 Giulio的

2 个答案:

答案 0 :(得分:1)

最后,我设法用byte-buddy获取想要的结果(我不知道它是否是最好的解决方案,但它有效):

  1. 仪器库类(library.Element)使用'rebase'策略将方法'setProperties'调用委托给拦截器。
  2. 注意:当尚未加载library.Element.class时,这必须作为maven插件执行的第一条指令完成(我不想使用JVM代理)

    1. 将上面的拦截器定义为一个类,它将原始“属性”值存储在全局映射中(key =对象的身份哈希码,value = properties),然后调用库的原始“setProperties”方法.Element

    2. 更改我的代码以从地图中获取属性,而不是library.Element getter(我已经有了这个类的包装器)。

    3. 如果有人有兴趣,我可以展示一些代码。

答案 1 :(得分:0)

你的建议听起来有点hackish,一般来说,如果不从JAR生成源代码,修改它们,然后重新打包,你甚至不可能做什么。如果我遇到这个问题,我会考虑使用装饰模式。您可以创建一个公开JAR所有方法的包装器,除了它会添加一个额外的字段以及一个getter和setter。

import com.giulio.old.jar.everything.*;

public class WrapperOfJar {
    private String newField;

    public String getNewField() { // ... }
    public void setNewField() { // ... }

    // all getters and setters from current JAR
}

现在,您的用户将看到相同的界面,并为您的字段添加一种新方法。这个答案假设有问题的课程不是final