58

我有一个 jar,其内容如下所示,

在此处输入图像描述

下面是我的清单文件

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.3
Created-By: 1.7.0_06-b24 (Oracle Corporation)
Main-Class: org.sai.com.DerbyDemo
Class-Path: derby.jar derbyclient.jar derbynet.jar derbytools.jar

当我尝试运行 jar 时,它抛出了一个ClassNotFoundExcception含义,它没有引用外部 jar 中的 jar。

Class-Path属性中,如何derby.jar在实际 jar 中引用 jars(等)?

4

7 回答 7

39

为此,您将需要一个自定义类加载器,请查看One Jar

One-JAR 允许您将 Java 应用程序及其依赖项 Jar 打包到单个可执行 Jar 文件中。

它有一个蚂蚁任务,它也可以简化它的构建。

参考(来自背景

大多数开发人员合理地假设将依赖项 Jar 文件放入他们自己的 Jar 文件中,并将 Class-Path 属性添加到 META-INF/MANIFEST 即可


jarname.jar
| /META-INF
| |  MANIFEST.MF
| |    Main-Class: com.mydomain.mypackage.Main
| |    Class-Path: commons-logging.jar
| /com/mydomain/mypackage
| |  Main.class
| commons-logging.jar

不幸的是,这是行不通的。JavaLauncher$AppClassLoader不知道如何使用这种Class-Path. 试图使用jar:file:jarname.jar!/commons-logging.jar也会导致死胡同。这种方法只有在您将支持的 Jar 文件安装(即分散)到安装 jarname.jar 文件的目录中时才有效。

于 2012-09-10T18:36:39.090 回答
24

你不能。来自官方教程

通过在清单中使用 Class-Path 标头,您可以避免在调用 Java 来运行应用程序时必须指定 long -classpath 标志。

注意:Class-Path 标头指向本地网络上的类或 JAR 文件,而不是 JAR 文件中的 JAR 文件或可通过 Internet 协议访问的类。要将 JAR 文件中的 JAR 文件中的类加载到类路径中,您必须编写自定义代码来加载这些类。例如,如果 MyJar.jar 包含另一个名为 MyUtils.jar 的 JAR 文件,则不能使用 MyJar.jar 清单中的 Class-Path 标头将 MyUtils.jar 中的类加载到类路径中。

于 2012-09-10T18:37:15.033 回答
14

在 Eclipse 中,您可以选择导出可执行的 jar。 在此处输入图像描述 您可以选择将所有与项目相关的 jar 打包到生成的 jar 中,这样 eclipse 添加自定义类加载器,它将引用您在新 jar 中集成的 jar。

在此处输入图像描述

于 2015-07-07T13:16:47.253 回答
6

类加载器的默认实现无法从 jar-within-a-jar 加载:为此,必须将整个“子 jar”加载到内存中,这破坏了 jar 格式的随机访问优势(参考待定 - 一旦找到支持此的文档,我将进行编辑)。

我建议使用JarSplice 之类的程序将所有内容捆绑到一个干净的可执行 jar 中。

编辑:找不到源参考,但 Sun 网站上有一个未解决的 RFE,描述了这个确切的“问题”:http ://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4648386

此外,您可以通过将库 jar 文件放在\lib目录的classes子目录中,然后从命令行运行来“测试”您的程序是否正常工作。换句话说,具有以下目录结构:

classes/org/sai/com/DerbyDemo.class
classes/org/sai/com/OtherClassFiles.class
classes/lib/derby.jar
classes/lib/derbyclient.jar

从命令行,导航到上述“类”目录,然后键入:

java -cp .:lib/* org.sai.com.DerbyDemo
于 2012-09-10T18:44:57.883 回答
4

如果您不想创建自定义类加载器。您可以读取 jar 文件流。并将其传输到 File 对象。然后你可以得到文件的url。将其发送到 URLClassLoader,您可以根据需要加载 jar 文件。样本:

InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("example"+ ".jar");
final File tempFile = File.createTempFile("temp", ".jar");
tempFile.deleteOnExit();  // you can delete the temp file or not
try (FileOutputStream out = new FileOutputStream(tempFile)) {
    IOUtils.copy(resourceAsStream, out);
}
IOUtils.closeQuietly(resourceAsStream);
URL url = tempFile.toURI().toURL();
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url});
urlClassLoader.loadClass()
...
于 2019-08-06T09:00:12.267 回答
2

将 jar 文件添加到您的库(如果使用 netbeans)并修改清单文件classpath,如下所示:

Class-Path: lib/derby.jar lib/derbyclient.jar lib/derbynet.jar lib/derbytools.jar

类似的答案存在here

于 2013-12-07T12:52:02.050 回答
-1

在 Eclipse 中,右键单击项目,选择 RunAs -> Run Configuration 并保存您的运行配置,这将在您下次导出为 Runnable JAR 时使用

于 2017-04-20T05:58:52.650 回答