【问题标题】:Allow Eclipse to recognize standard library JDK11 patched module允许 Eclipse 识别标准库 JDK11 补丁模块
【发布时间】:2019-06-06 05:44:03
【问题描述】:

出于好奇,我正在尝试设置 Eclipse 以允许它编译和运行一个应用程序,其中包含一个正在修补的标准库类。

我有 2 个 Java 项目 patchconsumer:一个包含字符串补丁类(使用新方法 size(),与 length() 相同),另一个应该使用上述方法 size()。设置如下:

- patch
  - bin (contains class files)
  - src
    - java
      - lang
        - String.java

- consumer
  - src
    - consumer
      - Main.java
      - module-info.java

Main.java:

package consumer;
public class Main {
    public static void main(String[] args) {
        String s  = new String("hello");
        System.out.println(s.size());
    }
}

编译patch(从而在patch/bin/java/lang/中得到String.class)我知道我可以轻松使用:

java --patch-module java.base=patchpjt/bin/  consumer/src/consumer/Main.java

正确调用新添加的方法size(),得到5的结果。

问题是在 Eclipse 中方法 size 仍然无法识别(错误是 Method Size() is underfined for type String):

所以我的问题是:

  • 如何配置 Eclipse 以使项目consumer 正确编译、运行并且不显示错误?
  • 如何配置 Eclipse 以便在 Content Assist 上显示方法 size()

我知道我需要使用Build Path -> Module Path -> Edit Is Modular -> Details Tab -> Patched module,但我不知道如何配置这两个项目。

一些您可能会觉得有用的信息:

  • Eclipse 2018-12 (4.10.0) 版本号:20181214-0600

感谢您的友好回复。

【问题讨论】:

  • 您是如何设置包含补丁的 Eclipse 项目的?它仅在尝试通过创建一个非模块化项目来修补非 jdk 模块时才对我有用,该项目依赖于我要在类路径上定义的模块,而不是在模块路径上。然而,对于 JRE,Eclipse 不允许我将它添加到类路径中......好吧.. 它允许它,但后来不知何故决定将它自己再次移动到模块路径中。因此,我总是得到“包 java.lang 与可从另一个模块访问的包冲突:java.base”。有什么提示吗?

标签: java eclipse java-11 eclipse-2018-12


【解决方案1】:

您使用的不是--patch-module (JEP 261: Module System):

--patch-module 选项仅用于测试和调试。 强烈建议不要在生产环境中使用它。

在您的场景中,您不会修补现有方法,而是添加一个破坏系统库 API 的附加方法。 Eclipse 只支持打补丁而不破坏系统库的API。在我看来,javac 没有显示任何错误(可能是由于缺少检查 API 不会被破坏)这一事实是一个错误。

如果您创建自己的 JRE,请将其添加到 Window > Preferences: Java > Installed JREs 并确保在创建新 Java 项目时不要选择 执行环境 JRE,但您的特定 JRE

【讨论】:

  • 感谢您的回复。我正在关注this 之类的东西向库中添加方法(主要是List.firstOrFail() 等集合中的有用方法)。从 Java11 开始,我想知道模块系统如何实现这一点,因为 rt.jar 不再存在。愿意提出一些想法(或者这样做很愚蠢)?
  • 我估计扩展标准库的维护成本太高了。相反,我会将附加功能放在单独的包中,这些包的类和接口扩展了标准类。例如,类似于 Eclipse Collections 所做的。
  • @howlger:虽然 JEP 表示不鼓励这样做,但我找不到任何关于不支持的信息,因为它破坏了 API。事实上,我什至不认为添加新方法会破坏 API。放弃一个肯定会,对我来说也是修改现有方法并改变行为。所以我仍然不明白为什么不支持上述用于有目的的测试和调试目的的原因。正是在那里(测试时)我可能想尝试一种新方法的执行方式。还是我错过了什么?
  • @HaasipSatang 如果将方法添加到系统库的类并在应用程序中使用,应用程序将无法再使用未修改的 JRE 运行。从系统库的角度来看,API 已经被扩展,但是如果应用程序使用了扩展,它就不再坚持给定的 API(这就是我的意思它破坏了 API)。如果要更改系统库,则不应将其与应用程序代码混合。 --patch-module,顾名思义,就是打补丁,而不是扩展系统库。
  • @HaasipSatang 在the dialog that is shown here as second (sub)dialog 我检查了修补现有模块 并输入java.base 以测试修复并创建补丁JAR。恕我直言,扩展应该作为系统库之外的单独框架开发,而不是破坏现有模块的封装。
猜你喜欢
  • 1970-01-01
  • 2016-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多