Ko nozīmē "Nevar atrast vai ielādēt galveno klasi"?

Bieži sastopama problēma, ar ko saskaras jaunie Java izstrādātāji, ir tā, ka viņu programmas neizdodas palaist ar kļūdas paziņojumu: Nevar atrast vai ielādēt galveno klasi ...

Ko tas nozīmē, kas to izraisa un kā to novērst?

Risinājums

Komandas java sintakse

Vispirms jums jāizprot, kā pareizi palaist programmu, izmantojot java (vai javaw) komandu. Parastā sintakse1 ir šāda:

    java [  ... ]  [ ...]

kur ir komandrindas opcija (sākas ar "-" rakstzīmi), ir pilnīgs Java klases vārds, un `` ir patvaļīgs komandrindas arguments, kas tiek nodots jūsu programmai.
1 - Pastāv otra JAR failu "izpildāmo failu" sintakse, kuru es aprakstīšu apakšā. Pilnīgi kvalificēto klases nosaukumu (FQN) tradicionāli raksta tāpat, kā to rakstītu Java avota kodā; piem.

    packagename.packagename2.packagename3.ClassName

Tomēr dažās java komandas versijās periodu vietā var lietot slīpsvītras; piem.

    packagename/packagename2/packagename3/ClassName

kas (mulsinoši) izskatās kā faila ceļa vārds, bet tāds nav. Ievērojiet, ka termins pilnīgi kvalificēts vārds ir standarta Java terminoloģija ... nevis kaut kas, ko es vienkārši izdomāju, lai jūs maldinātu :-) Lūk, piemērs, kā jāizskatās java komandai:

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

Iepriekš minētais java komandai java veiks šādas darbības:

  1. Meklēt kompilēto com.acme.example.ListUsers klases versiju.
  2. Ielādējiet klasi.
  3. Pārbaudiet, vai klasei ir main metode ar parakstu, atgriešanas tipu un modifikatoriem, kas norādīti ar public static void main(String[]). (Ņemiet vērā, ka metodes argumenta nosaukums nav paraksta daļa.)
  4. Izsauciet šo metodi, nododot tai komandrindas argumentus ("fred", "joe", "bert") kā String[]. Iemesli, kāpēc Java nevar atrast klasi

    Ja tiek parādīts ziņojums "Nevar atrast vai ielādēt galveno klasi ...", tas nozīmē, ka pirmais solis nav izdevies. Komanda java nespēja atrast klasi. Un patiešām, "..." ziņojumā būs pilnīgi kvalificēts klases nosaukums, ko java meklē. Tad kāpēc tā nevar atrast klasi?
    Iemesls Nr. 1 - jūs kļūdījāties ar klases nosaukuma argumentu

    Pirmais iespējamais iemesls ir tas, ka, iespējams, esat norādījis nepareizu klases nosaukumu. (Vai ... pareizo klases nosaukumu, bet nepareizā formā.) Ņemot vērā iepriekš minēto piemēru, šeit ir minēti dažādi nepareizi veidi, kā norādīt klases nosaukumu:

  • Piemērs Nr. 1 - vienkāršs klases nosaukums:

    java ListUser

    Ja klase ir deklarēta pakotnē, piemēram, com.acme.example, tad komandā java jāizmanto pilns klases nosaukums, ieskaitot pakotnes nosaukumu; piem. java com.acme.example.ListUser

  • Piemērs Nr. 2 - faila vai ceļa nosaukums, nevis klases nosaukums: java ListUser.class java com/acme/example/ListUser.class

    1. piemērs - klases nosaukums ar nepareizu locījumu: java com.acme.example.listuser: java com.acme.example.listuser.
  • Piemērs #4 - pārrakstīšanās kļūda java com.acme.example.mistuser

  • Piemērs #5 - avota faila nosaukums java ListUser.java

  • Piemērs #6 - jūs pilnībā aizmirsāt klases nosaukumu java daudz argumentu

  1. iemesls - nepareizi norādīts lietojumprogrammas klases ceļš

    Otrs iespējamais iemesls ir tāds, ka klases nosaukums ir pareizs, bet java komanda nevar atrast klasi. Lai to saprastu, ir jāizprot jēdziens "classpath". Oracle dokumentācijā tas ir labi izskaidrots:

  1. Izlasiet trīs iepriekš minētos dokumentus. (Jā ... LASĪT tos. Ir svarīgi, lai Java programmētājs izprastu vismaz pamatus par to, kā darbojas Java klases ceļa mehānisms.)
  2. Aplūkojiet komandrindu un/vai CLASSPATH vides mainīgo, kas ir spēkā, kad palaižat java komandu. Pārbaudiet, vai direktoriju nosaukumi un JAR failu nosaukumi ir pareizi.
  3. Ja classpath ir relatīvie ceļu nosaukumi, pārbaudiet, vai tie ir pareizi atrisināti ... no pašreizējā direktorija, kas ir spēkā, kad izpildāt java komandu.
  4. Pārbaudiet, vai klasi (kas minēta kļūdas ziņojumā) var atrast efektīvajā klases celiņā.
  5. Ņemiet vērā, ka klases ceļa sintakse ir atšķirīga operētājsistēmai Windows salīdzinājumā ar Linux un Mac OS. (Klases ceļa atdalītājs ir ; operētājsistēmā Windows un : pārējās operētājsistēmās. Ja izmantojat nepareizu atdalītāju savai platformai, jūs nesaņemsiet skaidru kļūdas ziņojumu. Tā vietā ceļā parādīsies neesošs fails vai direktorija, kas tiks ignorēta.) 2.a iemesls - klases ceļā ir nepareiza direktorija

    Kad direktoriju ievietojat klasesceliņā, tas nosacīti atbilst kvalificētās vārdu telpas saknei. Klases tiek izvietotas direktoriju struktūrā zem šīs saknes, pārveidojot pilnībā kvalificēto nosaukumu uz ceļa vārdu. Piemēram, ja "/usr/local/acme/classes" ir klases ceļā, tad, kad JVM meklē klasi ar nosaukumu com.acme.example.Foon, tas meklēs ".class" failu ar šo ceļa nosaukumu:

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

Ja klases ceļā būtu ierakstīts "/usr/local/acme/classes/com/acme/example", tad JVM nevarētu atrast šo klasi. 2.b iemesls - apakšdirektorija ceļš nesakrīt ar FQN

Ja jūsu klases FQN ir com.acme.example.Foon, tad JVM meklēs "Foon.class" direktorijā "com/acme/example":

  • Ja jūsu direktoriju struktūra nesakrīt ar paketes nosaukumiem saskaņā ar iepriekš minēto paraugu, JVM neatradīs jūsu klasi.
  • Ja jūs mēģināsiet pārsaukt klasi, to pārvietojot, arī tas neizdosies ... bet izņēmuma stacktrace būs atšķirīgs. Tā var būt apmēram šāda: Cēlo: java.lang.NoClassDefFoundError: <path> (nepareizs nosaukums: ) jo klases faila FQN neatbilst tam, ko klases ielādētājs sagaida atrast. Lai sniegtu konkrētu piemēru, pieņemsim, ka:
  • Jūs vēlaties palaist com.acme.example.Foon klasi,
  • pilns faila ceļš ir /usr/local/acme/classes/com/acme/example/Foon.class,
  • jūsu pašreizējais darba direktorijs ir /usr/local/acme/classes/com/acme/example/, tad:
# 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

Piezīmes:

  • Vairumā Java versiju -classpath opciju var saīsināt līdz -cp. Pārbaudiet attiecīgos rokasgrāmatas ierakstus par java, javac un tā tālāk.

  • Rūpīgi pārdomājiet, izvēloties starp absolūtajiem un relatīvajiem ceļa nosaukumiem klasesceļos. Atcerieties, ka relatīvais ceļa nosaukums var "pārtrūkt", ja mainās pašreizējais direktorijs.
    c) iemesls - klasesceļā trūkst atkarību

    Klases ceļā ir jāiekļauj visas pārējās (ne sistēmas) klases, no kurām ir atkarīga jūsu lietojumprogramma. (Sistēmas klases tiek izvietotas automātiski, un jums reti kad par to ir jārūpējas). Lai galvenā klase tiktu ielādēta pareizi, JVM ir jāatrod:

  • pašu klasi.

  • visas klases un saskarnes virsklases hierarhijā (piemēram, skatīt https://stackoverflow.com/questions/42880748).

  • visas klases un saskarnes, uz kurām atsaucas, izmantojot mainīgo vai mainīgo deklarācijas, vai metodes izsaukuma vai lauka piekļuves izteiksmes. (Piezīme: JLS un JVM specifikācijas pieļauj, ka JVM var ielādēt klases "laiski", un tas var ietekmēt to, kad tiek izmests klases ielādētāja izņēmums).

  1. iemesls - klase ir deklarēta nepareizā paketē.

    Reizēm gadās, ka kāds ievieto avota koda failu pakotnē nepareizajā avota koda mapē vai arī izlaiž paketes deklarāciju. Ja jūs to darāt kādā IDE, IDE kompilators uzreiz par to paziņos. Līdzīgi, ja jūs izmantojat pienācīgu Java kompilēšanas rīku, tas palaidīs javac tā, lai atklātu šo problēmu. Tomēr, ja veidojat savu Java kodu ar rokām, varat to darīt tā, ka kompilators šo problēmu nepamanīs, un rezultātā izveidotais ".class" fails neatradīsies tajā vietā, kur tas ir paredzēts. Joprojām nevarat atrast problēmu?

    Ir daudz pārbaudāmo lietu, un ir viegli kaut ko palaist garām. Mēģiniet pievienot -Xdiag opciju java komandrindai (kā pirmo pēc java). Tā izvadīs dažādus datus par klašu ielādēšanu, un tas var sniegt jums norādes par to, kas ir īstā problēma. Apsveriet arī iespējamās problēmas, ko izraisa neredzamu vai neASCII rakstzīmju kopēšana un ielīmēšana no tīmekļa vietnēm, dokumentiem utt. Un apsveriet "homoglifus", kad divi burti vai simboli izskatās vienādi... bet tā nav.

    Sintakse java -jar

    Alternatīvā sintakse, ko izmanto "izpildāmiem" JAR failiem, ir šāda:

  java [  ... ] -jar  [ ...]

piem.

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

Šajā gadījumā JAR faila MANIFEST ir norādīts ieejas punkta klases nosaukums (t. i., com.acme.example.ListUser) un klases ceļš.

IDE

Tipiska Java IDE atbalsta Java lietojumprogrammu palaišanu pašā IDE JVM vai meitas JVM. Tās parasti ir pasargātas no šī izņēmuma, jo IDE izmanto savus mehānismus, lai konstruētu izpildes laika klases ceļu, identificētu galveno klasi un izveidotu java komandrindu. Tomēr joprojām ir iespējams, ka šis izņēmums var rasties, ja kaut ko darāt aiz IDE muguras. Piemēram, ja iepriekš Eclipse ir iestatīts lietojumprogrammas palaišanas palaidējs savai Java lietojumprogrammai un pēc tam JAR fails, kurā ir "main" klase, ir pārvietots uz citu vietu failu sistēmā neinformējot Eclipse, Eclipse neapzināti palaistu JVM ar nepareizu klases ceļu. Īsi sakot, ja šī problēma rodas IDE, pārbaudiet, vai IDE stāvoklis nav novecojis, vai nav bojātas projekta atsauces vai palaišanas konfigurācijas. Ir arī iespējams, ka IDE ir vienkārši sajaukta. IDE ir ārkārtīgi sarežģīta programmatūra, kas sastāv no daudzām savstarpēji mijiedarbojošām daļām. Daudzas no šīm daļām izmanto dažādas kešēšanas stratēģijas, lai padarītu IDE kā veselumu atsaucīgu. Dažreiz tās var būt nepareizas, un viens no iespējamiem simptomiem ir problēmas lietojumprogrammu palaišanas laikā. Ja jums ir aizdomas, ka tā varētu notikt, ir vērts izmēģināt IDE restartēšanu un projekta pārbūvi.

Citas atsauces

Komentāri (11)

Dažreiz problēmas cēlonis var nebūt saistīts ar galveno klasi, un man nācās to noskaidrot grūtā ceļā. Tā bija atsauce uz bibliotēku, kuru es pārcēlu, un tā man parādīja:

Nevarēja atrast vai ielādēt galveno klasi xxx Linux

Es vienkārši dzēsu šo atsauci, pievienoju to no jauna, un viss atkal darbojās pareizi.

Komentāri (5)

Vispirms iestatiet ceļu, izmantojot šo komandu;

set path="paste the set path address"

Pēc tam ielādējiet programmu. Ierakstiet "cd (mapes nosaukums)" saglabātajā diskā un kompilējiet to. Piemēram, ja mana programma ir saglabāta D diskā, ierakstiet "D:" nospiediet enter un ierakstiet " cd (mapes nosaukums)".

Komentāri (3)