ปัญหาทั่วไปที่นักพัฒนา Java ใหม่พบคือโปรแกรมของพวกเขาล้มเหลวในการทำงานพร้อมกับข้อความแสดงข้อผิดพลาด: Could not find or load main class ...
สิ่งนี้หมายความว่าอะไรเป็นสาเหตุและคุณควรแก้ไขอย่างไร
ปัญหาทั่วไปที่นักพัฒนา Java ใหม่พบคือโปรแกรมของพวกเขาล้มเหลวในการทำงานพร้อมกับข้อความแสดงข้อผิดพลาด: Could not find or load main class ...
สิ่งนี้หมายความว่าอะไรเป็นสาเหตุและคุณควรแก้ไขอย่างไร
คำตอบ:
java <class-name>
ไวยากรณ์คำสั่งก่อนอื่นคุณต้องเข้าใจวิธีที่ถูกต้องในการเปิดโปรแกรมโดยใช้คำสั่งjava
(หรือjavaw
)
ไวยากรณ์ปกติ1คือ:
java [ <options> ] <class-name> [<arg> ...]
โดยที่<option>
เป็นตัวเลือกบรรทัดคำสั่ง (เริ่มต้นด้วยอักขระ "-") <class-name>
เป็นชื่อคลาส Java แบบเต็มและ<arg>
เป็นอาร์กิวเมนต์บรรทัดคำสั่งโดยพลการที่ส่งผ่านไปยังแอปพลิเคชันของคุณ
1 - มีซินแท็กซ์อื่น ๆ ที่อธิบายไว้ใกล้จะจบคำตอบนี้
ชื่อแบบเต็ม (FQN) สำหรับคลาสนั้นถูกเขียนตามอัตภาพตามที่คุณต้องการในซอร์สโค้ด Java เช่น
packagename.packagename2.packagename3.ClassName
อย่างไรก็ตามjava
คำสั่งบางเวอร์ชันอนุญาตให้คุณใช้เครื่องหมายทับแทนระยะเวลา เช่น
packagename/packagename2/packagename3/ClassName
ซึ่ง (สับสน) ดูเหมือนว่าชื่อพา ธ ของไฟล์ แต่ไม่ใช่ชื่อเดียว โปรดทราบว่าชื่อที่ผ่านการรับรองโดยสมบูรณ์เป็นคำศัพท์ Java มาตรฐาน ... ไม่ใช่สิ่งที่ฉันเพิ่งสร้างความสับสนให้คุณ :-)
นี่คือตัวอย่างของสิ่งที่java
คำสั่งควรมีลักษณะ:
java -Xmx100m com.acme.example.ListUsers fred joe bert
ด้านบนจะทำให้java
คำสั่งทำดังต่อไปนี้:
com.acme.example.ListUsers
คลาสที่คอมไพล์แล้วของคลาสmain
วิธีการที่มีลายเซ็น , ประเภทกลับและปรับเปลี่ยนpublic static void main(String[])
ให้โดย (หมายเหตุชื่ออาร์กิวเมนต์ของเมธอดไม่ได้เป็นส่วนหนึ่งของลายเซ็น)String[]
ในฐานะที่เป็นเมื่อคุณได้รับข้อความ "ไม่พบหรือโหลดคลาสหลัก ... " นั่นหมายความว่าขั้นตอนแรกล้มเหลว java
คำสั่งก็ไม่สามารถที่จะหาชั้นเรียน และแน่นอนว่า "... " ในข้อความจะเป็นชื่อคลาสที่มีคุณสมบัติครบถ้วนที่java
ต้องการ
เหตุใดจึงไม่สามารถหาชั้นเรียนได้
สาเหตุแรกคือคุณอาจระบุชื่อคลาสไม่ถูกต้อง (หรือ ... ชื่อคลาสที่ถูกต้อง แต่อยู่ในรูปแบบที่ไม่ถูกต้อง) เมื่อพิจารณาจากตัวอย่างด้านบนนี่คือวิธีที่ผิดหลายวิธีในการระบุชื่อคลาส:
ตัวอย่าง # 1 - ชื่อคลาสแบบง่าย:
java ListUser
เมื่อคลาสถูกประกาศในแพ็กเกจเช่นcom.acme.example
คุณต้องใช้ชื่อคลาสแบบเต็มรวมถึงชื่อแพ็กเกจในjava
คำสั่ง เช่น
java com.acme.example.ListUser
ตัวอย่าง # 2 - ชื่อไฟล์หรือชื่อพา ธ มากกว่าชื่อคลาส:
java ListUser.class
java com/acme/example/ListUser.class
ตัวอย่าง # 3 - ชื่อคลาสที่ปลอกไม่ถูกต้อง:
java com.acme.example.listuser
ตัวอย่าง # 4 - การพิมพ์ผิด
java com.acme.example.mistuser
ตัวอย่าง # 5 - ชื่อไฟล์ต้นฉบับ (ยกเว้น Java 11 หรือใหม่กว่า; ดูด้านล่าง)
java ListUser.java
ตัวอย่าง # 6 - คุณลืมชื่อคลาสทั้งหมด
java lots of arguments
สาเหตุที่เป็นไปได้ที่สองคือชื่อคลาสนั้นถูกต้อง แต่java
คำสั่งไม่สามารถหาคลาสได้ เพื่อให้เข้าใจสิ่งนี้คุณต้องเข้าใจแนวคิดของ "classpath" สิ่งนี้อธิบายได้ดีจากเอกสารของ Oracle:
java
เอกสารคำสั่งดังนั้น ... หากคุณระบุชื่อคลาสอย่างถูกต้องสิ่งต่อไปที่ต้องตรวจสอบคือคุณได้ระบุคลาสพา ธ อย่างถูกต้อง:
java
คำสั่ง ตรวจสอบว่าชื่อไดเร็กทอรีและชื่อไฟล์ JAR ถูกต้องjava
คำสั่ง;
บน Windows และ:
ที่อื่น ๆ หากคุณใช้ตัวคั่นที่ไม่ถูกต้องสำหรับแพลตฟอร์มของคุณคุณจะไม่ได้รับข้อความแสดงข้อผิดพลาดอย่างชัดเจนแทนคุณจะได้รับไฟล์หรือไดเรกทอรีที่ไม่มีอยู่บนเส้นทางที่จะถูกเพิกเฉยอย่างเงียบ ๆ .)เมื่อคุณวางไดเรกทอรีบน classpath นั้นจะสอดคล้องกับรูทของพื้นที่ชื่อที่ผ่านการรับรอง เรียนที่จะมีอยู่ในโครงสร้างไดเรกทอรีรากใต้ว่าด้วยการแมปชื่อที่มีคุณสมบัติครบถ้วนที่จะพา ธ ตัวอย่างเช่นหาก "/ usr / local / acme / classes" อยู่ในคลาสพา ธ ดังนั้นเมื่อ JVM ค้นหาคลาสที่เรียกว่าcom.acme.example.Foon
ไฟล์จะค้นหาไฟล์ ".class" ด้วยชื่อพา ธ นี้:
/usr/local/acme/classes/com/acme/example/Foon.class
หากคุณใส่ "/ usr / local / acme / classes / com / acme / example" บน classpath ดังนั้น JVM จะไม่สามารถหาชั้นเรียนได้
หากคลาส FQN ของคุณเป็นcom.acme.example.Foon
เช่นนั้น JVM จะมองหา "Foon.class" ในไดเรกทอรี "com / acme / example":
หากโครงสร้างไดเรกทอรีของคุณไม่ตรงกับการตั้งชื่อแพ็คเกจตามรูปแบบด้านบน JVM จะไม่พบชั้นเรียนของคุณ
หากคุณพยายามเปลี่ยนชื่อคลาสโดยการย้ายคลาสนั้นจะล้มเหลวเช่นกัน ... แต่สแต็กข้อยกเว้นสแต็กจะแตกต่างกัน มีแนวโน้มที่จะพูดบางสิ่งเช่นนี้:
Caused by: java.lang.NoClassDefFoundError: <path> (wrong name: <name>)
เนื่องจาก FQN ในไฟล์คลาสไม่ตรงกับสิ่งที่ class loader ต้องการที่จะค้นหา
หากต้องการยกตัวอย่างที่เป็นรูปธรรมสมมติว่า:
com.acme.example.Foon
คลาส/usr/local/acme/classes/com/acme/example/Foon.class
,/usr/local/acme/classes/com/acme/example/
,แล้ว:
# wrong, FQN is needed
java Foon
# wrong, there is no `com/acme/example` folder in the current working directory
java com.acme.example.Foon
# wrong, similar to above
java -classpath . com.acme.example.Foon
# fine; relative classpath set
java -classpath ../../.. com.acme.example.Foon
# fine; absolute classpath set
java -classpath /usr/local/acme/classes com.acme.example.Foon
หมายเหตุ:
-classpath
ตัวเลือกที่สามารถลงไป-cp
ในส่วนเผยแพร่ Java ตรวจสอบรายการคู่มือที่เกี่ยวข้องสำหรับjava
, javac
และอื่น ๆคลาสพา ธ ต้องรวมคลาสอื่น ๆ (ที่ไม่ใช่ระบบ) ทั้งหมดที่แอปพลิเคชันของคุณขึ้นอยู่กับ (คลาสของระบบจะอยู่โดยอัตโนมัติและคุณไม่ต้องกังวลกับสิ่งนี้) สำหรับคลาสหลักที่จะโหลดอย่างถูกต้อง JVM ต้องค้นหา:
(หมายเหตุ: ข้อกำหนด JLS และ JVM อนุญาตให้มีขอบเขตสำหรับ JVM ในการโหลดคลาส "lazily" และสิ่งนี้อาจส่งผลต่อเมื่อมีข้อยกเว้นตัวโหลดคลาส)
บางครั้งมันเกิดขึ้นที่มีคนใส่ไฟล์ซอร์สโค้ดลงในโฟลเดอร์ที่ไม่ถูกต้องในทรีซอร์สโค้ดของพวกเขาหรือพวกเขาไม่ออกpackage
ประกาศ หากคุณทำสิ่งนี้ใน IDE คอมไพเลอร์ของ IDE จะบอกคุณเกี่ยวกับสิ่งนี้ทันที ในทำนองเดียวกันถ้าคุณใช้เครื่องมือสร้าง Java ที่เหมาะสมเครื่องมือจะทำงานjavac
ในลักษณะที่จะตรวจพบปัญหา อย่างไรก็ตามหากคุณสร้างโค้ด Java ด้วยตัวเองคุณสามารถทำได้ในลักษณะที่คอมไพเลอร์ไม่สังเกตเห็นปัญหาและไฟล์ ".class" ที่ได้นั้นไม่ได้อยู่ในตำแหน่งที่คุณคาดหวัง
มีหลายสิ่งหลายอย่างให้ตรวจสอบและง่ายต่อการพลาดบางสิ่ง ลองเพิ่ม-Xdiag
ตัวเลือกในjava
บรรทัดคำสั่ง (เป็นสิ่งแรกหลังจากนั้นjava
) มันจะเอาท์พุทสิ่งต่าง ๆ เกี่ยวกับการโหลดคลาสและสิ่งนี้อาจให้เบาะแสว่าปัญหาจริงคืออะไร
และพิจารณาปัญหาที่อาจเกิดขึ้นจากการคัดลอกและวางอักขระที่มองไม่เห็นหรือไม่ใช่ ASCII จากเว็บไซต์เอกสารและอื่น ๆ และพิจารณาว่า "homoglyphs" เป็นตัวอักษรหรือสัญลักษณ์สองตัวที่ดูเหมือนกัน ... แต่ไม่ใช่
สุดท้ายคุณก็สามารถเรียกใช้เห็นได้ชัดว่าเป็นปัญหานี้ถ้าคุณพยายามที่จะเปิดตัวจากไฟล์ JAR (META-INF/*.SF)
ที่มีลายเซ็นไม่ถูกต้องใน
java
java command
มีสามไวยากรณ์ทางเลือกสำหรับการเปิดตัวโปรแกรมจาวาโดยใช้เป็น
1) ไวยากรณ์ที่ใช้สำหรับเรียกใช้งานไฟล์ "executable" JAR มีดังนี้:
java [ <options> ] -jar <jar-file-name> [<arg> ...]
เช่น
java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
ชื่อของคลาส entry-point (เช่นcom.acme.example.ListUser
) และ classpath ถูกระบุใน MANIFEST ของไฟล์ JAR
2) ไวยากรณ์สำหรับเรียกใช้แอปพลิเคชันจากโมดูล (Java 9 และใหม่กว่า) มีดังนี้:
java [ <options> ] --module <module>[/<mainclass>] [<arg> ...]
ชื่อของคลาสจุดเข้าใช้งานที่มีการกำหนดไว้อย่างใดอย่างหนึ่งโดยตัวของมันเองหรือจะได้รับโดยไม่จำเป็น<module>
<mainclass>
3) จาก Java 11 เป็นต้นไปคุณสามารถรวบรวมและเรียกใช้ไฟล์ซอร์สโค้ดเดียวและรันด้วยไวยากรณ์ต่อไปนี้:
java [ <options> ] <sourcefile> [<arg> ...]
โดยที่ (ปกติ) ไฟล์ที่มีคำต่อท้าย ".java"
สำหรับรายละเอียดเพิ่มเติมโปรดดูเอกสารประกอบอย่างเป็นทางการสำหรับjava
คำสั่งสำหรับรุ่น Java ที่คุณใช้
Java IDE ทั่วไปมีการสนับสนุนสำหรับการรันแอปพลิเคชัน Java ใน IDE JVM เองหรือในลูก JVM สิ่งเหล่านี้โดยทั่วไปจะยกเว้นจากข้อยกเว้นนี้เนื่องจาก IDE ใช้กลไกของตนเองเพื่อสร้าง runtime classpath ระบุคลาสหลักและสร้างjava
บรรทัดคำสั่ง
อย่างไรก็ตามยังคงเป็นไปได้ที่ข้อยกเว้นนี้จะเกิดขึ้นหากคุณทำสิ่งต่าง ๆ ที่อยู่ด้านหลังของ IDE ตัวอย่างเช่นหากก่อนหน้านี้คุณตั้งค่าตัวเรียกใช้งานแอปพลิเคชันสำหรับแอป Java ของคุณใน Eclipse และจากนั้นคุณย้ายไฟล์ JAR ที่มีคลาส "หลัก" ไปยังตำแหน่งอื่นในระบบไฟล์โดยไม่บอก Eclipse Eclipse จะเปิด JVM โดยไม่เจตนา ด้วย classpath ที่ไม่ถูกต้อง
ในระยะสั้นหากคุณพบปัญหานี้ใน IDE ให้ตรวจสอบสิ่งต่าง ๆ เช่นสถานะ IDE เก่าการอ้างอิงโครงการที่เสียหายหรือการกำหนดค่าตัวเรียกใช้งานที่เสียหาย
นอกจากนี้ยังเป็นไปได้ที่ IDE จะสับสน IDE เป็นชิ้นส่วนซอฟต์แวร์ที่มีความซับซ้อนอย่างมากซึ่งประกอบไปด้วยส่วนที่มีปฏิสัมพันธ์มากมาย หลายส่วนเหล่านี้นำกลยุทธ์การแคชต่าง ๆ มาใช้เพื่อทำให้ IDE เป็นแบบตอบสนองโดยรวม บางครั้งสิ่งเหล่านี้อาจผิดไปได้และอาการหนึ่งที่เป็นไปได้คือปัญหาเมื่อเปิดแอปพลิเคชัน หากคุณสงสัยว่าอาจเกิดเหตุการณ์เช่นนี้ขึ้นคุณควรลองทำสิ่งอื่นเช่นเริ่มต้น IDE ของคุณสร้างโครงการใหม่และอื่น ๆ
java -cp ../third-party-library.jar com.my.package.MyClass
; มันใช้งานไม่ได้ แต่จำเป็นต้องเพิ่มโฟลเดอร์ในเครื่องไปยังเส้นทางของคลาสด้วย (คั่นด้วย:
ดังนี้: java -cp ../third-party-library.jar:. com.my.package.MyClass
จากนั้นควรทำงาน
java
ว่าไม่ได้บอกว่ามันไม่พบคลาสที่อิมพอร์ต แต่แทนที่จะเป็นคลาสหลักที่คุณพยายามรัน นี่คือการเข้าใจผิดแม้ว่าฉันแน่ใจว่ามีเหตุผลสำหรับสิ่งนั้น ฉันมีกรณีที่java
รู้แน่ชัดว่าชั้นเรียนของฉันอยู่ที่ไหน แต่ไม่พบชั้นเรียนที่นำเข้า แทนที่จะบอกว่ามันบ่นเกี่ยวกับการไม่หาชั้นเรียนหลักของฉัน จริงๆแล้ว annoing
หากชื่อรหัสต้นฉบับของคุณเป็น HelloWorld.java, HelloWorld.class
รหัสเรียบเรียงของคุณจะ
คุณจะได้รับข้อผิดพลาดนั้นหากคุณโทรหาโดยใช้:
java HelloWorld.class
ใช้สิ่งนี้แทน:
java HelloWorld
javac TestCode.java
ตามด้วยjava TestCode
java -classpath . HelloWorld
หากคลาสของคุณอยู่ในแพ็คเกจคุณต้องไปcd
ยังไดเรกทอรีรูทของโครงการของคุณและรันโดยใช้ชื่อที่ผ่านการรับรองโดยสมบูรณ์ของคลาส (packageName.MainClassName)
ตัวอย่าง:
ชั้นเรียนของฉันอยู่ที่นี่:
D:\project\com\cse\
ชื่อเต็มของคลาสหลักของฉันคือ:
com.cse.Main
ดังนั้นฉันcd
กลับไปที่ไดเรกทอรีโครงการราก:
D:\project
จากนั้นออกjava
คำสั่ง:
java com.cse.Main
คำตอบนี้ใช้สำหรับการช่วยเหลือโปรแกรมเมอร์ Java มือใหม่จากความขัดข้องที่เกิดจากข้อผิดพลาดทั่วไปผมแนะนำให้คุณอ่านคำตอบที่ได้รับการยอมรับสำหรับความรู้เชิงลึกเกี่ยวกับ java classpath
หากคุณกำหนดคลาสหลักและเมธอดหลักใน apackage
, คุณควรรันบนไดเรคทอรีลำดับชั้นโดยใช้ชื่อเต็มของคลาส (packageName.MainClassName
)
สมมติว่ามีไฟล์ซอร์สโค้ด (Main.java):
package com.test;
public class Main {
public static void main(String[] args) {
System.out.println("salam 2nya\n");
}
}
สำหรับการเรียกใช้รหัสนี้คุณควรวางในแพคเกจเช่นไดเรกทอรีMain.Class
./com/test/Main.Java
และในการใช้ไดเรกทอรีรูjava com.test.Main
ท
เมื่อรหัสเดียวกันทำงานบนพีซีเครื่องหนึ่ง แต่มันแสดงข้อผิดพลาดในอีกวิธีที่ดีที่สุดที่ฉันเคยพบคือการรวบรวมดังต่อไปนี้:
javac HelloWorld.java
java -cp . HelloWorld
javac -classpath . HelloWorld.java
คงจะทำงานได้ดีอย่างแน่นอน! และนั่นเป็นทางออกที่ดีกว่าในกรณีของคุณ
สิ่งที่ช่วยฉันได้ระบุ classpath ในบรรทัดคำสั่งตัวอย่างเช่น:
สร้างโฟลเดอร์ใหม่ C:\temp
สร้างไฟล์ Temp.java C:\temp
ด้วยคลาสต่อไปนี้:
public class Temp {
public static void main(String args[]) {
System.out.println(args[0]);
}
}
เปิดบรรทัดคำสั่งในโฟลเดอร์C:\temp
และเขียนคำสั่งต่อไปนี้เพื่อคอมไพล์คลาส Temp:
javac Temp.java
รันคลาส Java ที่คอมไพล์แล้วเพิ่ม-classpath
ตัวเลือกเพื่อให้ JRE ทราบตำแหน่งที่จะหาคลาส:
java -classpath C:\temp Temp Hello!
java
ไม่ได้ดู $ CLASSPATH (เพราะคุณใช้ -classpath หรือ -jar) หรือ 2) การตั้งค่า classpath ไม่ได้ตั้งค่าในสภาพแวดล้อมที่ไม่ได้มีผลบังคับใช้ในบริบทที่java
เป็น วิ่ง; เช่นเนื่องจากคุณไม่ได้ "ซอร์ส" ไฟล์ที่เพิ่มคำสั่ง setenv ในเชลล์ด้านขวา
ตามข้อความแสดงข้อผิดพลาด ("ไม่พบหรือโหลดคลาสหลัก") มีปัญหาสองประเภท:
ไม่พบคลาสหลักเมื่อมีการพิมพ์ผิดหรือไวยากรณ์ผิดในชื่อคลาสที่ผ่านการรับรองโดยสมบูรณ์หรือไม่มีอยู่ใน classpath ที่ระบุ
ไม่สามารถโหลดคลาสหลักได้เมื่อไม่สามารถเริ่มคลาสได้โดยทั่วไปคลาสหลักจะขยายคลาสอื่นและคลาสนั้นไม่มีอยู่ใน classpath ที่ระบุ
ตัวอย่างเช่น:
public class YourMain extends org.apache.camel.spring.Main
หากไม่มีอูฐสปริงข้อผิดพลาดนี้จะถูกรายงาน
extends
) ฉันเพิ่งเรียนรู้วิธีที่ยากที่เมื่อคลาสหลักล้มเหลวในการโหลดเพราะมันขยายออกไปอีกอันที่ไม่สามารถพบได้จาวาไม่ได้รายงานว่าไม่พบคลาสจริง (ไม่เหมือนNoClassDefFoundError
) ใช่มันเกิดขึ้นและมันเป็นสถานการณ์ที่ดึงผมเมื่อคุณไม่รู้เรื่องนี้
ฉันมีข้อผิดพลาดดังกล่าวในกรณีนี้:
java -cp lib.jar com.mypackage.Main
ใช้งานได้กับ;
Windows และ:
Unix:
java -cp lib.jar; com.mypackage.Main
Main
ไม่ได้อยู่ในไฟล์ JAR -cp lib.jar;
หมายถึงสิ่งเดียวกัน-cp lib.jar;.
เช่นไดเรกทอรีปัจจุบันรวมอยู่ใน classpath
ลอง-Xdiag
คำตอบของ Steve Cครอบคลุมกรณีที่เป็นไปได้อย่างดี แต่บางครั้งเพื่อตรวจสอบว่าไม่พบคลาสหรือโหลดอาจไม่ง่ายขนาดนั้น ใช้java -Xdiag
(ตั้งแต่ JDK 7) วิธีนี้จะพิมพ์ stacktrace ที่สวยงามซึ่งให้คำแนะนำเกี่ยวกับความCould not find or load main class
หมายของข้อความ
ตัวอย่างเช่นมันสามารถชี้ให้คุณไปที่คลาสอื่น ๆ ที่ใช้โดยคลาสหลักที่ไม่พบและป้องกันไม่ให้โหลดคลาสหลัก
ใช้คำสั่งนี้:
java -cp . [PACKAGE.]CLASSNAME
ตัวอย่าง: หากชื่อคลาสของคุณคือ Hello.class สร้างขึ้นจาก Hello.java ให้ใช้คำสั่งด้านล่าง:
java -cp . Hello
หากไฟล์ Hello.java ของคุณอยู่ใน package com.demo ให้ใช้คำสั่งด้านล่าง
java -cp . com.demo.Hello
ด้วย JDK 8 หลายครั้งมันเกิดขึ้นว่าไฟล์คลาสมีอยู่ในโฟลเดอร์เดียวกัน แต่java
คำสั่งคาดว่า classpath และด้วยเหตุนี้เราเพิ่ม-cp .
เพื่อใช้โฟลเดอร์ปัจจุบันเป็นการอ้างอิงสำหรับ classpath
-cp .
ไม่จำเป็นเพราะถ้า$CLASSPATH
ไม่มีการตั้ง.
ค่า classpath นั้นจะเป็นค่าเริ่มต้น
echo %CLASSPATH%
ผลลัพธ์คืออะไร) และไม่ฉันไม่สามารถตรวจสอบได้เพราะฉันไม่มีพีซี Windows
บางครั้งสิ่งที่อาจทำให้เกิดปัญหาไม่มีอะไรเกี่ยวข้องกับชั้นเรียนหลักและฉันต้องค้นหาวิธีที่ยาก มันเป็นห้องสมุดอ้างอิงที่ฉันย้ายและมันทำให้ฉัน:
ไม่สามารถค้นหาหรือโหลดคลาสหลัก xxx Linux
ฉันเพิ่งลบการอ้างอิงนั้นเพิ่มอีกครั้งและมันก็ใช้ได้ดีอีกครั้ง
ในตัวอย่างนี้คุณมี:
ไม่พบหรือโหลดระดับหลัก? classpath
เป็นเพราะคุณกำลังใช้ "-classpath" แต่เส้นประไม่ใช่เส้นประเดียวกับที่ใช้java
บนพรอมต์คำสั่ง ฉันมีปัญหาในการคัดลอกและวางจากNotepadเป็น cmd
ฉันมีปัญหาเดียวกันและในที่สุดก็พบข้อผิดพลาดของฉัน :) ฉันใช้คำสั่งนี้เพื่อรวบรวมและทำงานได้อย่างถูกต้อง:
javac -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode.java
แต่คำสั่งนี้ใช้ไม่ได้สำหรับฉัน (ฉันหาหรือโหลดคลาสหลักไม่ได้qrcode
):
java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode
ในที่สุดฉันเพิ่งเพิ่มอักขระ ':' ที่ส่วนท้ายของ classpath และปัญหาได้รับการแก้ไขแล้ว:
java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar:" qrcode
ในกรณีของฉันเกิดข้อผิดพลาดเนื่องจากฉันได้ระบุชื่อไฟล์ต้นฉบับแทนชื่อคลาส
เราจำเป็นต้องระบุชื่อคลาสที่มีวิธีการหลักให้กับล่าม
สิ่งนี้อาจช่วยคุณได้หากกรณีของคุณเป็นของฉันโดยเฉพาะ: ในฐานะผู้เริ่มต้นฉันพบปัญหานี้เมื่อฉันพยายามเรียกใช้โปรแกรม Java
ฉันรวบรวมมันเช่นนี้:
javac HelloWorld.java
และฉันพยายามเรียกใช้ด้วยนามสกุลเดียวกัน:
java Helloworld.java
เมื่อฉันลบ.java
และเขียนคำสั่งเช่นjava HelloWorld
นั้นโปรแกรมทำงานได้อย่างสมบูรณ์แบบ :)
คำตอบทั้งหมดที่นี่นำไปสู่ผู้ใช้ Windows ที่ดูเหมือน สำหรับ Mac คั่น classpath คือไม่:
;
ในฐานะที่เป็นข้อผิดพลาดการตั้งค่า classpath ที่ใช้;
ไม่ได้ถูกส่งออกไปแล้วนี่อาจเป็นเรื่องยากที่จะค้นพบว่ามาจาก Windows กับ Mac
นี่คือคำสั่ง Mac ที่สอดคล้องกัน:
java -classpath ".:./lib/*" com.test.MyClass
ในตัวอย่างนี้แพคเกจคือcom.test
และlib
โฟลเดอร์จะรวมอยู่ใน classpath
/*
จำเป็น?
ตำแหน่งไฟล์คลาส: C: \ test \ com \ company
ชื่อไฟล์: Main.class
ชื่อคลาสที่ผ่านการรับรองโดยสมบูรณ์: com.company.Main
คำสั่งบรรทัดคำสั่ง:
java -classpath "C:\test" com.company.Main
โปรดทราบที่นี่ว่าคลาสพา ธ ไม่รวม \ com \ company
ฉันใช้เวลาพอสมควรในการพยายามแก้ไขปัญหานี้ ฉันคิดว่าฉันตั้ง classpath ไม่ถูกต้อง แต่ปัญหาคือฉันพิมพ์:
java -cp C:/java/MyClasses C:/java/MyClasses/utilities/myapp/Cool
แทน:
java -cp C:/java/MyClasses utilities/myapp/Cool
ฉันคิดว่าความหมายของการรับรองแบบเต็มหมายถึงการรวมชื่อพา ธ เต็มแทนชื่อแพคเกจแบบเต็ม
utilities.myapp.Cool
หรืออะไรก็ตามชื่อแพคเกจของมันคือถ้ามี
ก่อนอื่นกำหนดเส้นทางโดยใช้คำสั่งนี้;
set path="paste the set path address"
จากนั้นคุณต้องโหลดโปรแกรม พิมพ์ "cd (ชื่อโฟลเดอร์)" ในไดรฟ์ที่จัดเก็บและรวบรวม ตัวอย่างเช่นหากโปรแกรมของฉันเก็บไว้ในไดรฟ์ D ให้พิมพ์ "D:" กด Enter และพิมพ์ "cd (ชื่อโฟลเดอร์)"
if "cd" helps then it by luck rather than by judgement
. นี่เป็นสิ่งที่ผิด (ฉันเชื่อ) เนื่องจาก java ใช้ไดเรกทอรีปัจจุบัน.
เป็นส่วนหนึ่งของ classpath โดยค่าเริ่มต้น
สิ่งที่แก้ไขปัญหาในกรณีของฉันคือ:
คลิกขวาที่โครงการ / ระดับคุณต้องการเรียกใช้แล้ว->Run As
Run Configurations
จากนั้นคุณควรแก้ไขการกำหนดค่าที่มีอยู่หรือเพิ่มใหม่ด้วยวิธีต่อไปนี้:
เปิดClasspath
แท็บคลิกที่Advanced...
ปุ่มแล้วเพิ่มbin
โฟลเดอร์ของโครงการของคุณ
หากคุณใช้Mavenเพื่อสร้างไฟล์ JAR โปรดตรวจสอบให้แน่ใจว่าระบุคลาสหลักในไฟล์ pom.xml:
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>class name us.com.test.abc.MyMainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
นี่เป็นกรณีเฉพาะ แต่เมื่อฉันมาที่หน้านี้เพื่อค้นหาวิธีแก้ปัญหาและไม่พบมันฉันจะเพิ่มที่นี่
Windows (ทดสอบกับ 7) ไม่ยอมรับอักขระพิเศษ (เช่นá
) ในชื่อคลาสและแพ็คเกจ แม้ว่า Linux จะทำเช่นนั้น
ฉันพบสิ่งนี้เมื่อฉันสร้าง.jar
ใน NetBeans และพยายามเรียกใช้ในบรรทัดคำสั่ง มันทำงานใน NetBeans แต่ไม่ใช่ในบรรทัดคำสั่ง
บน Windows ให้ใส่.;
ค่า CLASSPATH ในตอนต้น
ส่วน (จุด) หมายถึง "ดูในไดเรกทอรีปัจจุบัน" นี่คือทางออกที่ถาวร
นอกจากนี้คุณสามารถตั้งค่า "ครั้งเดียว" CLASSPATH=%CLASSPATH%;.
กับชุด สิ่งนี้จะคงอยู่ตราบเท่าที่หน้าต่างคำสั่งของคุณเปิดอยู่
คุณต้องทำสิ่งนี้จากsrc
โฟลเดอร์ ที่นั่นคุณพิมพ์บรรทัดคำสั่งต่อไปนี้:
[name of the package].[Class Name] [arguments]
สมมติว่าคลาสของคุณถูกเรียกใช้CommandLine.class
และโค้ดมีลักษณะดังนี้:
package com.tutorialspoint.java;
/**
* Created by mda21185 on 15-6-2016.
*/
public class CommandLine {
public static void main(String args[]){
for(int i=0; i<args.length; i++){
System.out.println("args[" + i + "]: " + args[i]);
}
}
}
จากนั้นคุณควรcd
ไปที่โฟลเดอร์ src และคำสั่งที่คุณต้องการเรียกใช้จะมีลักษณะดังนี้:
java com.tutorialspoint.java.CommandLine this is a command line 200 -100
และผลลัพธ์บนบรรทัดคำสั่งจะเป็น:
args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100
cd
เข้าไปsrc
แล้วรันคำสั่งjava ../bin com.blah.blah.MyClass
ที่ใช้งานได้สำหรับฉัน ขอบคุณมากสำหรับเคล็ดลับ!
ใน Java บางครั้งเมื่อคุณเรียกใช้ JVM จากบรรทัดคำสั่งโดยใช้โปรแกรมจาวาและพยายามเริ่มโปรแกรมจากไฟล์คลาสที่มี public void main (PSVM) คุณอาจพบข้อผิดพลาดด้านล่างแม้ว่าพารามิเตอร์ classpath JVM นั้นถูกต้องและมีไฟล์คลาสอยู่บน classpath:
Error: main class not found or loaded
สิ่งนี้จะเกิดขึ้นหากไฟล์คลาสที่มี PSVM ไม่สามารถโหลดได้ เหตุผลหนึ่งที่เป็นไปได้คือคลาสอาจใช้อินเตอร์เฟสหรือขยายคลาสอื่นที่ไม่ได้อยู่ใน classpath โดยปกติถ้าคลาสไม่ได้อยู่ใน classpath ข้อผิดพลาดที่ส่งออกจะระบุว่าเป็นเช่นนั้น แต่ถ้าคลาสที่ใช้นั้นถูกขยายหรือนำไปใช้จาวาจะไม่สามารถโหลดคลาสเองได้
การอ้างอิง: https://www.computingnotes.net/java/error-main-class-not-found-or-loaded/
เมื่อเรียกใช้java
กับ-cp
ตัวเลือกตามที่โฆษณาใน Windows PowerShell คุณอาจได้รับข้อผิดพลาดที่มีลักษณะบางอย่างเช่น:
The term `ClassName` is not recognized as the name of a cmdlet, function, script ...
เพื่อให้ PowerShell ยอมรับคำสั่งอาร์กิวเมนต์ของ-cp
ตัวเลือกจะต้องมีอยู่ในเครื่องหมายคำพูดเช่นเดียวกับใน:
java -cp 'someDependency.jar;.' ClassName
การขึ้นรูปคำสั่งด้วยวิธีนี้จะช่วยให้กระบวนการ Java อาร์กิวเมนต์ classpath ได้อย่างถูกต้อง
ฉันยังประสบข้อผิดพลาดที่คล้ายกันขณะทดสอบการเชื่อมต่อ Java MongoDB JDBC ฉันคิดว่ามันเป็นการดีที่จะสรุปวิธีแก้ปัญหาสุดท้ายของฉันในระยะสั้นเพื่อให้ในอนาคตใครก็ตามสามารถดูคำสั่งสองคำสั่งได้โดยตรงและเป็นการดีที่จะดำเนินการต่อไป
สมมติว่าคุณอยู่ในไดเรกทอรีที่มีไฟล์ Java และการอ้างอิงภายนอก (ไฟล์ JAR) ของคุณ
รวบรวม:
javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
วิ่ง:
java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
JavaMongoDBConnection
ไม่มีแพ็คเกจและ 2) คุณไม่เปลี่ยนไดเรกทอรี มันคือการพูดน้อยเปราะบาง และโดยไม่ได้อธิบายปัญหาก็จะนำไปสู่มือใหม่ลองใช้วิธีนี้ในสถานการณ์ที่มันจะไม่ทำงาน ในระยะสั้นมันกระตุ้นให้ "เทคนิคการเขียนโปรแกรมวูดู": en.wikipedia.org/wiki/Voodoo_programming
เอาล่ะมีคำตอบมากมายอยู่แล้ว แต่ก็ไม่มีใครพูดถึงกรณีที่การอนุญาตของไฟล์เป็นตัวการ
เมื่อรันผู้ใช้อาจไม่สามารถเข้าถึงไฟล์ JAR หรือหนึ่งในไดเรกทอรีของพา ธ ตัวอย่างเช่นพิจารณา:
ไฟล์ Jar ใน /dir1/dir2/dir3/myjar.jar
ผู้ใช้ 1 ที่เป็นเจ้าของไฟล์ JAR สามารถทำได้:
# Running as User1
cd /dir1/dir2/dir3/
chmod +r myjar.jar
แต่มันก็ยังไม่ทำงาน:
# Running as User2
java -cp "/dir1/dir2/dir3:/dir1/dir2/javalibs" MyProgram
Error: Could not find or load main class MyProgram
นี่เป็นเพราะผู้ใช้ที่กำลังทำงาน (User2) ไม่มีสิทธิ์เข้าถึง dir1, dir2 หรือ javalibs หรือ dir3 มันอาจทำให้บางคนถั่วเมื่อ User1 สามารถดูไฟล์และสามารถเข้าถึงพวกเขา แต่ข้อผิดพลาดยังคงเกิดขึ้นสำหรับ User2
ฉันได้รับข้อผิดพลาดนี้หลังจากทำmvn eclipse:eclipse
สิ่งนี้ทำให้.classpath
ไฟล์ของฉันยุ่งเล็กน้อย
ต้องเปลี่ยนสาย.classpath
จาก
<classpathentry kind="src" path="src/main/java" including="**/*.java"/>
<classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
ถึง
<classpathentry kind="src" path="src/main/java" output="target/classes" />
<classpathentry kind="src" path="src/main/resources" excluding="**" output="target/classes" />
ฉันไม่สามารถแก้ไขปัญหานี้ได้ด้วยวิธีแก้ไขปัญหาที่ระบุไว้ที่นี่ (แม้ว่าคำตอบที่ระบุไว้มีไม่ต้องสงสัยเลย ฉันประสบปัญหานี้สองครั้งและทุกครั้งที่ฉันลองใช้วิธีแก้ไขปัญหาที่แตกต่างกัน (ใน Eclipse IDE)
main
วิธีการหลายวิธีในชั้นเรียนที่แตกต่างกันของโครงการของฉัน ดังนั้นฉันจึงลบmain
เมธอดออกจากคลาสที่ตามมาmain
วิธีการลบจะไม่สามารถแก้ไขปัญหาได้ ไม่มีอะไรผิดปกติทางเทคนิคกับแอปพลิเคชันที่มีจุดเข้าใช้หลายจุด