Cách Fix Lỗi “could not find or load main class” thành công 100%

5/5 - (1 bình chọn)

Vì sao lỗi “Error: Could not find or load main class” xuất hiện?

Những lý do chính gây ra lỗi “Error: Could not find or load main class

3 lý do chính khiến chương trình Java của bạn khi chạy và gặp phải lỗi “Error: Could not find or load main class” bao gồm:

sua-loi-error-could-not-find-or-load-main-class

Ví dụ bằng chương trình cơ bản

Phần lớn những bạn tìm đến bài viết này đều chủ yếu là người mới học Java, vì thế, TinoHost sẽ giải thích thật kỹ giúp bạn và đưa ra ví dụ HelloWorld “thần thánh” dễ hiểu như sau:

public class HelloWorld {

 public static void main(String[] args) {

 System.out.println("Hello world!");

 }

}

Sau khi biên dịch, chúng ta sẽ được kết quả như sau:

$ javac HelloWorld.java. 

Đồng nghĩa với việc chúng ta đã có được một tệp thực thi .class được sinh ra có cùng tên với tên class trong chương trình Java phía trên (public class HelloWorld).

Thay vì làm 2 phần tách biệt bao gồm lỗi và cách sửa lỗi, TinoHost sẽ gom lại thành 1 phần duy nhất: lỗi và cách sửa lỗi ngay trong cùng 1 mục để bạn dễ theo dõi hơn nhé!

Một số từ khóa TinoHost sẽ giữ nguyên trong bài viết:

Cách sửa lỗi “Error: Could not find or load main class

Lỗi “Error: Could not find or load main class” do đặt tên sai và gọi sai tên

Ví dụ về lỗi đặt sai tên và gọi sai tên

Đây là một lỗi phổ biến rất nhiều người gặp phải vì ngôn ngữ Java phân biệt chữ in hoa và chữ in thường. Ví dụ như sau:

Sau khi bạn đã có được file .class, chúng ta sẽ chạy chương trình bằng lệnh sau:

java <.class tên file>

Áp dụng vào chương trình mẫu ở trên chúng ta sẽ có như sau:

$ java helloworld

Error: Could not find or load main class helloworld

Như bạn thấy, dòng lỗi“Error: Could not find or load main class helloworld” hiện lên vì lý do:

Tệp .class có tên làHelloWorldchứ không phảihelloworld.Đồng nghĩa với việc bạn sẽ phải gõ chính xác “HelloWorld” chương trình của bạn mới có thể chạy được.

Tương tự, thay vì gọi HelloWorld và bạn gọiHeloWorld(thiếu l) hayHelloWord(thiếu l) chương trình cũng sẽ bị lỗi.

Đôi khi bạn sẽ dùng lệnh như sau để chạy:

$ java HelloWorld.class

Error: Could not find or load main class HelloWorld.class

Đồng nghĩa với việc bạn gọi luôn cả phần mở rộng .class của HelloWorld. Tuy nhiên, điều này hoàn toàn không cần thiết và gây ra lỗi “Error: Could not find or load main class.”

Sửa lỗi “Error: Could not find or load main class” do đặt sai tên và gọi sai tên

Suy ra, cách để sửa lỗi này rất đơn giản. Bạn chỉ cầnkiểm tra chính xác tên gọicủa .class bạn đã tạo ở trên. Và trình biên dịch cũng tự động tạo .class có cùng tên với tên class bạn đặt trong chương trình.

Bạn thử lại với đúng cách viết hoa, đúng chính tả và không thêm phần đuôi mở rộng. Chương trình của bạn sẽ không báo lỗi nữa:

$ java HelloWorld

Hello world!

Lỗi “Error: Could not find or load main class” do Package bị sai

Ví dụ về lỗi Package bị sai

Khi sử dụng Java, bạn có thể tạo ra các class tương tự nhau và gói gọn lại trong một package. Và chúng ta sẽ chuyển class HelloWorld vào bên trong gói com.tino như sau:

package com.tino:

public class HelloWorld {

 public static void main(String[] args) {

 System.out.println("Hello world!");

 }

}

Bây giờ bạn chỉ cần biên dịch sau đó chạy chương trình HelloWorld và chúng ta sẽ được kết quả như sau:

$ java HelloWorld
Error: Could not find or load main class HelloWorld

Sửa lỗi “Error: Could not find or load main class” do Package bị sai

Quá trình nhập của bạn không sai, viết đúng chính tả in hoa nhưng lại không thể chạy được là vì sao?

Lý do:Khi bạn đưa class vào trong package, bạn sẽ cần phải gọi đầy đủ tên của chúng.Vì vậy, trong trường hợp này, bạn sẽ cần gọi đầy đủ package này là:com.tino.HelloWorld.

Với cách tạo này, bạn sẽ tạo ra một thư mục cây như sau: com/tino/HelloWorld.java

Bạn chỉ cần đảm bảo các tệp trong thư mục cây này tồn tại bạn sẽ có thể chạy được chương trình.

$ java com.tino.HelloWorld
Hello world!

Classpath không chính xác/ đường dẫn không chính xác

Classpath là gì?

Classpath là một tham số trong JVM – java Virtual Machine (tạm dịch Máy ảo Java) hoặc trình biên dịch Java nhằm để chỉ vị trí của các class và các package do người dùng thực hiện.

Giải thích đơn giản hơn, bạn có thể sử dụng Classpath để “nói” và hướng dẫn cho JVM, trình biên dịch Java biết tệp .class đang ở đâu trong máy tính của bạn.

Bạn có thể sử dụng lệnh sau:

java -classpath /myprograms/compiled HelloWorld

Và Java sẽ tự động chạy đi tìm theo đường dẫn để đến classHelloWorld.

Sửa lỗi “Error: Could not find or load main class” do Classpath không chính xác

Cách sửa lỗi cũng khá đơn giản như ở phần “Sửa lỗi Error: Could not find or load main class do đặt sai tên và gọi sai tên”. Bạn chỉ cần kiểm tra lại chính xác tên của từng thư mục và tệp trong đường dẫn và tệp class của bạn có tồn tại trong đường dẫn đó hay không.

Giả sử, bạn muốn chạy com.tino.HelloWorld ở một thư mục khác, một tệp khác. Bạn sẽ phải làm như thế nào?

Rất may, nhà phát triển ngôn ngữ Java cũng là lập trình viên và tạo điều kiện thuận lợi hơn trong việc lập trình của các bạn bằng cách: sử dụngdấu chấm ‘.’thay cho tên thư mục là được.

Thay vì sử dụng:java -classpath <tệp mẹ>/<tệp con>/ com.tino.HelloWorld

Bạn chỉ cần thay vào dấu ‘.’:java -classpath ././ com.tino.HelloWorld

Vấn đề của bạn sẽ được giải quyết nhanh hơn, ít lỗi hơn.

Trong trường hợp bạn đang sử dụng các hệ điều hành khác, bạn có thể tham khảo tài liệu gốc của Oracle về PATH và CLASSPATH để hiểu rõ hơn nhé!

Cácjava <class-name>cú pháp lệnh

Trước hết, bạn cần hiểu đúng cách để khởi chạy một chương trình bằng lệnhjava(hoặcjavaw).

Cú pháp bình thường1là đây:

    java [ <options> ] <class-name> [<arg> ...]

trong đó<option>là một tùy chọn dòng lệnh (bắt đầu bằng ký tự “-“),<class-name>là tên lớp Java đủ điều kiện và<arg>là một đối số dòng lệnh tùy ý được truyền cho ứng dụng của bạn.


1 – Có một số cú pháp khác được mô tả ở gần cuối câu trả lời này.

Tên đủ điều kiện (FQN) cho lớp được viết theo quy ước như bạn làm trong mã nguồn Java; ví dụ

    packagename.packagename2.packagename3.ClassName

Tuy nhiên, một số phiên bản củajavalệnh cho phép bạn sử dụng dấu gạch chéo thay vì dấu chấm; ví dụ

    packagename/packagename2/packagename3/ClassName

mà (khó hiểu) trông giống như một tên đường dẫn tệp, nhưng không phải là một tên. Lưu ý rằng thuật ngữtên đủ điều kiệnlà thuật ngữ Java tiêu chuẩn … không phải là thứ tôi vừa tạo ra để làm bạn bối rối 🙂

Dưới đây là một ví dụ về mộtjavalệnh sẽ trông như thế nào:

    java -Xmx100m com.acme.example.ListUsers fred joe bert

Ở trên sẽ gây rajavalệnh để làm như sau:

  1. Tìm kiếm phiên bản biên dịch củacom.acme.example.ListUserslớp.
  2. Tải lớp.
  3. Kiểm tra xem lớp có mộtmainphương thức vớichữ ký,kiểu trả vềvà cácsửa đổiđược đưa ra bởipublic static void main(String[]). (Lưu ý, tên của đối số phương thứcKHÔNG phảilà một phần của chữ ký.)
  4. Gọi phương thức đó truyền cho nó các đối số dòng lệnh (“fred”, “joe”, “bert”) là aString[].

Lý do tại sao Java không thể tìm thấy lớp

Khi bạn nhận được thông báo “Không thể tìm hoặc tải lớp chính …”, điều đó có nghĩa là bước đầu tiên đã thất bại. Cácjavalệnh đã không thể tìm thấy những lớp. Và quả thực, những “…” trong thông điệp sẽ làtên lớp đầy đủjavalà tìm kiếm.

Vậy tại sao nó không thể tìm thấy lớp học?

Lý do số 1 – bạn đã mắc lỗi với đối số tên lớp

Nguyên nhân có thể đầu tiên là bạn có thể đã cung cấp tên lớp sai. (Hoặc … tên lớp đúng, nhưng ở dạng sai.) Xem xét ví dụ trên, đây là một loạt cáccách saiđể chỉ định tên lớp:

Lý do # 2 – đường dẫn lớp của ứng dụng được chỉ định không chính xác

Nguyên nhân có khả năng thứ hai là tên lớp là chính xác, nhưngjavalệnh không thể tìm thấy lớp. Để hiểu điều này, bạn cần hiểu khái niệm về “classpath”. Điều này được giải thíchtốtbởi tài liệu của Oracle:

Vì vậy, nếu bạn đã chỉ định tên lớp một cách chính xác, điều tiếp theo cần kiểm tra là bạn đã chỉ định chính xác đường dẫn lớp:

  1. Đọc ba tài liệu liên kết ở trên. (Có … ĐỌC chúng! Điều quan trọng là một lập trình viên Java phảihiểuít nhất những điều cơ bản về cách các cơ chế đường dẫn Java hoạt động.)
  2. Nhìn vào dòng lệnh và / hoặc biến môi trường CLASSPATH có hiệu lực khi bạn chạyjavalệnh. Kiểm tra xem tên thư mục và tên tệp JAR có đúng không.
  3. Nếu có tên đường dẫntương đốitrong đường dẫn lớp, hãy kiểm tra xem chúng có giải quyết chính xác không … từ thư mục hiện tại có hiệu lực khi bạn chạyjavalệnh.
  4. Kiểm tra xem lớp (được đề cập trong thông báo lỗi) có thể được định vị trên đường dẫn lớphiệu quả.
  5. Lưu ý rằng cú pháp classpathkhácvới Windows so với Linux và Mac OS. (Dấu phân tách classpath nằm;trên Windows và:trên các bộ phân loại khác. Nếu bạn sử dụng trình phân tách sai cho nền tảng của mình, bạn sẽ không nhận được thông báo lỗi rõ ràng. Thay vào đó, bạn sẽ nhận được một tệp hoặc thư mục không tồn tại trên đường dẫn sẽ bị bỏ qua trong âm thầm .)

Lý do # 2a – thư mục sai nằm trên đường dẫn lớp

Khi bạn đặt một thư mục trên đường dẫn lớp, nó sẽ tương ứng với thư mục gốc của không gian tên đủ điều kiện. Các lớp được đặt trong cấu trúc thư mục bên dưới gốc đó,bằng cách ánh xạ tên đủ điều kiện vào một tên đường dẫn. Vì vậy, ví dụ, nếu “/ usr / local / acme / class” nằm trên đường dẫn lớp, thì khi JVM tìm kiếm một lớp được gọicom.acme.example.Foon, nó sẽ tìm tệp “. Class ” với tên đường dẫn này:

  /usr/local/acme/classes/com/acme/example/Foon.class

Nếu bạn đã đặt “/ usr / local / acme / class / com / acme / example” trên đường dẫn lớp, thì JVM sẽ không thể tìm thấy lớp.

Lý do # 2b – đường dẫn thư mục con không khớp với FQN

Nếu các lớp FQN của bạn làcom.acme.example.Foon, thì JVM sẽ tìm kiếm “Foon. Class” trong thư mục “com / acme / example”:

Để đưa ra một ví dụ cụ thể, giả sử rằng:

sau đó:

# 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

Ghi chú:

Lý do # 2c – thiếu phụ thuộc từ đường dẫn lớp

Classpath cần bao gồm tất cả các lớpkhác(không phải hệ thống) mà ứng dụng của bạn phụ thuộc vào. (Các lớp hệ thống được đặt tự động và bạn hiếm khi cần quan tâm đến vấn đề này.) Để lớp chính tải chính xác, JVM cần tìm:

(Lưu ý: các đặc tả JLS và JVM cho phép một số phạm vi để JVM tải các lớp “một cách lười biếng” và điều này có thể ảnh hưởng khi ném ngoại lệ trình nạp lớp.)

Lý do # 3 – lớp đã bị khai báo sai gói

Đôi khi xảy ra việc ai đó đặt tệp mã nguồn vào thư mục sai trong cây mã nguồn của họ hoặc họ bỏ qua phầnpackagekhai báo. Nếu bạn làm điều này trong một IDE, trình biên dịch của IDE sẽ cho bạn biết về điều này ngay lập tức. Tương tự như vậy nếu bạn sử dụng một công cụ xây dựng Java phong nha, công cụ này sẽ chạyjavactheo cách sẽ phát hiện vấn đề. Tuy nhiên, nếu bạn xây dựng mã Java bằng tay, bạn có thể thực hiện theo cách mà trình biên dịch không nhận thấy vấn đề và tệp “. Class” kết quả không nằm ở vị trí mà bạn mong đợi.

Vẫn không thể tìm thấy vấn đề?

Có rất nhiều thứ để kiểm tra, và rất dễ bỏ lỡ một cái gì đó. Hãy thử thêm-Xdiagtùy chọn vàojavadòng lệnh (như điều đầu tiên saujava). Nó sẽ đưa ra nhiều thứ khác nhau về tải lớp và điều này có thể cung cấp cho bạn manh mối về vấn đề thực sự là gì.

Ngoài ra, hãy xem xét các sự cố có thể xảy ra do sao chép và dán các ký tự vô hình hoặc không phải ASCII từ các trang web, tài liệu, v.v. Và xem xét “homoglyphs”, hai chữ cái hoặc ký hiệu trông giống nhau … nhưng không.

Cuối cùng, rõ ràng bạn có thể gặp phải vấn đề này nếu bạn cố khởi chạy từ tệp JAR có chữ ký không chính xác(META-INF/*.SF).


Cú pháp thay thế chojava

Có ba cú pháp thay thế cho các chương trình Java khởi chạy bằng cách sử dụngjava command.

1) Cú pháp được sử dụng để khởi chạy tệp JAR “thực thi” như sau:

  java [ <options> ] -jar <jar-file-name> [<arg> ...]

ví dụ

  java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred

Tên của lớp điểm đầu vào (nghĩa làcom.acme.example.ListUser) và đường dẫn lớp được chỉ định trong MANIFEST của tệp JAR.

2) Cú pháp khởi chạy một ứng dụng từ một mô-đun (Java 9 trở lên) như sau:

  java [ <options> ] --module <module>[/<mainclass>] [<arg> ...]

Tên của lớp entrypoint được xác định bởi<module>chính nó, hoặc được đưa ra bởi tùy chọn<mainclass>.

3) Từ Java 11 trở đi, bạn có thể biên dịch và chạy một tệp mã nguồn duy nhất và chạy nó với cú pháp sau:

  java [ <options> ] <sourcefile> [<arg> ...]

trong đó (thường là) một tệp có hậu tố “.java”.

Để biết thêm chi tiết, vui lòng tham khảo tài liệu chính thức chojavalệnh phát hành Java mà bạn đang sử dụng.


IDE

Một IDE Java điển hình có hỗ trợ để chạy các ứng dụng Java trong chính JVM IDE hoặc trong một JVM con. Chúngthườngmiễn dịch với ngoại lệ cụ thể này, vì IDE sử dụng các cơ chế riêng của nó để xây dựng đường dẫn lớp thời gian chạy, xác định lớp chính và tạojavadòng lệnh.

Tuy nhiên vẫn có thể xảy ra ngoại lệ này, nếu bạn làm những việc phía sau IDE. Ví dụ, nếu trước đây bạn đã thiết lập Trình khởi chạy ứng dụng cho ứng dụng Java của mình trong Eclipse và sau đó bạn đã di chuyển tệp JAR chứa lớp “chính” sang một vị trí khác trong hệ thống tệpmà không thông báo cho Eclipse, Eclipse sẽ vô tình khởi chạy JVM với một classpath không chính xác.

Nói tóm lại, nếu bạn gặp vấn đề này trong IDE, hãy kiểm tra những thứ như trạng thái IDE cũ, tham chiếu dự án bị hỏng hoặc cấu hình trình khởi chạy bị hỏng.

IDE cũng có thể bị nhầm lẫn. IDE là những phần mềm cực kỳ phức tạp bao gồm nhiều phần tương tác. Nhiều trong số các phần này áp dụng các chiến lược bộ nhớ đệm khác nhau để làm cho toàn bộ IDE đáp ứng. Điều này đôi khi có thể đi sai, và một triệu chứng có thể là vấn đề khi khởi chạy ứng dụng. Nếu bạn nghi ngờ điều này có thể xảy ra, đáng để thử những thứ khác như khởi động lại IDE của bạn, xây dựng lại dự án

Nguồn:

Exit mobile version