Java Language
Het Classpath
Zoeken…
Invoering
Opmerkingen
Java-klasse wordt geladen
De JVM (Java Virtual Machine) laadt klassen wanneer en wanneer de klassen vereist zijn (dit wordt lui laden genoemd). De locaties van de te gebruiken klassen worden op drie plaatsen gespecificeerd: -
- Die vereist door het Java-platform worden eerst geladen, zoals die in de Java Class Library en zijn afhankelijkheden.
- Extensieklassen worden vervolgens geladen (dwz die in
jre/lib/ext/
) - Door de gebruiker gedefinieerde klassen via het classpath worden vervolgens geladen
Klassen worden geladen met klassen die subtypen zijn van java.lang.ClassLoader
. Dit wordt in meer detail beschreven in dit onderwerp: Classloaders .
classpath
Het classpath is een parameter die wordt gebruikt door de JVM of compiler en die de locaties van door de gebruiker gedefinieerde klassen en pakketten aangeeft. Dit kan worden ingesteld op de opdrachtregel zoals bij de meeste van deze voorbeelden of via een omgevingsvariabele ( CLASSPATH
)
Verschillende manieren om het klassenpad op te geven
Er zijn drie manieren om het klassenpad in te stellen.
Het kan worden ingesteld met behulp van de omgevingsvariabele
CLASSPATH
:set CLASSPATH=... # Windows and csh export CLASSPATH=... # Unix ksh/bash
Het kan als volgt op de opdrachtregel worden ingesteld
java -classpath ... javac -classpath ...
Merk op dat de optie
-classpath
(of-cp
) voorrang heeft op de omgevingsvariabeleCLASSPATH
.Het klassepad voor een uitvoerbaar JAR-bestand wordt opgegeven met behulp van het element
Class-Path
inMANIFEST.MF
:Class-Path: jar1-name jar2-name directory-name/jar3-name
Merk op dat dit alleen van toepassing is als het JAR-bestand als volgt wordt uitgevoerd:
java -jar some.jar ...
In deze uitvoeringsmodus worden de optie
-classpath
en de omgevingsvariabele CLASSPATH genegeerd, zelfs als het JAR-bestand geenClass-Path
element heeft.
Als er geen classpath is opgegeven, is het standaard classpath het geselecteerde JAR-bestand bij gebruik van java -jar
of anders de huidige map.
Verwant:
- https://docs.oracle.com/javase/tutorial/deployment/jar/downman.html
- http://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html
Alle JAR's in een map toevoegen aan het klassenpad
Als u alle JAR's in de directory aan het classpath wilt toevoegen, kunt u dit bondig doen met de syntaxis van de classpath-wildcard; bijvoorbeeld:
someFolder/*
Dit vertelt de JVM om alle JAR- en ZIP-bestanden in de map someFolder
aan het classpath toe te voegen. Deze syntaxis kan worden gebruikt in een -cp
argument, een CLASSPATH
omgevingsvariabele, of een Class-Path
attribuut in manifest file.See een uitvoerbaar JAR-bestand van de Class Path instellen: Klassepad Wild Cards voor voorbeelden en waarschuwingen.
Opmerkingen:
- Classpath-jokertekens werden voor het eerst geïntroduceerd in Java 6. Eerdere versies van Java behandelen "*" niet als een jokerteken.
- U kunt geen andere tekens vóór of na de " " plaatsen; bijv. "someFolder / .jar" is geen wildcard.
- Een jokerteken komt alleen overeen met bestanden met het achtervoegsel ".jar" of ".JAR". ZIP-bestanden worden genegeerd, net als JAR-bestanden met een ander achtervoegsel.
- Een jokerteken komt alleen overeen met JAR-bestanden in de map zelf, niet in de submappen.
- Wanneer een groep JAR-bestanden wordt gekoppeld aan een jokerteken, wordt hun relatieve volgorde op het klassepad niet opgegeven.
Syntaxis van het klassepad
Het classpath is een reeks vermeldingen die mappadnamen, JAR- of ZIP-bestandspaden of JAR / ZIP-jokertekenspecificaties zijn.
Voor een klassepad dat is opgegeven op de opdrachtregel (bijvoorbeeld
-classpath
) of als omgevingsvariabele, moeten de items worden gescheiden met;
(puntkomma) tekens op Windows, of:
(dubbele punt) tekens op andere platforms (Linux, UNIX, MacOSX enzovoort).Gebruik voor het
Class-Path
element inMANIFEST.MF
een JAR-bestand een spatie om de items te scheiden.
Soms is het nodig om een spatie in te voegen in een klassepaditem
Wanneer het classpath op de opdrachtregel wordt opgegeven, is het gewoon een kwestie van het juiste shell-citaat gebruiken. Bijvoorbeeld:
export CLASSPATH="/home/user/My JAR Files/foo.jar:second.jar"
(De details kunnen afhankelijk zijn van de opdrachtshell die u gebruikt.)
Wanneer het klassepad is opgegeven in een JAR-bestand, is dit een "MANIFEST.MF" -bestand, moet URL-codering worden gebruikt.
Class-Path: /home/user/My%20JAR%20Files/foo.jar second.jar
Dynamisch klassenpad
Soms is het niet voldoende om alle JAR's uit een map toe te voegen, bijvoorbeeld wanneer u een native code hebt en een subset JAR's moet selecteren. In dit geval hebt u twee hoofdmethoden main()
. De eerste bouwt een classloader en gebruikt deze classloader om de tweede main()
aan te roepen.
Hier is een voorbeeld dat de juiste SWT native JAR voor uw platform selecteert, alle JAR's van uw applicatie toevoegt en vervolgens de echte main()
-methode oproept: Cross-platform Java SWT Application maken
Laad een bron uit het classpath
Het kan handig zijn om een bron (afbeelding, tekstbestand, eigenschappen, KeyStore, ...) te laden die in een JAR is verpakt. Voor dit doel kunnen we de Class
en ClassLoader
s gebruiken.
Stel dat we de volgende projectstructuur hebben:
program.jar
|
\-com
\-project
|
|-file.txt
\-Test.class
En we willen toegang hebben tot de inhoud van file.txt
vanuit de klasse Test
. We kunnen dit doen door de classloader te vragen:
InputStream is = Test.class.getClassLoader().getResourceAsStream("com/project/file.txt");
Door de classloader te gebruiken, moeten we het volledig gekwalificeerde pad van onze resource (elk pakket) opgeven.
Of we kunnen het testklasse-object ook rechtstreeks vragen
InputStream is = Test.class.getResourceAsStream("file.txt");
Met het klasseobject is het pad relatief ten opzichte van de klasse zelf. Test.class
onze Test.class
deel com.project
pakket com.project
, hetzelfde als file.txt
, hoeven we helemaal geen pad op te geven.
We kunnen echter absolute paden uit het klasseobject als volgt gebruiken:
is = Test.class.getResourceAsStream("/com/project/file.txt");
Klasnamen toewijzen aan padnamen
De standaard Java-toolchain (en tools van derden die zijn ontworpen om ermee te werken) hebben specifieke regels voor het toewijzen van de namen van klassen aan de padnamen van bestanden en andere bronnen die hen vertegenwoordigen.
De toewijzingen zijn als volgt
- Voor klassen in het standaardpakket zijn de padnamen eenvoudige bestandsnamen.
- Voor klassen in een benoemd pakket worden de componenten van de pakketnaam toegewezen aan mappen.
- Voor geneste en binnenklassen wordt de bestandsnaamcomponent gevormd door de klassenamen te voegen met een
$
-teken. - Voor anonieme binnenklassen worden nummers gebruikt in plaats van namen.
Dit wordt geïllustreerd in de volgende tabel:
Naam van de klasse | Bronpadnaam | Classfile padnaam |
---|---|---|
SomeClass | SomeClass.java | SomeClass.class |
com.example.SomeClass | com/example/SomeClass.java | com/example/SomeClass.class |
SomeClass.Inner | (in SomeClass.java ) | SomeClass$Inner.class |
SomeClass anon binnenklassen | (in SomeClass.java ) | SomeClass$1.class , SomeClass$2.class , enz |
Wat het klassenpad betekent: hoe zoekopdrachten werken
Het doel van het classpath is om een JVM te vertellen waar hij klassen en andere bronnen kan vinden. De betekenis van het classpath en het zoekproces zijn met elkaar verweven.
Het classpath is een vorm van een zoekpad dat een reeks locaties opgeeft om naar bronnen te zoeken. In een standaard classpath zijn deze plaatsen ofwel een map in het hostbestandssysteem, een JAR-bestand of een ZIP-bestand. In alle gevallen is de locatie de root van een naamruimte waarnaar wordt gezocht.
De standaardprocedure voor het zoeken naar een klasse op het klassenpad is als volgt:
Wijs de klassennaam toe aan een relatieve klassebestand padnaam
RP
. De toewijzing van klassenamen aan klassenbestandsnamen wordt elders beschreven.Voor elk item
E
in het klassenpad:- Als het item een bestandssysteemmap is:
- Los
RP
ten opzichte vanE
om een absolute padnaamAP
. - Test of
AP
een pad is voor een bestaand bestand. - Zo ja, laad de klasse uit dat bestand
- Los
- Als het item een JAR- of ZIP-bestand is:
- Lookup
RP
in de JAR / ZIP-bestandsindex. - Als de overeenkomstige JAR / ZIP-bestandsvermelding bestaat, laadt u de klasse uit die vermelding.
- Lookup
- Als het item een bestandssysteemmap is:
De procedure voor het zoeken naar een bron op het klassenpad is afhankelijk van of het bronpad absoluut of relatief is. Voor een absoluut resourcepad is de procedure als hierboven. Voor een relatief bronpad dat is opgelost met Class.getResource
of Class.getResourceAsStream
, wordt het pad voor het Class.getResourceAsStream
voorafgaand aan het zoeken voorafgegaan.
(Merk op dat dit de procedures zijn die worden geïmplementeerd door de standaard Java classloaders. Een aangepaste classloader kan de zoekopdracht anders uitvoeren.)
Het bootstrap-klassenpad
De normale Java-classloaders zoeken eerst naar klassen in het bootstrap-klassenpad, voordat wordt gecontroleerd op uitbreidingen en het toepassingsklassepad. Standaard bestaat het bootstrap-klassenpad uit het bestand "rt.jar" en enkele andere belangrijke JAR-bestanden die worden geleverd door de JRE-installatie. Deze bieden alle klassen in de standaard Java SE-klassenbibliotheek, samen met verschillende "interne" implementatieklassen.
Onder normale omstandigheden hoeft u zich hier geen zorgen over te maken. Standaard commando's als java
, javac
en ga zo maar door de juiste versies van de runtime bibliotheken.
Heel af en toe is het noodzakelijk om het normale gedrag van de Java-runtime te negeren door een alternatieve versie van een klasse in de standaardbibliotheken te gebruiken. U kunt bijvoorbeeld in de runtime-bibliotheken een bug tegenkomen die u niet normaal kunt omzeilen. In een dergelijke situatie is het mogelijk om een JAR-bestand met de gewijzigde klasse te maken en dit vervolgens toe te voegen aan het bootstrap-klassenpad dat de JVM start.
De opdracht java
biedt de volgende -X
opties voor het wijzigen van het bootstrap-klassenpad:
-
-Xbootclasspath:<path>
vervangt het huidige opstartklassepad door het opgegeven pad. -
-Xbootclasspath/a:<path>
voegt het opgegeven pad toe aan het huidige opstartklassepad. -
-Xbootclasspath/p:<path>
plaatst het opgegeven pad naar het huidige opstartklassepad.
Merk op dat wanneer u de bootclasspath-opties gebruikt om een Java-klasse (etcetera) te vervangen of te negeren, u technisch Java aanpast. Er kunnen licentie-implicaties zijn als u vervolgens uw code distribueert. (Raadpleeg de algemene voorwaarden van de Java Binary License ... en raadpleeg een advocaat.)