生成的 JAR 主类抛出 ClassNotFoundException

2024-01-06

我正在使用 IntelliJ IDEA 创建一个 JAR。我为库 JAR 选择了“来自具有依赖项的模块的 JAR”和“提取到目标 JAR” - 生成的 JAR 看起来很好:

myJar.jar
  |
  +- META-INF
  |  +- MANIFEST.MF
  +- com
  |  +- my
  |     +- package
  |        +- Main.class
  +- some dependencies...

我检查了两次:所有需要的依赖项都存在。这Main-Class领域在MANIFEST.MF指向正确的主类(com.my.package.Main在此示例中)。我已在存档工具中打开该文件并使用检查它

jar tf myJar.jar

两者都表明所需的课程是可用的(也Main.class)。我已经离开了ClasspathIntelliJ 向导中的字段为空,因为我不需要任何外部库。但是,当我发出

java -jar myJar.jar

它抛出以下异常:

Error: could not find or load main class com.my.package.Main
Caused by: java.lang.ClassNotFoundException: com.my.package.Main

我已经关注了本指南由 JetBrains 提供 https://blog.jetbrains.com/idea/2010/08/quickly-create-jar-artifact/,并且 IntelliJ 自动添加来自 Maven 的所有依赖项pom.xml解压到 JAR 中,这是正确的。

我是否缺少一些我应该在这里配置的东西,为什么这不起作用?

(注意:当我为库 JAR 选择“复制到输出文件夹并通过清单链接”时,从该项目生成 JAR 也不起作用。)

(注2:使用maven-assembly-plugin遗憾的是,这不是一个选项,因为我引用了其他 IntelliJ 工作区模块,但这些模块不会被包含在内。)


Update:它应该按原样工作还显示了以下现象:当我解压缩我的 JAR 并执行

java -cp . com.my.package.Main

在创建的目录中,它工作没有任何问题,考虑到Java拒绝加载它,这很奇怪......


就我而言,由于某些已签名的 JAR 依赖项,我的 JAR 未按预期工作。

这些 JAR 带有签名和密钥文件,当您嵌入签名的 JAR 时,这些文件也会被提取。删除它们基本上没有风险,但它们是您的 JAR 无法工作的众多可能原因之一。

如何从 JAR 中删除此类签名?
我正在描述 Linux/Darwin 的以下步骤,但我认为 Windows 也有类似的方法。

  1. 打开 JAR 的包装。
    由于 JAR 只不过是简单的 ZIP 存档,因此您可以使用unzip:

    mkdir temporaryDirectory
    unzip myJar.jar -d temporaryDirectory/
    

    The -d选项是可选的,但它有助于保持目录结构干净,因为它设置目标目录。

  2. 找到签名文件。
    签名文件(或密钥)位于META-INF/目录,所以在那里改变:

    cd temporaryDirectory/META-INF/
    

    接下来,我们需要找到有问题的文件。他们有文件扩展名.SF(用于签名)和.DSA对于密钥文件:

    ll | grep '.DSA\|.SF'
    
  3. 删除(或重命名)签名和密钥文件。
    重命名这些文件的好处是您可以稍后恢复它们(无论出于何种原因),删除它们也可以解决问题,但风险更大:

    • 删除:

      rm signature.DSA signature.SF
      # Either enter the name of the files
      # instead of 'signature' or use * to delete any:
      # rm *.DSA *.SF
      
    • 重命名:

      rename 's/\.DSA$/.DSA.old/' *  # Append ".old" to all .DSA files
      rename 's/\.SF$/.SF.old/' *    # Append ".old" to all .SF files
      
  4. 重新打包你的 JAR。
    还在temporaryDirectory/,我们可以重新打包 JAR 以使它们正常工作:

    cd ../                      # If you're still in temporaryDirectory/META-INF
    jar cfm ../myWorkingJar.jar ./META-INF/MANIFEST.MF -C ./ .
    

    解释:

    • jar cfm
      jar是 Java 的内置 JAR 构建器。调用它c意味着我们要创建一个 JAR,f代表输出文件(我们接下来指定)和m是为了MANIFEST.MF我们想用。如果你省略m, jar会写一个空的MANIFEST.MF到 JAR。
    • ../myWorkingJar.jar
      这是我们想要输出 JAR 的路径。它属于f我们之前指定的。
    • ./META-INF/MANIFEST.MF
      这是我们要使用的清单文件。它属于m of cfm.
    • -C ./
      这意味着我们的.class文件位于此目录中(.).
    • .(最后一个参数)
      这指定我们要将此目录添加到 JAR 中。

    如果您想要详细说明什么jar正在做,你可以从上面发出命令cvfm代替cfm (v代表详细)。

  5. 验证它是否有效。
    一切就绪,现在您可以通过发出命令来检查您的 JAR 是否按预期工作

    java -jar myWorkingJar.jar
    
  6. 删除临时目录。
    由于您已完成 JAR 修复,因此您可以安全地删除我们创建的临时目录(和/或“损坏的”JAR)。

我创建了一个简单的 BASH 脚本,可以“自动化”此过程little bit:

#!/bin/bash
JARNAME=myJar.jar          # enter your JAR's name here
OUT_JARNAME=myJar_out.jar  # enter your output JAR's name here

# Creating the directory, unpacking the JAR, entering META-INF/
mkdir temp
unzip $JARNAME -d temp
cd temp/META-INF

# Renaming the troublemakers.
rename 's/\.DSA$/.DSA.old/' *
rename 's/\.SF$/.SF.old/' *

# Reassembling the JAR
cd ../
jar cfm ../$OUT_JARNAME ./META-INF/MANIFEST.MF -C ./ .
cd ../

# Uncomment this line if you wish to delete the temp directory upon finish.
# rm -r temp

我希望这可以帮助也遇到此问题的人们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

生成的 JAR 主类抛出 ClassNotFoundException 的相关文章

随机推荐

  • 根据项目特定情况设置函数默认值 R

    通常 我使用相同的功能设置 我想知道除了在路径中拥有一个本质上是函数包装器的新对象之外 是否还有一种方法来设置默认参数 例如 paste 有它的sep参数设置为空格 我写累了 sep 一遍又一遍 那么有没有办法 暂时 用我选择的默认值替换该
  • 如何从 SVN 的修订版本中删除 1 个文件?

    我的一位同事在 SVN 中签入了一些文件 其中一个文件中有密码 密码已从文件中删除 并签入了新版本 但如果我们查看修订历史记录并转到该修订版本 密码显然仍在存储库中 我们使用 TortoiseSVN 作为客户端 那么如何安全地从 SVN 存
  • Apple iTunes Connect Analytics:归因提供商和营销活动 ID 值传递给应用程序委托

    新的 iTunes Connect 现在具有分析功能 您可以在 URL 中指定提供商 pid ID 和活动 ID cid 例如 您可以将这些值传递到应用程序中以用于各种目的吗 即使经过检查 我也找不到任何表明这一点的内容 didFinish
  • CamelCasePropertyNamesContractResolver 在 MapHttpRoute 之后不工作

    我正在尝试在我的 Net API 项目中实现 JSON 驼峰式大小写 在我的启动类中 我添加了以下几行 config Formatters JsonFormatter SerializerSettings ContractResolver
  • ASP.NET MVC 中的模型绑定嵌套集合

    我正在使用史蒂夫 桑德森的BeginCollectionItem 帮助器 http blog stevensanderson com 2010 01 28 editing a variable length list aspnet mvc
  • Rails 3 - 如何从 link_to 创建新记录

    我正在尝试创建一个 标签 功能 允许用户 标记 他们感兴趣的项目 这是我的模型 class tag belongs to user belongs to item end 对应的DB表有必要的 user id and item id字段 在
  • 通过WebService发送电子邮件

    我在Windows上开发了应用程序 现在我需要通过 Web 服务发送一封电子邮件 包括附件功能 我怎样才能做到这一点 我还需要在 n 天之前通知电子邮件 n 天是由用户控制的功能 如果有任何意见请告诉我 Thanks public bool
  • 如何使用另一个位图作为掩码在位图上绘图?

    我想要draw在位图上使用另一个位图作为掩码 蒙版是一个黑色位图 其中有一个透明对象 我希望这个透明部分填充任意颜色并添加到我的原始图像中 如何才能做到这一点 蓝色 我必须按照 Christian 的描述更换面具 然后 可以很容易地产生想要
  • GLSL:无法获取制服位置

    我的问题是 我无法获得某些制服的位置 而其他制服的位置我却没有问题 例如 我的 VS 制服称为 MVP 和 模特 并且 MVP 位置没有问题 但我没有对称使用的 模特 位置 以同样的方式 我无法从 FS 中的 Light 结构中获取字段的位
  • DOM 突变事件库?

    当内容添加到网页时 我需要触发一个操作 更新可以具有不同的性质 例如 AJAX 延迟脚本 用户操作 并且不受我的控制 我想使用 DOM 突变事件 但它们并非在所有浏览器中都可用 是否有跨浏览器库提供后备计划 另外 我很想知道 Interne
  • 如何动态加载AttachProvider(attach.dll)

    我在用着com sun tools attach来自jdk的tools jar并且它需要一个指定的java library path环境指向attach dll在启动时正确实例化提供程序 例如WindowsAttachProvider 由于
  • 在 Android 上实现多级选项菜单的最佳实践?

    我目前正在将 iPhone 应用程序移植到 Android 上 iPhone 应用程序在屏幕底部有一个自定义的全局导航菜单 当将其移植到 Android 时 建议将此自定义菜单替换为通用选项菜单 通过设备上的选项键调用 以提供该菜单更原生的
  • Google Drive API 权限不足:请求的身份验证范围不足

    我成功完成了此处的快速入门演示 https developers google com drive api v3 quickstart python https developers google com drive api v3 quic
  • Newtonsoft.json 序列化和反序列化基本/继承,其中类来自共享项目

    所以我有两个像下面这样的课程 它们都位于同一名称空间和同一共享项目中 public class Person public string Name get set public class EmployedPerson Person pub
  • 为什么 macvim 不总是使用 ruby​​ 1.9.3?

    我已经安装了yadr 点文件 https github com skwp dotfiles 一组vim ruby等插件 我的文件中有以下 Ruby 代码行foo rb foo bar 注意我使用 ruby 1 9 3 语法进行符号赋值 定义
  • 无法将任何第三方模块与 AWS Lambdas 一起使用

    我正在开发一个使用模块 异步 请求等 的 lambda Unable to import module index Error at Function Module resolveFilename module js 338 15 at F
  • 在 PHP 中使用空格连接字符串的最佳方法

    我需要连接不确定数量的字符串 并且我希望在两个相邻字符串之间有一个空格 像这样a b c d e f 另外 我不需要任何前导或尾随空格 在 PHP 中执行此操作的最佳方法是什么 你的意思是 str implode array a b c d
  • 如何以编程方式设置静态控件背景颜色

    我想更改函数内的标签背景颜色 我尝试了这段代码 但调用后没有任何变化changecolor功能 HWND hWndLabel LRESULT CALLBACK WndProc HWND hWnd UINT message WPARAM wP
  • 使用 Casbah/Scala 在 MongoDB 上执行自定义函数

    我使用 MongoDB 的命令行客户端在 MongoDB 中定义了一个函数 function something 我想知道如何使用 Scala 中的 casbah 执行自定义 MongoDB 函数 有什么建议吗 Thanks 有几种方法可以
  • 生成的 JAR 主类抛出 ClassNotFoundException

    我正在使用 IntelliJ IDEA 创建一个 JAR 我为库 JAR 选择了 来自具有依赖项的模块的 JAR 和 提取到目标 JAR 生成的 JAR 看起来很好 myJar jar META INF MANIFEST MF com my