【问题标题】:Disabling Class-Path from Manifest-Files java从清单文件 java 中禁用类路径
【发布时间】:2014-07-01 17:29:26
【问题描述】:

我正在开发一个具有自动更新功能的软件,即使用户对安装文件夹没有写入权限,它也能正常工作。 为此,应用程序分析类路径并检查在单独的用户目录中类路径中的条目是否存在更新的 JAR 文件。在这种情况下,应用程序会生成一个修改后的类路径并使用该类路径启动一个新 VM。

当 java 默认类加载器通过插入清单文件中提到的库来更改 JAR 文件的顺序时,就会出现我的问题。

我会给你一个简化的例子,它缺少很多细节,对于真正的更新场景没有意义,但它会解释我的问题。所以假设我不允许更改 main.jar 的内容。

我启动应用程序

java -jar main.jar

main.jar 有一个适当的 MANIFEST 文件,其中包含 Main-Class 和 Class-Path,引用了附加库 c.jar 和 d.jar。

因此,运行时完整的 Class-Path 将是:

main.jar, c.jar, d.jar

顺序很重要,因为 main.jar 会覆盖 c.jar 中的类。 现在应用程序发现有可用的更新,这需要额外的库 a.jar 和 b.jar。

所以应用程序现在计算新的类路径:

main.jar, a.jar, b.jar, c.jar, d.jar

同样,顺序很重要,因为 a.jar 会覆盖 d.jar 中的类。 现在应用程序启动一个带有显式类路径的新 VM:

java -cp main.jar:a.jar:b.jar:c.jar:d.jar <Main-Class>

不幸的是,java 通过在 main.jar 的位置插入由 main.jar 的 MANIFEST 引用的库来更改类路径。所以有效的类路径是:

main.jar, c.jar, d.jar, a.jar, b.jar, c.jar, d.jar
--------  ------------  --------------------------
   CP       MANIFEST                CP  

使用该顺序,c.jar 现在比 a.jar 具有更高的优先级。并且不会加载来自 a.jar 的覆盖类。

这个问题的明显解决方案是提供一个没有清单的 main.jar。 但这会导致其他问题,我想避免。

我的问题是:有没有办法在搜索类路径时禁用 java 的行为以包含清单中引用的 JAR 文件?

【问题讨论】:

  • 有趣。我一直认为不使用-jar时Class-Path属性会被忽略。
  • 如果你只是打电话给java -cp a.jar:b.jar:main.jar:c.jar:d.jar &lt;Main-Class&gt; 怎么办?

标签: java classpath manifest


【解决方案1】:

只是一个快速且未经测试的想法。如果您能够在运行时动态加载更新的 jar,而不是在命令行中指定它们,您可以为这些 jar 创建一个 URLClassLoader 并使用该自定义类加载器显式加载您的类:

URL[] jarurls = new URL[]{jar1,jar2,...};
URLClassLoader customCL= new URLClassLoader (jarurls, getClass().getClassLoader());
Class clazz = Class.forName ("com.blablabla.MyClass1", true, customCL);
MyClass1 instance = (MyClass1)clazz.newInstance();

您可以将驻留在用户文件夹中的每个 jar 加载到该类加载器中。当实例化一个类时,你会优先考虑你的自定义类加载器和默认的故障转移。

这肯定会给您的设计增加复杂性/风险,因为现在需要通过反射来实例化类。

【讨论】:

    猜你喜欢
    • 2015-11-20
    • 1970-01-01
    • 2010-10-18
    • 2012-04-29
    • 2013-05-28
    • 2015-05-17
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多