当前位置: 首页 > 面试题库 >

用自定义版本替换Java类库中的类

松建本
2023-03-14
问题内容

BasicLabelUI的javax /秋千/ PLAF /基本
是通过影响已确认的bug。在我的应用程序中,我
需要
固定版本(适用于v9)提供的功能。由于法律和技术方面的原因,我仍然受受影响的JDK版本的约束。

我的方法是在项目内部创建一个包含固定版本的包 javax / swing / plaf / basic

与已安装的JDK中的缺陷类相比,我该如何强迫我的项目偏爱包含的类版本?

这必须具有一定的可移植性,因为固定类也必须在客户端使用,并且必须忽略JDK安装中的缺陷类。因此,我不想修改JDK,而是绕过此特定类。


问题答案:

正如其他的答案中提到,您 可能 在过程中解压缩到JVM的理论 rt.jar的 文件,并兼容bugfixed版本替换该文件。

引导类加载 会加载Java类库的所有类(例如Swing的 类),该类加载器 会从 rt.jar
查找其类。如果不将类添加到此文件中,通常不能将它们添加到 该类 路径中。有(非标准)VM选项

-Xbootclasspath/jarWithPatchedClass.jar:path

您可能会在其中添加一个包含修补程序版本的jar文件,但这在任何Java虚拟机上都不一定有效。另外, 部署 更改此行为 的应用程序 也是
非法的
!如官方文档中所述:

不要部署使用此选项覆盖rt.jar中的类的应用程序,因为这违反了Java Runtime Environment二进制代码许可证。

但是,如果您将一个类附加到引导类加载器(通过使用仪表API不使用非标准API的情况下可以实现),则运行时仍会加载原始类,因为引导类加载器在这种情况下首先搜索
rt.jar 。因此,如果不修改此文件就无法“遮盖”损坏的类。

最后,分发带有补丁文件的VM(即将其放入客户的生产系统中)始终是非法的。许可协议明确指出您需要

[…]完整且未经修改地分发[Java运行时],仅捆绑为小程序和应用程序的一部分

因此,不建议更改分发的VM,因为一旦发现它,您可能会面临法律后果。

当然,从理论上讲,您可以构建自己的OpenJDK版本,但是在分发二进制 Java
时,您再也不能调用它了,并且我认为您的客户在您的回答中所建议的不允许这样做。根据经验,许多安全环境会在执行之前计算二进制哈希,这将阻止两种方法来调整正在执行的VM。

对您而言,最简单的解决方案可能是创建一个Java代理,然后在启动时将其添加到VM进程中。最后,这与将库添加为类路径依赖项非常相似:

java -javaagent:bugFixAgent.jar -jar myApp.jar

启动应用程序时,Java代理能够替换类的二进制表示形式,因此可以更改越野车方法的实现。

在您的情况下,代理将如下所示,您需要将修补的类文件作为资源包括在内:

public static class BugFixAgent {
  public static void premain(String args, Instrumentation inst) {
    inst.addClassFileTransformer(new ClassFileTransformer() {
      @Override
      public byte[] transform(ClassLoader loader, 
                              String className, 
                              Class<?> classBeingRedefined, 
                              ProtectionDomain protectionDomain, 
                              byte[] classfileBuffer) {
        if (className.equals("javax/swing/plaf/basic/BasicLabelUI")) {
          return patchedClassFile; // as found in the repository
          // Consider removing the transformer for future class loading
        } else {
          return null; // skips instrumentation for other classes
        }
      }
    });
  }
}

javadoc
java.lang.instrumentation软件包提供了有关如何构建和实现Java代理的详细描述。使用这种方法,您可以使用相关类的固定版本,
而不会违反许可协议

从经验来看,Java代理是修复第三方库和Java类库中的临时错误的好方法,而无需部署代码中的更改,甚至不需要为客户部署新版本。实际上,这是使用Java代理的典型用例。



 类似资料:
  • Subversion 版本库的定义 在进入版本库管理这块宽泛的主题之前,让我们进一步确定一下版本库的定义,它是怎样工作的?让人有什么感觉?它希望茶是热的还是冰的,加糖或柠檬吗?作为一名管理员,你应该既能够从物理具体细节的视角-版本库如何响应一个非Subversion的工具,也能够从逻辑视角-数据在版本库中如何展示。 通过典型的文件浏览器应用程序或命令行为基础的文件系统浏览工具查看,Subversi

  • 我试图将jasper reports library()作为maven依赖项添加到我的项目中,不幸的是,它的一个依赖项有点不典型,不能位于maven Central中。但是,我发现它可以在http://jasperreports.sourceforge.net/maven2/com/lowagie/itext/上找到。 我的问题是: > jaspersoft自定义构建iText的目的是什么?帕琪丝

  • 如果您是经验丰富的ML开发人员,并且预构建的TensorFlow Lite库不能满足您的需求,则可以使用ML Kit 自定义TensorFlow Lite版本。例如,您可能想要添加自定义操作。 先决条件 一个可用的TensorFlow Lite构建环境 检出(checkout)0.1.7的Tensorflow Lite 你可以通过使用git检出正确版本: $ git checkout -b wor

  • 我试图按照上一个答案中的建议设置和变量,但没有结果。

  • 问题内容: 如何导入在其他文件中编写的类?我所有的课程都在同一个程序包下。 问题答案: 如果所有类都在同一个程序包中,则无需导入它们。 只需像这样实例化该对象:

  • 正确的方法是什么?