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

Modify library class at runtime - java/maven

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

库代码应该使用我的 'new' class,我希望能够使用 getter 来检索一些额外的信息。

此 class 的实例是在 库代码中创建的(我不是在我的代码中创建它们,我只需要访问它们)。 Class 是非最终的 public class。

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

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

有一个名为 "Parser" 的库 class 可以实例化和填充一些 "Element" 实例。我的代码如下所示:

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

Parser.parse() 方法对每个元素调用 "Element.setProperties(List properties)"。 我希望能够丰富 setProperties 方法来存储原始属性列表(否则会丢失)

谢谢 朱利奥

你的建议听起来有点老套,一般来说,如果不从 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
}

现在您的用户将看到相同的界面,外加一种适用于您的领域的新方法。此答案假定所讨论的 class 不是 final.

最后我用byte-buddy 得到了想要的结果(我不知道这是否是最好的解决方案但它有效):

  1. 工具库 class (library.Element) 使用 'rebase' 策略将方法 'setProperties' 调用委托给拦截器。

注意:当library.Element.class尚未加载时,这必须作为maven插件执行的第一条指令完成(我没有'不想使用 JVM 代理)

  1. 将上面的拦截器定义为一个class,将原始的'properties'值存储在全局映射中(键=对象的身份哈希码,值=属性)和然后调用library.Element

  2. 原来的'setProperties'方法
  3. 更改我的代码以从地图获取属性,而不是 library.Element getter(我已经有了这个 class 的包装)。

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