[英]Cannot run JAR file due to cannot load main class error
我構建了我的項目並使用 Gradle 構建框架生成了一個 JAR 文件。 但是,在這種情況下,輸出 jar 文件無法從主類 ( miner.Tracker ) 加載主要方法。
正如我所提到的,使用-jar
選項運行失敗。
$ java -jar Backtracker.jar
Error: Could not find or load main class miner.Tracker
我還嘗試使用-cp
選項直接運行該類,但失敗了。
$ java -cp Backtracker.jar miner.Tracker
Error: Could not find or load main class miner.Tracker
最后,我解壓縮了 jar 文件並從內部調用該類。 這一次,它已經成功地找到並運行了帶有 main 方法的類。
$ mkdir classes
$ cd classes
$ classes $ tar xvf ../Backtracker.jar
x META-INF/
x META-INF/MANIFEST.MF
x CHANGELOG.md
x com/
1. ...
classes $ java miner.Tracker
2021-04-12 22:47:48.008 | Logging started
...
這是META-INF/MANIFEST.MF
文件的內容。
Manifest-Version: 1.0
Implementation-Title: BackTracker
Implementation-Version: 1.9.xx
Specification-Title: release
Specification-Version: 1.9.xx
Main-Class: miner.Tracker
我從 Oracle Java 1.8 運行它。
$ java -version
java version "1.8.0_271"
Java(TM) SE Runtime Environment (build 1.8.0_271-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.271-b09, mixed mode)
謝謝你的幫助。
更新:
$ tar tvf Backtracker.jar |grep miner\/Tracker
-rw-r--r-- 0 0 0 2175 Apr 14 20:38 miner/TrackerUtil.class
-rw-r--r-- 0 0 0 40963 Apr 14 20:38 miner/Tracker.class
經過一些實驗,我同意用戶第 11維的觀點,即您的清單文件可能有問題。 不過,我認為這與非數字版本無關。 我試過了,有效。
我注意到的是,如果您添加的行包含的空間超過正常空間(字符 32 dec, 20 hex),您將看到您描述的錯誤,因為清單無法解析。 顯然,清單解析器在每個非空行上都需要類似MyKey: MyValue
東西。 即使在末尾以外的任何地方的空行也可能導致相同的問題,如果它們位於所謂的部分的中間。 因此,如果您有類似以下之一的清單,無論您使用-cp
還是-jar
,您都會看到ClassNotFoundException
:
Manifest-Version: 1.0
Main-Class: miner.Tracker
x
Manifest-Version: 1.0
Main-Class: miner.Tracker
即使在最后一行之后你有一行只包含這樣的制表符,也會發生錯誤:
Manifest-Version: 1.0
Main-Class: miner.Tracker
如果您有使用其他不可見字符(例如非標准Unicode 空格)的行,情況也是如此。
就像我在之前的評論中所說的那樣:檢查清單中任何位置的此類字符。 如果這沒有產生任何結果,還請檢查您的 Java 源代碼文件,尤其是包和類名稱。
更新:這是一個小 Java 示例,展示了我之前解釋過的內容:
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.jar.Manifest;
public class ManifestValidator {
public static void main(String[] args) {
// Valid: nothing unusual
parseManifest("Manifest-Version: 1.0\nMain-Class: miner.Tracker\n");
// Valid: trailing empty line
parseManifest("Manifest-Version: 1.0\nMain-Class: miner.Tracker\n\n");
// Valid: line continuation by leading space
parseManifest("Manifest-Version: 1.0\nMain-Class: miner.Track\n er\n");
// Valid: last line is ignored if it does not end with a line feed
parseManifest("Manifest-Version: 1.0\nMain-Class: miner.Tracker\nSome garbage");
// Invalid: line beginning with tab
parseManifest("Manifest-Version: 1.0\nMain-Class: miner.Tracker\n\t\n");
// Invalid: not a key-value pair "key: value"
parseManifest("Manifest-Version: 1.0\nMain-Class: miner.Tracker\nFoo=bar\n");
// Invalid: empty line in section
parseManifest("Manifest-Version: 1.0\n\nMain-Class: miner.Tracker\n");
// Invalid: non-default unicode space instead of normal one
parseManifest("Manifest-Version: 1.0\nMain-Class:\u00A0miner.Tracker\n");
}
public static void parseManifest(String content) {
try {
Manifest manifest = new Manifest(new ByteArrayInputStream(content.getBytes()));
System.out.println(manifest.getMainAttributes().entrySet());
}
catch (IOException e) {
System.out.println(e);
}
}
}
[Manifest-Version=1.0, Main-Class=miner.Tracker]
[Manifest-Version=1.0, Main-Class=miner.Tracker]
[Manifest-Version=1.0, Main-Class=miner.Tracker]
[Manifest-Version=1.0, Main-Class=miner.Tracker]
java.io.IOException: invalid header field
java.io.IOException: invalid header field
java.io.IOException: invalid manifest format
java.io.IOException: invalid header field
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.