使用自建 jar 文件时出现 ClassNotFoundException
ClassNotFoundException when using a self-created jar file
我使用 Eclipse 创建了一些解析器 classes 我想将其作为 jar 存档提供给另一个项目以用于验证目的。所以解析器项目看起来像这样:
ParserProject
- src
-- com.package.x
--- ClassA
--- ClassB
- lib
-- external1.jar
-- external2.jar
ClassA
和 ClassB
使用外部 jar 存档,如 Jackson 或一些 Apache commons。为了向另一个项目提供功能,我将整个项目导出为 jar 存档和可执行 jar 存档(右键单击项目 > 导出... > Java > JAR 文件 > Select所有文件和 "Export generated class files and resources" > 完成).
jar文件创建成功,没有任何错误。当我在我的验证项目中使用 parserproject.jar
时,我可以使用自动完成访问我的所有方法,但是当我 运行 验证项目时,我得到一个 java.lang.ClassNotFoundException: com.fasterxml.jackson.core.JsonParseException
。
现在三件奇怪的事:
解析器项目中包含所有 jackson jar。此外,我可以在解析器项目中 运行 一个 main()
方法,一切正常,没有 ClassNotFoundException
发生。
当我将 parserproject.jar
添加到 class 路径中的验证项目并在 Package Explorer 中打开 jar 存档时,parserproject.jar 似乎包含它需要的所有罐子。
对于可执行 jar 存档,所有必需的外部 jar 都包含在 MANIFEST.MF
中(Package Explorer > validation project > Referenced Libraries > + 除了 parserproject.jar > META-INF > MANIFEST.MF)。它看起来像这样:
Manifest-Version: 1.0
Rsrc-Class-Path: ./ json-20140107.jar jackson-annotations-2.5.4.jar ja
ckson-core-2.5.4.jar jackson-databind-2.5.4.jar commons-io-2.4.jar co
mmons-validator-1.3.1.jar slf4j-api-1.7.5.jar slf4j-log4j12-1.7.5.jar
json-schema-validator-2.2.6.jar jackson-module-jsonSchema-2.4.4.jar
juniversalchardet-1.0.3.jar snakeyaml-1.15.jar commons-beanutils-1.7.
0.jar commons-digester-1.6.jar commons-logging-1.0.4.jar joda-time-2.
8.1.jar jopt-simple-4.6.jar jsr305-3.0.0.jar json-schema-core-1.2.5.j
ar libphonenumber-6.2.jar jackson-coreutils-1.8.jar commons-lang-2.6.
jar guava-16.0.1.jar msg-simple-1.1.jar btf-1.2.jar mailapi-1.4.3.jar
uri-template-0.9.jar
Class-Path: .
Rsrc-Main-Class: com.package.SchemeValidator
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
- 当且仅当我在我的验证项目中使用生成的 jar 文件时,我才会得到异常。如果我摆脱
parserproject.jar
并改为定义对 ecplise 解析器项目的依赖项( 右键单击验证项目 > 属性 > Java 构建路径 > 项目 ) 我没有得到 ClassNotFoundException
.
所以现在我的问题是,我应该如何导出 jar 以便找到每个 class。谢谢!
您可以考虑创建一个所谓的 fat jar,它将包含所有需要的 类。例如:http://fjep.sourceforge.net/
如果您不想经历自己管理所有依赖项的麻烦,请考虑使用像这样的构建工具
Maven https://maven.apache.org/ or Gradle https://gradle.org/.
Eclipse 仅在生成 .jar 时处理编译时依赖关系
由于您生成的 .jar 可以移动到几乎任何地方,因此在执行期间必须再次存在依赖项。
您有两个选择:
- 使用
-jar
选项执行你的 jar,同时保留所有
同一文件夹中的依赖项。由于您的清单使用“./”作为 classpath
,这意味着所有依赖项必须位于您执行 jar 的同一目录中。 注意 class路径是相对于您执行的目录,而不是文件所在的目录。
- 使用我们的
-jar
选项执行您的 jar,并指定 -cp
选项指向依赖项,并指定主要的 class.
java -cp "<path to your jar>;<path to dependency 1>;<path to dependency 3>[;...]" <your main class>
我使用 Eclipse 创建了一些解析器 classes 我想将其作为 jar 存档提供给另一个项目以用于验证目的。所以解析器项目看起来像这样:
ParserProject
- src
-- com.package.x
--- ClassA
--- ClassB
- lib
-- external1.jar
-- external2.jar
ClassA
和 ClassB
使用外部 jar 存档,如 Jackson 或一些 Apache commons。为了向另一个项目提供功能,我将整个项目导出为 jar 存档和可执行 jar 存档(右键单击项目 > 导出... > Java > JAR 文件 > Select所有文件和 "Export generated class files and resources" > 完成).
jar文件创建成功,没有任何错误。当我在我的验证项目中使用 parserproject.jar
时,我可以使用自动完成访问我的所有方法,但是当我 运行 验证项目时,我得到一个 java.lang.ClassNotFoundException: com.fasterxml.jackson.core.JsonParseException
。
现在三件奇怪的事:
解析器项目中包含所有 jackson jar。此外,我可以在解析器项目中 运行 一个
main()
方法,一切正常,没有ClassNotFoundException
发生。当我将
parserproject.jar
添加到 class 路径中的验证项目并在 Package Explorer 中打开 jar 存档时,parserproject.jar 似乎包含它需要的所有罐子。对于可执行 jar 存档,所有必需的外部 jar 都包含在
MANIFEST.MF
中(Package Explorer > validation project > Referenced Libraries > + 除了 parserproject.jar > META-INF > MANIFEST.MF)。它看起来像这样:
Manifest-Version: 1.0 Rsrc-Class-Path: ./ json-20140107.jar jackson-annotations-2.5.4.jar ja ckson-core-2.5.4.jar jackson-databind-2.5.4.jar commons-io-2.4.jar co mmons-validator-1.3.1.jar slf4j-api-1.7.5.jar slf4j-log4j12-1.7.5.jar json-schema-validator-2.2.6.jar jackson-module-jsonSchema-2.4.4.jar juniversalchardet-1.0.3.jar snakeyaml-1.15.jar commons-beanutils-1.7. 0.jar commons-digester-1.6.jar commons-logging-1.0.4.jar joda-time-2. 8.1.jar jopt-simple-4.6.jar jsr305-3.0.0.jar json-schema-core-1.2.5.j ar libphonenumber-6.2.jar jackson-coreutils-1.8.jar commons-lang-2.6. jar guava-16.0.1.jar msg-simple-1.1.jar btf-1.2.jar mailapi-1.4.3.jar uri-template-0.9.jar Class-Path: . Rsrc-Main-Class: com.package.SchemeValidator Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
- 当且仅当我在我的验证项目中使用生成的 jar 文件时,我才会得到异常。如果我摆脱
parserproject.jar
并改为定义对 ecplise 解析器项目的依赖项( 右键单击验证项目 > 属性 > Java 构建路径 > 项目 ) 我没有得到ClassNotFoundException
.
所以现在我的问题是,我应该如何导出 jar 以便找到每个 class。谢谢!
您可以考虑创建一个所谓的 fat jar,它将包含所有需要的 类。例如:http://fjep.sourceforge.net/
如果您不想经历自己管理所有依赖项的麻烦,请考虑使用像这样的构建工具 Maven https://maven.apache.org/ or Gradle https://gradle.org/.
Eclipse 仅在生成 .jar 时处理编译时依赖关系
由于您生成的 .jar 可以移动到几乎任何地方,因此在执行期间必须再次存在依赖项。
您有两个选择:
- 使用
-jar
选项执行你的 jar,同时保留所有 同一文件夹中的依赖项。由于您的清单使用“./”作为classpath
,这意味着所有依赖项必须位于您执行 jar 的同一目录中。 注意 class路径是相对于您执行的目录,而不是文件所在的目录。 - 使用我们的
-jar
选项执行您的 jar,并指定-cp
选项指向依赖项,并指定主要的 class.
java -cp "<path to your jar>;<path to dependency 1>;<path to dependency 3>[;...]" <your main class>