Et vanlig problem som nye Java-utviklere opplever er at programmene deres ikke kjører med feilmeldingen: Kunne ikke finne eller laste inn hovedklassen ...
Hva betyr dette, hva forårsaker det, og hvordan skal du fikse det?
java <class-name>
-kommandoenFørst og fremst må du forstå den riktige måten å starte et program ved hjelp av kommandoen java
(eller javaw
).
Den normale syntaksen1 er denne:
java [ <option> ... ] <class-name> [<argument> ...]
der <option>
er et kommandolinjealternativ (som begynner med et "-" tegn), <class-name>
er et fullt kvalifisert Java-klassenavn, og <argument>
er et vilkårlig kommandolinjeargument som sendes til programmet.
1 - Det er en annen syntaks for "kjørbare" JAR-filer som jeg vil beskrive nederst.
Det fullt kvalifiserte navnet (FQN) for klassen er konvensjonelt skrevet som du ville gjort i Java-kildekode; f.eks.
packagename.packagename2.packagename3.ClassName
Noen versjoner av java
-kommandoen lar deg imidlertid bruke skråstreker i stedet for punktum; f.eks.
packagename/packagename2/packagename3/ClassName
som (til forveksling) ser ut som et filstinavn, men ikke er det. Merk at begrepet fullstendig kvalifisert navn er standard Java-terminologi ... ikke noe jeg bare har funnet på for å forvirre deg :-)
Her er et eksempel på hvordan en java
-kommando skal se ut:
java -Xmx100m com.acme.example.ListUsers fred joe bert
Ovennevnte kommer til å føre til at java
-kommandoen gjør følgende:
com.acme.example.ListUsers
.main
-metode med signature, return type og modifiers gitt ved public static void main(String[])
. (Merk at navnet på metodeargumentet ikke er en del av signaturen).String[]
.
Årsaker til at Java ikke finner klassenjava
var ikke i stand til å finne klassen. Og faktisk vil "..." i meldingen være det fullt kvalifiserte klassenavnet som java
leter etter.
Så hvorfor kan det være ute av stand til å finne klassen?Den første sannsynlige årsaken er at du kan ha oppgitt feil klassenavn. (Eller ... riktig klassenavn, men i feil form.) Med tanke på eksemplet ovenfor er det en rekke feil måter å angi klassenavnet på:
Eksempel nr. 1 - et enkelt klassenavn:
java ListUser
Når klassen er deklarert i en pakke som com.acme.example
, må du bruke hele klassenavnet inkludert pakkenavnet i java
-kommandoen; f.eks.
java com.acme.eksempel.ListUser
Eksempel 2 - et filnavn eller banenavn i stedet for et klassenavn: java ListUser.class java com/acme/eksempel/ListUser.class
Eksempel nr. 3 - et klassenavn med feil innkapsling: java com.acme.example.listuser
Eksempel nr. 4 - en skrivefeil java com.acme.eksempel.mistuser
Eksempel nr. 5 - et kildefilnavn java ListUser.java
Den andre sannsynlige årsaken er at klassenavnet er riktig, men at kommandoen java
ikke finner klassen. For å forstå dette må du forstå konseptet med "classpath". Dette forklares godt av Oracle-dokumentasjonen:
Java-veiledningen - PATH and CLASSPATH Så ... hvis du har spesifisert klassenavnet riktig, er det neste du må sjekke at du har spesifisert klassestien riktig:
java
. Kontroller at katalognavnene og JAR-filnavnene er korrekte.java
.;
på Windows og :
på de andre. Hvis du bruker feil skilletegn for din plattform, vil du ikke få en eksplisitt feilmelding. I stedet vil du få en ikke-eksisterende fil eller katalog på banen som vil bli ignorert).
Årsak #2a - feil katalog er på klassestienNår du legger en katalog på klassestien, tilsvarer den teoretisk sett roten til det kvalifiserte navnerommet. Klasser er plassert i katalogstrukturen under denne roten, ved å tilordne det fullt kvalifiserte navnet til et banenavn. Så for eksempel, hvis "/usr/local/acme/classes" er på klassebanen, så når JVM ser etter en klasse som heter com.acme.example.Foon
, vil den se etter en ".class" fil med dette banenavnet:
/usr/local/acme/classes/com/acme/example/Foon.class
Hvis klassens FQN er "com.acme.example.Foon", vil JVM-en lete etter "Foon.class" i katalogen "com/acme/example":
com.acme.example.Foon
klassen,/usr/local/acme/classes/com/acme/example/Foon.class
,/usr/local/acme/classes/com/acme/example/
,
deretter:# 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
Merknader:
Alternativet -classpath
kan forkortes til -cp
i de fleste Java-versjoner. Sjekk de respektive manuelle oppføringene for java
, javac
og så videre.
Klassestien må inneholde alle andre (ikke-system) klasser som applikasjonen din er avhengig av. (Systemklassene lokaliseres automatisk, og du trenger sjelden å bekymre deg for dette). For at hovedklassen skal lastes riktig, må JVM-en finne:
selve klassen.
alle klasser og grensesnitt i superklassehierarkiet (se f.eks. https://stackoverflow.com/questions/42880748).
pakke
-deklarasjonen. Hvis du gjør dette i en IDE, vil IDE&# 39s kompilator fortelle deg om dette umiddelbart. Tilsvarende hvis du bruker et anstendig Java-byggeverktøy, vil verktøyet kjøre javac
på en måte som vil oppdage problemet. Men hvis du bygger Java-koden din for hånd, kan du gjøre det på en slik måte at kompilatoren ikke merker problemet, og den resulterende .class-filen ikke er på det stedet du forventer at den skal være.
Finner du fortsatt ikke problemet?-Xdiag
alternativet til java
kommandolinjen (som det første etter java
). Det vil sende ut forskjellige ting om klasselasting, og dette kan gi deg ledetråder om hva det virkelige problemet er.
Vurder også mulige problemer forårsaket av å kopiere og lime inn usynlige eller ikke-ASCII-tegn fra nettsteder, dokumenter og så videre. Og vurder "homoglyfer", der to bokstaver eller symboler ser like ut ... men ikke er det.java -jar <jar file>
syntaksDen alternative syntaksen som brukes for "kjørbare" JAR-filer er som følger:
java [ <option> ... ] -jar <jar-file-name> [<argument> ...]
f.eks.
java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
com.acme.example.ListUser
) og klassestien i MANIFEST i JAR-filen.java
.
Det er imidlertid fortsatt mulig for dette unntaket å oppstå, hvis du gjør ting bak ryggen til IDE. For eksempel, hvis du tidligere har satt opp en Application Launcher for Java-appen din i Eclipse, og du deretter flyttet JAR-filen som inneholder "main" -klassen til et annet sted i filsystemet uten å fortelle Eclipse , vil Eclipse uforvarende starte JVM med en feil klassesti.
Kort sagt, hvis du får dette problemet i en IDE, se etter ting som foreldet IDE-tilstand, ødelagte prosjektreferanser eller ødelagte startkonfigurasjoner.
Det er også mulig for en IDE å bare bli forvirret. IDE-er er enormt kompliserte programvare som består av mange samhandlende deler. Mange av disse delene tar i bruk ulike hurtigbufringsstrategier for å gjøre IDE-en som helhet responsiv. Disse kan noen ganger gå galt, og et mulig symptom er problemer når du starter applikasjoner. Hvis du mistenker at dette kan skje, er det verdt å prøve å starte IDE-en på nytt og gjenoppbygge prosjektet.Noen ganger har det som kan forårsake problemet ingenting å gjøre med hovedklassen, og jeg måtte finne ut dette på den harde måten. Det var et referert bibliotek som jeg flyttet, og det ga meg:
Kunne ikke finne eller laste inn hovedklassen xxx Linux
Jeg slettet bare den referansen, la den til igjen, og det fungerte fint igjen.
Angi først banen ved hjelp av denne kommandoen;
set path="paste the set path address"
Deretter må du laste inn programmet. Skriv "cd (mappenavn)" i den lagrede stasjonen og kompilere den. For eksempel, hvis programmet mitt er lagret på D-stasjonen, skriver du "D: " trykk enter og skriv " cd (mappenavn) ".