Zoeken…


Invoering

Het classpath toont plaatsen waar de Java-runtime naar klassen en bronnen moet zoeken. Het classpath wordt ook gebruikt door de Java-compiler om eerder gecompileerde en externe afhankelijkheden te vinden.

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: -

  1. Die vereist door het Java-platform worden eerst geladen, zoals die in de Java Class Library en zijn afhankelijkheden.
  2. Extensieklassen worden vervolgens geladen (dwz die in jre/lib/ext/ )
  3. 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.

  1. Het kan worden ingesteld met behulp van de omgevingsvariabele CLASSPATH :

     set CLASSPATH=...         # Windows and csh
     export CLASSPATH=...      # Unix ksh/bash
    
  2. 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 omgevingsvariabele CLASSPATH .

  3. Het klassepad voor een uitvoerbaar JAR-bestand wordt opgegeven met behulp van het element Class-Path in MANIFEST.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 geen Class-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:

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:

  1. Classpath-jokertekens werden voor het eerst geïntroduceerd in Java 6. Eerdere versies van Java behandelen "*" niet als een jokerteken.
  2. U kunt geen andere tekens vóór of na de " " plaatsen; bijv. "someFolder / .jar" is geen wildcard.
  3. 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.
  4. Een jokerteken komt alleen overeen met JAR-bestanden in de map zelf, niet in de submappen.
  5. 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 in MANIFEST.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:

  1. Wijs de klassennaam toe aan een relatieve klassebestand padnaam RP . De toewijzing van klassenamen aan klassenbestandsnamen wordt elders beschreven.

  2. Voor elk item E in het klassenpad:

    • Als het item een bestandssysteemmap is:
      • Los RP ten opzichte van E om een absolute padnaam AP .
      • Test of AP een pad is voor een bestaand bestand.
      • Zo ja, laad de klasse uit dat bestand
    • 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.

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.)



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow