Hva betyr "Kunne ikke finne eller laste inn hovedklassen"?
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?
1270
3
Syntaksen for
java
-kommandoenFørst og fremst må du forstå den riktige måten å starte et program ved hjelp av kommandoen
java
(ellerjavaw
). Den normale syntaksen1 er denne:der
er et kommandolinjealternativ (som begynner med et "-" tegn),
er et fullt kvalifisert Java-klassenavn, og `` 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.
Noen versjoner av
java
-kommandoen lar deg imidlertid bruke skråstreker i stedet for punktum; f.eks.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: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 vedpublic static void main(String[])
. (Merk at navnet på metodeargumentet ikke er en del av signaturen).Kall den metoden og gi den kommandolinjeargumentene ("fred", "joe", "bert") som en
String[]
. Årsaker til at Java ikke finner klassenNår du får meldingen "Could not find or load main class ...", betyr det at det første trinnet har mislyktes. Kommandoen
java
var ikke i stand til å finne klassen. Og faktisk vil "..." i meldingen være det fullt kvalifiserte klassenavnet somjava
leter etter. Så hvorfor kan det være ute av stand til å finne klassen?Årsak nr. 1 - du gjorde en feil med argumentet classname
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:
Når klassen er deklarert i en pakke som
com.acme.example
, må du bruke hele klassenavnet inkludert pakkenavnet ijava
-kommandoen; f.eks. java com.acme.eksempel.ListUserEksempel 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
Eksempel nr. 6 - du har glemt hele klassenavnet java mange argumenter Årsak nr. 2 - applikasjonens klassesti er feil spesifisert
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:The
java
kommando dokumentasjonStille inn klassestien.
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
.Merk at syntaksen for klassestien er forskjellig for Windows og Linux og Mac OS. (Skilletegn for klassesti er
;
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:Hvis du hadde satt "/usr/local/acme/classes/com/acme/example" på klassestien, ville JVM ikke kunne finne klassen. Årsak #2b - underkatalog banen ikke samsvarer med FQN
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:Merknader:
Alternativet
-classpath
kan forkortes til-cp
i de fleste Java-versjoner. Sjekk de respektive manuelle oppføringene forjava
,javac
og så videre.Tenk deg nøye om når du velger mellom absolutte og relative banenavn i klassestier. Husk at et relativt banenavn kan gå i stykker hvis den aktuelle katalogen endres.
Årsak nr. 2c - avhengigheter som mangler i klassestien
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).
alle klasser og grensesnitt som det refereres til ved hjelp av variabel- eller variabeldeklarasjoner, eller metodeanrop eller felttilgangsuttrykk. (Merk: JLS- og JVM-spesifikasjonene gir et visst rom for at en JVM kan laste klasser "lat", og dette kan påvirke når et classloader-unntak kastes). Årsak #3 - klassen har blitt erklært i feil pakken
Det hender av og til at noen legger en kildekodefil inn i feil mappe i kildekodetreet sitt, eller de utelater
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ørejavac
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?Det er mange ting å sjekke, og det er lett å gå glipp av noe. Prøv å legge til
-Xdiag
alternativet tiljava
kommandolinjen (som det første etterjava
). 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.Syntaksen
java -jar
syntaksDen alternative syntaksen som brukes for "kjørbare" JAR-filer er som følger:
f.eks.
I dette tilfellet angis navnet på inngangspunktsklassen (dvs.
com.acme.example.ListUser
) og klassestien i MANIFEST i JAR-filen.IDE-er
En typisk Java IDE har støtte for å kjøre Java-applikasjoner i selve IDE-JVM-en eller i en underordnet JVM. Disse er generelt immune mot dette spesielle unntaket, fordi IDE-en bruker sine egne mekanismer for å konstruere kjøretidsstien, identifisere hovedklassen og opprette kommandolinjen
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.Andre referanser
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:
Jeg slettet bare den referansen, la den til igjen, og det fungerte fint igjen.
Angi først banen ved hjelp av denne kommandoen;
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) ".