Qu'est-ce qu'un chemin de classe et comment le définir?


325

Je lisais juste cette ligne:

La première chose que fait la méthode format () est de charger un modèle Velocity à partir du chemin de classe nommé output.vm

Veuillez expliquer ce que signifiait classpath dans ce contexte et comment je devrais définir le classpath.

Réponses:


531

Lors de la programmation en Java, vous mettez d'autres classes à la disposition de la classe que vous écrivez en plaçant quelque chose comme ça en haut de votre fichier source:

import org.javaguy.coolframework.MyClass;

Ou parfois vous «importez en vrac» des choses en disant:

import org.javaguy.coolframework.*;

Donc plus tard dans votre programme quand vous dites:

MyClass mine = new MyClass();

La machine virtuelle Java saura où trouver votre classe compilée.

Il ne serait pas pratique que la machine virtuelle recherche dans chaque dossier de votre machine, vous devez donc fournir à la machine virtuelle une liste d'emplacements à rechercher. Pour cela, placez les fichiers de dossiers et de fichiers jar dans votre chemin de classe.

Avant de parler de la façon dont le chemin de classe est défini, parlons des fichiers .class, des packages et des fichiers .jar.

Supposons d'abord que MyClass soit quelque chose que vous avez construit dans le cadre de votre projet, et qu'il se trouve dans un répertoire de votre projet appelé output. Le fichier .class serait à output/org/javaguy/coolframework/MyClass.class(avec tous les autres fichiers de ce package). Pour accéder à ce fichier, votre chemin devrait simplement contenir le dossier «sortie», et non la structure complète du package, car votre instruction d'importation fournit toutes ces informations à la machine virtuelle.

Supposons maintenant que vous regroupiez CoolFramework dans un fichier .jar et placez ce CoolFramework.jar dans un répertoire lib de votre projet. Vous devez maintenant mettre lib/CoolFramework.jardans votre chemin de classe. La machine virtuelle recherchera la org/javaguy/coolframeworkpièce dans le fichier jar et trouvera votre classe.

Ainsi, les chemins de classe contiennent:

  • Les fichiers JAR et
  • Chemins vers le haut des hiérarchies de packages.

Comment définissez-vous votre chemin de classe?

La première façon que tout le monde semble apprendre est avec les variables d'environnement. Sur une machine Unix, vous pouvez dire quelque chose comme:

export CLASSPATH=/home/myaccount/myproject/lib/CoolFramework.jar:/home/myaccount/myproject/output/

Sur une machine Windows, vous devez accéder aux paramètres de votre environnement et ajouter ou modifier la valeur déjà présente.

La deuxième façon consiste à utiliser le -cpparamètre lors du démarrage de Java, comme ceci:

java -cp "/home/myaccount/myproject/lib/CoolFramework.jar:/home/myaccount/myproject/output/"  MyMainClass

Une variante de ceci est la troisième méthode qui est souvent effectuée avec un fichier .shou .batqui calcule le chemin de classe et le transmet à Java via le -cpparamètre.

Il y a un "gotcha" avec tout ce qui précède. Sur la plupart des systèmes (Linux, Mac OS, UNIX, etc.), le caractère deux-points (':') est le séparateur de chemin de classe. Dans windowsm, le séparateur est le point-virgule (';')

Alors, quelle est la meilleure façon de procéder?

Définir des éléments globalement via des variables d'environnement est mauvais, généralement pour les mêmes raisons que les variables globales sont mauvaises. Vous modifiez la variable d'environnement CLASSPATH pour qu'un programme fonctionne et vous finissez par interrompre un autre programme.

Le -cp est le chemin à parcourir. Je m'assure généralement que ma variable d'environnement CLASSPATH est une chaîne vide où je développe, dans la mesure du possible, afin d'éviter les problèmes de chemin de classe global (certains outils ne sont pas satisfaits quand le chemin de classe global est vide - je connais deux méga-milliers communs serveurs J2EE et Java sous licence dollar qui rencontrent ce type de problème avec leurs outils de ligne de commande).



En python, il y a un dossier appelé Lib où vous pouvez stocker n'importe quel module à utiliser à tout moment avec une simple déclaration d'importation. Est-ce différent de la définition de la variable d'environnement CLASSPATH dans un répertoire pour les packages java tiers? Même si elle serait globale, il ne serait pas nécessaire de modifier la variable, à part ajouter plus de packages.
Josie Thompson

Bonne réponse, mais pour les nuls ici: pourquoi n'avez-vous pas besoin d'utiliser la commande -cp pour chaque nouvelle classe que vous créez? Cela est sûrement résolu automatiquement par votre système, n'est-ce pas? Mais comment? Je rencontre parfois un problème où "quelque chose" ne peut pas être trouvé dans mon chemin de classe - je suppose que c'est parce que je ne l'ai pas ajouté au cp, mais pourquoi une telle erreur ne se produit-elle que parfois au lieu de toujours? Je pose cette question parce que, pour être honnête, je n'ai jamais rien inclus manuellement avec la commande -cp et je ne saurais pas quoi faire avec une erreur comme ça
Vic Torious

2
@Vic Le chemin de classe doit contenir le répertoire au-dessus de la hiérarchie de répertoires correspondant au nom du package. Donc, si j'ai org.javaguy.coolfw, avec la structure de répertoires correspondante /path/to/org/javaguy/coolfw/, le chemin de classe devrait contenir /path/to/. Si j'ajoute un nouveau package org.javaguy.hotfwdans le même projet, la classe résultante se termine (généralement) à /path/to/org/javaguy/hotfw/. Cela nécessite que le chemin de classe contienne /path/to/, ce qu'il fait déjà. Ainsi, le nouveau package (et les classes qu'il contient) ne nécessite pas de nouveaux ajouts au chemin de classe.
tjalling

@Vic Pour un exemple et une explication plus concrets, voir Maîtriser le CLASSPATH Java (selon l'excellent commentaire de KNU )
tjalling

67

Considérez-le comme la réponse de Java à la variable d'environnement PATH - les OS recherchent les EXE sur le PATH, Java recherche les classes et les packages sur le chemin de classe.


13

Le chemin de classe est le chemin où la machine virtuelle Java recherche les classes, packages et ressources définis par l'utilisateur dans les programmes Java.

Dans ce contexte, la format()méthode charge un fichier modèle à partir de ce chemin.


5

Le chemin de classe dans ce contexte est exactement ce qu'il est dans le contexte général: partout où la machine virtuelle sait qu'elle peut trouver des classes à charger, ainsi que des ressources (comme output.vm dans votre cas).

Je comprends que Velocity s'attend à trouver un fichier nommé output.vm n'importe où dans "aucun package". Il peut s'agir d'un fichier JAR, d'un dossier standard, ... La racine de l'un des emplacements du chemin de classe de l'application.


2

Définition de la variable système CLASSPATH

Pour afficher la variable CLASSPATH actuelle, utilisez ces commandes sous Windows et UNIX (shell Bourne): Sous Windows: C:\> set CLASSPATH Sous UNIX: % echo $CLASSPATH

Pour supprimer le contenu actuel de la variable CLASSPATH, utilisez ces commandes: Sous Windows: C:\> set CLASSPATH= Sous UNIX: % unset CLASSPATH; export CLASSPATH

Pour définir la variable CLASSPATH, utilisez ces commandes (par exemple): Sous Windows: C:\> set CLASSPATH=C:\users\george\java\classes Sous UNIX: % CLASSPATH=/home/george/java/classes; export CLASSPATH


1
Bien que ces commandes puissent être utiles pour travailler avec des variables d'environnement, cela ne répond pas à la question
Hulk

1

Classpath est une variable d'environnement du système. Le paramètre de cette variable est utilisé pour fournir la racine de toute hiérarchie de packages au compilateur java.


1

CLASSPATH est une variable d'environnement (c'est-à-dire, des variables globales du système d'exploitation disponibles pour tous les processus) nécessaires au compilateur Java et au runtime pour localiser les packages Java utilisés dans un programme Java. (Pourquoi ne pas appeler PACKAGEPATH?) Ceci est similaire à une autre variable d'environnement PATH, qui est utilisée par le shell CMD pour trouver les programmes exécutables.

CLASSPATH peut être défini de l'une des manières suivantes:

CLASSPATH can be set permanently in the environment: In Windows, choose control panel  System  Advanced  Environment Variables  choose "System Variables" (for all the users) or "User Variables" (only the currently login user)  choose "Edit" (if CLASSPATH already exists) or "New"  Enter "CLASSPATH" as the variable name  Enter the required directories and JAR files (separated by semicolons) as the value (e.g., ".;c:\javaproject\classes;d:\tomcat\lib\servlet-api.jar"). Take note that you need to include the current working directory (denoted by '.') in the CLASSPATH.

To check the current setting of the CLASSPATH, issue the following command:

> SET CLASSPATH

CLASSPATH can be set temporarily for that particular CMD shell session by issuing the following command:

> SET CLASSPATH=.;c:\javaproject\classes;d:\tomcat\lib\servlet-api.jar

Instead of using the CLASSPATH environment variable, you can also use the command-line option -classpath or -cp of the javac and java commands, for example,

> java classpath c:\javaproject\classes com.abc.project1.subproject2.MyClass3

0

Un membre statique d'une classe peut être appelé directement sans créer d'instance d'objet. Puisque la méthode principale est statique, la machine virtuelle Java peut l'appeler sans créer d'instance d'une classe qui contient la méthode principale, qui est le point de départ du programme.


0

Pour les utilisateurs de Linux, et pour résumer et ajouter à ce que les autres ont dit ici, vous devez savoir ce qui suit:

  1. $ CLASSPATH est ce que Java utilise pour parcourir plusieurs répertoires pour trouver toutes les différentes classes dont il a besoin pour votre script (à moins que vous ne le disiez explicitement autrement avec la substitution -cp). L'utilisation de -cp nécessite que vous gardiez une trace de tous les répertoires manuellement et que vous copiez-colliez cette ligne chaque fois que vous exécutez le programme (pas préférable IMO).

  2. Le caractère deux-points (":") sépare les différents répertoires. Il n'y a qu'un seul $ CLASSPATH et il contient tous les répertoires. Ainsi, lorsque vous exécutez "export CLASSPATH = ....", vous souhaitez inclure la valeur actuelle "$ CLASSPATH" afin de l'ajouter. Par exemple:

    export CLASSPATH=.
    export CLASSPATH=$CLASSPATH:/usr/share/java/mysql-connector-java-5.1.12.jar

    Dans la première ligne ci-dessus, vous démarrez CLASSPATH avec juste un simple «point» qui est le chemin vers votre répertoire de travail actuel. Avec cela, chaque fois que vous exécutez java, il recherchera dans le répertoire de travail actuel (celui dans lequel vous vous trouvez) des classes. Dans la deuxième ligne ci-dessus, $ CLASSPATH récupère la valeur que vous avez entrée précédemment (.) Et ajoute le chemin d'accès à un répertoire mysql. Maintenant, java recherchera le pilote ET vos classes.

  3. echo $CLASSPATH

    est super pratique, et ce qu'il retourne devrait se lire comme une liste séparée par deux-points de tous les répertoires et fichiers .jar, vous voulez que java recherche les classes dont il a besoin.

  4. Tomcat n'utilise pas CLASSPATH. Lisez ce qu'il faut faire à ce sujet ici: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.