【问题标题】:.jar runs with -jar flag.jar 使用 -jar 标志运行
【发布时间】:2012-10-14 19:47:07
【问题描述】:

我已经成功创建了一个在我的开发计算机上运行良好的 Java 程序,包括 Netbeans 和 .jar 文件(双击)。问题是它不会在没有 JDK 或没有通过命令行使用 java -jar jarfile.jar 启动的计算机上启动(请注意,它不会在没有 -jar 标志的情况下启动)。

在开发计算机上,jar 文件都不会在命令行上没有-jar 标志的情况下运行。

在程序无法启动的所有情况下,我遇到的错误如下。

S:\Folder>Program.jar
Exception in thread "main" java.lang.NoClassDefFoundError: S:\Folder\Program/jar
Caused by: java.lang.ClassNotFoundException: S:\Folder\Program.jar
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: S:\Folder\Program.jar. Program will exit.

Program.jar 的文件结构如下:

Program.jar
    binlib
        build.xml
        manifest.mf
        onejar.mf
        one-jar-ant-task.xml
    com
        simontuffs
            onejar
                a lot of classes related to OneJar
    doc
        one-jar-license.txt
    lib
        itextpdf-5.3.3.jar
    main
        main.jar
            my
                package
                    all the classes related to my program
            META-INF
                manifest.mf
            Resources
                all my programs resources
            txt
                more resources
    META-INF
        MANIFEST.MF
    .version
    OneJar.class

该项目使用Netbeans and OneJar 编译,以在同一个jar 文件中获取所有必需的库(在本例中为iText)以帮助用户 - 一个文件比两个文件更容易。

jar 文件根目录下META-INF 文件夹中的MANIFEST.MF 文件包含以下内容:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: One-Jar 0.97 Ant taskdef
Main-Class: com.simontuffs.onejar.Boot
One-Jar-Main-Class: my.package.MainClass
Class-Path: lib/itextpdf-5.3.3.jar

请注意,这是由 OneJar 自动生成的,所以我认为这是正确的,尽管主类的真实路径也包含 /main/main.jar/,如果路径与根目录相关。

内部 jar 文件(实际程序)中的MANIFEST.MF 为空。 binlib 文件夹中的一个包含以下内容:

Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build
Main-Class: my.package.MainClass

如何让 jar 运行?

【问题讨论】:

    标签: java jar noclassdeffounderror


    【解决方案1】:

    如果没有 JDK,jar 文件将无法运行,因为 Windows 无法正确调用 java.exe(或 javaw.exe)。当用户选择默认程序打开jar文件时,Windows会在注册表中添加如下内容:

    "Path\To\JRE\Bin\java(w).exe" "%1"
    

    正如您在引用中看到的那样,缺少 -jar 标志。安装 JDK 时,它会自动更正这些值。

    要解决此问题,您需要一个批处理脚本来替换错误的值。需要修复的注册表项有jarfilejava.exejavaw.exe

    我所做的是部署带有程序的jarfix.bat,其中包含如何正确“安装”程序的说明。

    reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment" /v "CurrentVersion" 1>nul
    if errorlevel 1 goto :error
    
    @FOR /F "tokens=2* " %%A IN ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment" /v "CurrentVersion"') DO @SET JAVAVERSION=%%B
    
    reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\%JAVAVERSION%" /v "JavaHome" 1>nul
    reg query "HKEY_CURRENT_USER\SOFTWARE\Classes\Applications\java.exe" 1>nul
    reg query "HKEY_CURRENT_USER\SOFTWARE\Classes\Applications\javaw.exe" 1>nul
    if errorlevel 1 goto :error
    
    @FOR /F "tokens=2* " %%A IN ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\%JAVAVERSION%" /v "JavaHome"') DO @SET JAVAHOME=%%B
    @FOR /F "tokens=2* " %%A IN ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Classes\jarfile\shell\open\command" /v ""') DO @SET JAVACOMMAND=%%B
    @FOR /F "tokens=2* " %%A IN ('reg query "HKEY_CURRENT_USER\Software\Classes\Applications\java.exe\shell\open\command" /v ""') DO @SET JAVACOMMAND2=%%B
    
    reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Classes\jarfile\shell\open\command" /f /v "" /t REG_SZ /d "\"%JAVAHOME%\bin\javaw.exe\" -jar \"%%1\" %%*"
    reg add "HKEY_CURRENT_USER\Software\Classes\Applications\java.exe\shell\open\command" /f /v "" /t REG_SZ /d "\"%JAVAHOME%\bin\java.exe\" -jar \"%%1\" %%*"
    reg add "HKEY_CURRENT_USER\Software\Classes\Applications\javaw.exe\shell\open\command" /f /v "" /t REG_SZ /d "\"%JAVAHOME%\bin\javaw.exe\" -jar \"%%1\" %%*"
    

    该程序将编辑注册表,因此该程序需要管理员权限。为了在程序启动时检查它们,我做了以下操作

    NET SESSION >nul 2>&1
    if %errorlevel% == 0 (
        echo  User successfully detected as an administrator!
    ) else (
        echo User doesn't have administrator privileges!
        exit /b 1
    )
    

    【讨论】:

      【解决方案2】:

      Java JAR 文件只是一个包含许多二进制类的 ZIP,您的 CPU 或操作系统无法理解。为了运行 JAR,你需要能够真正理解和执行JAR文件、主类等内容的Java(JRE就够了,JDK是给开发者的)。当然这是因为Java字节码不是您的 CPU 可以理解的程序集 - 这些是 Java VM 可以理解并转换为 CPU 语言的指令。

      您可以考虑将您的 JAR 文件转换为 Windows 可执行文件,请查看:How can I convert my Java program to an .exe file?

      【讨论】:

      • 问题不在于我没有安装JRE。
      【解决方案3】:

      Jar 文件只是压缩数据,它不是可执行文件。您必须使用可执行文件 java 命令运行它。该命令具有打开 jar 文件、读取类文件和解释字节码、初始化 JVM 和运行字节码的智能。所以如果没有字节码解释器命令 (java) ,一个 jar 文件就没用了。因此,您可以通过两种方式运行 jar 中的类文件。

      1) java -classpath jarfile MainClass

      2) java -jar jarfile(如果 jar 文件的 MANIFEST 文件中提到了它的主类)

      【讨论】:

      • 我知道 Java 需要 JRE 才能运行。但是为什么它没有找到主类?我不能要求用户从命令行运行程序。
      猜你喜欢
      • 1970-01-01
      • 2020-11-26
      • 1970-01-01
      • 2014-07-12
      • 1970-01-01
      • 2015-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多