客户需要预览我们产品的新功能。他们要求将该功能以 jar 文件(如补丁)的形式发送给他们。将新类包含在所述 jar 文件中没有问题。但是,修改了现有类,这是集成新功能所必需的。他们只想添加这个新的 jar 文件,而不必更新我们产品的核心类。所以,问题是:是否可以使用单独的 jar 覆盖已经存在的类?如果是这样,怎么做?
提前致谢。
客户需要预览我们产品的新功能。他们要求将该功能以 jar 文件(如补丁)的形式发送给他们。将新类包含在所述 jar 文件中没有问题。但是,修改了现有类,这是集成新功能所必需的。他们只想添加这个新的 jar 文件,而不必更新我们产品的核心类。所以,问题是:是否可以使用单独的 jar 覆盖已经存在的类?如果是这样,怎么做?
提前致谢。
如果您将新 jar 放在类路径中的位置比原始 jar 更早,它就有可能起作用。值得一试,尽管它仍然听起来像是灾难的秘诀——或者至少,如果两个类都以某种方式被加载,那么很难调试问题。
编辑:我本来打算早点写这篇文章,但在火车旅行结束时被打断了......
我会回到客户那里并解释说,虽然他们的要求是可能的,但它可能会导致意想不到的问题。更新 jar 文件是一种更安全的修复方法,风险也更小。“意外问题”和“风险”这两个短语可能会给客户敲响警钟,所以希望他们能让你做正确的事情。
是也不是,这取决于您的环境。
例如,如果您使用 OSGi 并控制您的版本,则只需安装一个带有更高版本的导出包的新包(假设您的版本范围足够宽松)。
如果您使用没有花哨的自定义类加载的普通旧 Java,那么您最好早点将它放在您的类路径中(正如其他人已经提到的那样)。
如果您确实有自定义类加载,您需要确保您的“修补”类需要的所有类,以及整个传递依赖外壳,都可以从加载修补版本的类加载器中看到,这可能意味着您需要运送整个应用程序,最坏的情况。
所有规定将更新的类放在类路径中替换的类之前的所有答案都是正确的,前提是原始 JAR 没有密封或签名。
是的,可以通过将它放在类路径中比原始 jar 更早的位置来实现。然而,依赖类路径的顺序并不总能带来幸福。我不确定它是否记录在 Java 语言规范中;如果不是,那么对于不同的 JVM 甚至同一 JVM 的不同版本都会中断。
相反,请考虑引用一个现实的时间框架,将新功能集成到当前的代码库中。这可能不是您正在寻找的答案。
对于这种特定情况,可能超出了您的需要,但通常,如果您只想调整或扩充现有类,您也可以将 AspectJ 与load-time weaving一起使用。