禁用java清单文件中的类路径

禁用java清单文件中的类路径,java,classpath,manifest,Java,Classpath,Manifest,我正在开发一个具有自动更新功能的软件,即使用户没有对安装文件夹的写入权限,该软件也能工作。 为此,应用程序分析类路径,并检查在单独的用户目录中,类路径中的条目是否有较新的JAR文件。在这种情况下,应用程序将生成一个修改后的类路径,并使用该类路径启动一个新的VM 当java默认类加载器通过插入清单文件中提到的库来更改JAR文件的顺序时,就会出现我的问题 我将给你一个简单的例子,它缺少很多细节,对于真正的更新场景来说没有意义,但它将解释我的问题。所以我们假设我不允许更改main.jar的内容 我用

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

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

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

我用

java -jar main.jar
main.jar有一个适当的清单文件,其中包含主类和类路径,并引用其他库c.jar和d.jar

因此,运行时的完整类路径为:

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

因此,应用程序现在计算新的类路径:

main.jar, a.jar, b.jar, c.jar, d.jar
java -cp main.jar:a.jar:b.jar:c.jar:d.jar <Main-Class>
同样,顺序很重要,因为a.jar重写了d.jar中的类。 现在,应用程序使用显式类路径启动一个新VM:

main.jar, a.jar, b.jar, c.jar, d.jar
java -cp main.jar:a.jar:b.jar:c.jar:d.jar <Main-Class>
按照这个顺序,c.jar现在比a.jar具有更高的优先级。并且不会加载a.jar中的重写类

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


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

这只是一个快速且未经测试的想法。如果您能够在运行时动态加载更新的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加载到该类加载器中。在实例化一个类时,您会对自定义类装入器进行优先级排序,并在默认类装入器上进行故障切换


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

很有趣。我一直认为当不使用-jar时,类路径属性会被忽略。如果您只调用
java-cpa.jar:b.jar:main.jar:c.jar:d.jar
,会怎么样?