Recherche…


Introduction

Le classpath répertorie les endroits où le runtime Java doit rechercher des classes et des ressources. Le classpath est également utilisé par le compilateur Java pour rechercher les dépendances précédemment compilées et externes.

Remarques

Chargement de classe Java

La machine virtuelle Java (Java Virtual Machine) va charger les classes au fur et à mesure que les classes sont requises (cela s'appelle le chargement différé). Les emplacements des classes à utiliser sont spécifiés à trois endroits: -

  1. Ceux requis par la plate-forme Java sont chargés en premier, tels que ceux de la bibliothèque de classes Java et de ses dépendances.
  2. Les classes d'extension sont chargées ensuite (c'est-à-dire celles de jre/lib/ext/ )
  3. Les classes définies par l'utilisateur via le classpath sont ensuite chargées

Les classes sont chargées à l'aide de classes qui sont des sous-types de java.lang.ClassLoader . Ceci décrit plus en détail dans cette rubrique: Chargeurs de classes .

Chemin de classe

Le classpath est un paramètre utilisé par la JVM ou le compilateur qui spécifie les emplacements des classes et des packages définis par l'utilisateur. Cela peut être défini dans la ligne de commande comme avec la plupart de ces exemples ou via une variable d'environnement ( CLASSPATH )

Différentes manières de spécifier le classpath

Il existe trois façons de définir le chemin de classe.

  1. Il peut être défini à l'aide de la CLASSPATH environnement CLASSPATH :

     set CLASSPATH=...         # Windows and csh
     export CLASSPATH=...      # Unix ksh/bash
    
  2. Il peut être défini sur la ligne de commande comme suit

     java -classpath ...
     javac -classpath ...
    

    Notez que l' -classpath (ou -cp ) est prioritaire sur la CLASSPATH environnement CLASSPATH .

  3. Le Class-Path d'un fichier JAR exécutable est spécifié à l'aide de l'élément Class-Path dans MANIFEST.MF :

     Class-Path: jar1-name jar2-name directory-name/jar3-name
    

    Notez que cela ne s'applique que lorsque le fichier JAR est exécuté comme ceci:

     java -jar some.jar ...
    

    Dans ce mode d'exécution, l'option -classpath et la variable d'environnement CLASSPATH seront ignorées, même si le fichier JAR ne contient pas d'élément Class-Path .

Si aucun classpath n'est spécifié, le classpath par défaut est le fichier JAR sélectionné lors de l'utilisation de java -jar ou du répertoire en cours.

En relation:

Ajout de tous les JAR dans un répertoire au classpath

Si vous souhaitez ajouter tous les fichiers JAR dans le répertoire classpath, vous pouvez le faire de manière concise à l'aide de la syntaxe de classe de chemin d'accès au classpath; par exemple:

 someFolder/*

Cela indique à la JVM d'ajouter tous les fichiers JAR et ZIP du répertoire someFolder au classpath. Cette syntaxe peut être utilisée dans un -cp argument un CLASSPATH variable d'environnement ou d' une Class-Path attribut dans file.See manifeste d'un fichier exécutable JAR Réglage de la classe Chemin: Classe Chemin Jokers des exemples et des mises en garde.

Remarques:

  1. Les caractères génériques du chemin de classe ont été introduits pour la première fois dans Java 6. Les versions antérieures de Java ne traitaient pas "*" comme un caractère générique.
  2. Vous ne pouvez pas mettre d'autres caractères avant ou après le " "; Par exemple, "someFolder / .jar" n'est pas un joker.
  3. Un caractère générique ne correspond qu'à des fichiers portant le suffixe ".jar" ou ".JAR". Les fichiers ZIP sont ignorés, de même que les fichiers JAR avec un suffixe différent.
  4. Un caractère générique ne correspond qu'à des fichiers JAR du répertoire lui-même et non à ses sous-répertoires.
  5. Lorsqu'un groupe de fichiers JAR est associé à une entrée générique, leur ordre relatif sur le chemin de classe n'est pas spécifié.

Syntaxe du chemin de classe

Le classpath est une séquence d'entrées qui sont les noms de chemin d'accès aux répertoires, les chemins d'accès aux fichiers JAR ou ZIP, ou les spécifications de caractères génériques JAR / ZIP.

  • Pour un classpath spécifié sur la ligne de commande (par exemple -classpath ) ou comme variable d'environnement, les entrées doivent être séparées par ; (point-virgule) caractères sur Windows, ou : (deux-points) caractères sur d'autres plates-formes (Linux, UNIX, MacOSX, etc.).

  • Pour l'élément Class-Path dans MANIFEST.MF un fichier JAR, utilisez un seul espace pour séparer les entrées.

Parfois, il est nécessaire d'intégrer un espace dans une entrée classpath

  • Lorsque le chemin de classe est spécifié sur la ligne de commande, il suffit d'utiliser les citations de shell appropriées. Par exemple:

    export CLASSPATH="/home/user/My JAR Files/foo.jar:second.jar"
    

    (Les détails peuvent dépendre du shell de commande que vous utilisez.)

  • Lorsque le chemin de classe est spécifié dans un fichier JAR, le fichier "MANIFEST.MF" doit être utilisé.

     Class-Path: /home/user/My%20JAR%20Files/foo.jar second.jar
    

Classpath dynamique

Parfois, il ne suffit pas d’ajouter tous les fichiers JAR d’un dossier, par exemple lorsque vous avez du code natif et que vous devez sélectionner un sous-ensemble de fichiers JAR. Dans ce cas, vous avez besoin de deux méthodes main() . Le premier construit un classloader et utilise ensuite ce classloader pour appeler le second main() .

Voici un exemple qui sélectionne le JAR natif SWT correct pour votre plate-forme, ajoute tous les JAR de votre application, puis appelle la méthode main() : Créer une application Java SWT multi-plateforme

Charger une ressource depuis le classpath

Il peut être utile de charger une ressource (image, fichier texte, propriétés, KeyStore, ...) qui est incluse dans un JAR. Pour cela, nous pouvons utiliser les Class et ClassLoader .

Supposons que nous ayons la structure de projet suivante:

program.jar
|
\-com
  \-project
    |
    |-file.txt
    \-Test.class  

Et nous voulons accéder au contenu de file.txt de la classe Test . Nous pouvons le faire en demandant au classloader:

InputStream is = Test.class.getClassLoader().getResourceAsStream("com/project/file.txt");

En utilisant le classloader, nous devons spécifier le chemin complet de notre ressource (chaque paquet).

Ou alternativement, nous pouvons demander l'objet de classe de test directement

InputStream is = Test.class.getResourceAsStream("file.txt");

En utilisant l'objet class, le chemin est relatif à la classe elle-même. Notre Test.class étant dans le package com.project , identique à file.txt , nous n'avons pas besoin de spécifier de chemin du tout.

Nous pouvons cependant utiliser des chemins absolus à partir de l'objet de classe, comme ceci:

 is = Test.class.getResourceAsStream("/com/project/file.txt");

Mappage de noms de classes sur des chemins d'accès

La chaîne d'outils Java standard (et les outils tiers conçus pour interagir avec eux) ont des règles spécifiques pour mapper les noms de classes aux noms de fichiers et aux autres ressources qui les représentent.

Les mappages sont les suivants

  • Pour les classes du package par défaut, les chemins d'accès sont des noms de fichiers simples.
  • Pour les classes d'un package nommé, les composants du nom du package sont mappés aux répertoires.
  • Pour les classes imbriquées et internes nommées, le composant filename est formé en joignant les noms de classe avec un caractère $ .
  • Pour les classes internes anonymes, les nombres sont utilisés à la place des noms.

Ceci est illustré dans le tableau suivant:

Nom du cours Chemin d'accès source Chemin d'accès au fichier de classe
SomeClass SomeClass.java SomeClass.class
com.example.SomeClass com/example/SomeClass.java com/example/SomeClass.class
SomeClass.Inner (dans SomeClass.java ) SomeClass$Inner.class
SomeClass anon classes internes (dans SomeClass.java ) SomeClass$1.class , SomeClass$2.class , etc

Que signifie le classpath: comment les recherches fonctionnent

Le classpath a pour but d'indiquer à une machine virtuelle Java où trouver les classes et autres ressources. La signification du chemin de classe et le processus de recherche sont étroitement liés.

Le classpath est une forme de chemin de recherche qui spécifie une séquence d' emplacements pour rechercher des ressources. Dans un classpath standard, ces emplacements sont soit un répertoire dans le système de fichiers hôte, un fichier JAR ou un fichier ZIP. Dans chaque cas, l'emplacement est la racine d'un espace de noms qui sera recherché.

La procédure standard pour rechercher une classe sur le classpath est la suivante:

  1. Carte du nom de la classe à un chemin d'accès relatif ClassFile RP . Le mappage des noms de classe avec les noms de fichiers de classe est décrit ailleurs.

  2. Pour chaque entrée E dans le classpath:

    • Si l'entrée est un répertoire de système de fichiers:
      • Résoudre RP rapport à E pour donner un chemin d'accès absolu AP .
      • Testez si AP est un chemin pour un fichier existant.
      • Si oui, chargez la classe à partir de ce fichier
    • Si l'entrée est un fichier JAR ou ZIP:
      • Recherche RP dans l'index du fichier JAR / ZIP.
      • Si l'entrée de fichier JAR / ZIP correspondante existe, chargez la classe à partir de cette entrée.

La procédure de recherche d'une ressource sur le chemin de classe dépend du caractère absolu ou relatif du chemin d'accès à la ressource. Pour un chemin de ressource absolu, la procédure est comme ci-dessus. Pour un chemin de ressource relatif résolu avec Class.getResource ou Class.getResourceAsStream , le chemin du package de classes est ajouté avant la recherche.

(Notez que ces procédures sont implémentées par les chargeurs de classes Java standard. Un chargeur de classe personnalisé peut effectuer la recherche différemment.)

Le classpath du bootstrap

Les classloaders Java normaux recherchent d'abord les classes dans le chemin de classe bootstrap, avant de rechercher les extensions et le chemin de classe de l'application. Par défaut, le classpath bootstrap se compose du fichier "rt.jar" et d'autres fichiers JAR importants fournis par l'installation JRE. Celles-ci fournissent toutes les classes de la bibliothèque de classes Java SE standard, ainsi que diverses classes d'implémentation "internes".

Dans des circonstances normales, vous n'avez pas à vous en préoccuper. Par défaut, les commandes telles que java , javac , etc. utiliseront les versions appropriées des bibliothèques d'exécution.

Très occasionnellement, il est nécessaire de remplacer le comportement normal du runtime Java en utilisant une version alternative d'une classe dans les bibliothèques standard. Par exemple, vous pourriez rencontrer un bogue "show stopper" dans les bibliothèques d'exécution que vous ne pouvez pas contourner par des moyens normaux. Dans une telle situation, il est possible de créer un fichier JAR contenant la classe modifiée, puis de l'ajouter au chemin de classe bootstrap qui lance la machine virtuelle Java.

La commande java fournit les options -X suivantes pour modifier le chemin de classe bootstrap:

  • -Xbootclasspath:<path> remplace le -Xbootclasspath:<path> démarrage actuel par le chemin fourni.
  • -Xbootclasspath/a:<path> ajoute le chemin fourni au chemin de classe de démarrage actuel.
  • -Xbootclasspath/p:<path> ajoute le chemin fourni au chemin de classe de démarrage actuel.

Notez que lorsque vous utilisez les options bootclasspath pour remplacer ou remplacer une classe Java (etc.), vous modifiez techniquement Java. Si vous distribuez votre code, cela peut avoir des conséquences sur la licence. (Reportez-vous aux conditions générales de la licence binaire Java… et consultez un avocat.)



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow