如何在 JAR 清单文件中指定类路径加载顺序

How to specify classpath loading order in a JAR manifest file

我正在使用 Ant 制作 JAR 文件,但我需要为在 Manifiest 文件中生成的 JAR 文件指定类路径加载顺序。

这是因为我有一些依赖使用了另一个库的不同版本,我需要确保加载最新的。使用 Eclipse 界面很容易,但我不确定如何使用 Ant 来做到这一点。

这是我现在拥有的 JAR 任务:

<target depends="build-project" name="jar">
            <!-- Get the timestamp -->  
            <set.timestamp/>
            <!-- Create our own manifest file for our JAR -->
            <manifest file="MANIFEST.MF">
                <attribute name="Built-By" value="${username} - ${company.name}"/>
                <attribute name="Main-Class" value="some.package.Main"/>
                <attribute name="Class-path" value=". ${lib.list}"/> 
                <attribute name="Implementation-Version" 
                    value="${major.version.number}.${minor.version.number}.${revision.number}"/>   
                <attribute name="Built-Date" value="${current.time}"/>                 
            </manifest>

            <jar whenmanifestonly="fail" destfile="${dist.dir}/${jar.name}_${major.version.number}.${minor.version.number}.${revision.number}.jar" manifest="MANIFEST.MF">
</target>

现在这是类路径属性:

<manifestclasspath property="lib.list" jarfile="${dist.dir}/${jar.name}_${major.version.number}.${minor.version.number}.${revision.number}.jar">
   <classpath refid="manifest.classpath" />
</manifestclasspath>

这是 manifest.classpath:

<!-- Manifest classpaht -->
<path id="manifest.classpath">
    <fileset dir="${dist.dir}/lib">
          <include name="*.jar"/>
      </fileset>
</path>

在我看来,我必须在上面一个一个地手动定义每个库,而不是使用通配符...但是之后会保持该顺序吗?

谢谢! 亚历杭德罗

据我所知,清单中的类路径将使用按照您提供的顺序排列的条目定义。我知道它在 Maven 中是这样工作的,并且很确定在 Ant 中也是如此,所以你可以做的是先提供 "critical" 条目 - 然后放置通配符,从而提供所需的顺序 - 而不是手动定义所有必需的依赖项。

定义类路径时,可以在该路径中复制 jar,就像在 $PATH 中复制目录一样。虽然马虎,但还不错:

PATH="/bin:/usr/bin:$HOME/bin:/usr/local/bin:/bin"

/bin 目录被指定了两次,但这并不重要。如果我指定 ls,我的 $PATH/bin 的第一个实例将找到它。我的 $PATH 中的最后一个 /bin 实例没有执行任何操作。复制没有真正的伤害。

如果您需要指定某些 jar 必须位于第一个的类路径,请先指定您需要的内容。如果 $PATH 再次包含该特定的 jar 名称,则无关紧要:

 <path id="manifest.classpath">
     <pathelement location="${first.jar}"/>
     <pathelement location="${second.jar}"/>
     <fileset dir="${manifest.jars.dir}"/>
</path>

即使${first.jar}${second.jar}在那个${manifest.jars.dir}里面也没关系。它们仍然会在您的路径中首先被拾取,然后在您的路径中被忽略。

现在,您可以这样做:

<manifestclasspath property="manifest.path">
    <pathelement location="."/>
    <classpath refid="manifest.classpath"/>
</manifestclasspath>

最后:

<jar destdir="....">
    <manifest>
        <attribute name="Class-path" value="${manifest.path}"/>
        ...
    </manifest>
</jar>