¿Qué es un classpath y cómo lo configuro?

324

Estaba leyendo esta línea:

Lo primero que hace el método format () es cargar una plantilla Velocity desde el classpath llamado output.vm

Por favor, explique qué se entiende por classpath en este contexto y cómo debo configurar el classpath.

Blankman
fuente

Respuestas:

530

Al programar en Java, usted pone a disposición otras clases para la clase que está escribiendo colocando algo como esto en la parte superior de su archivo fuente:

import org.javaguy.coolframework.MyClass;

O a veces 'importas masivamente' cosas diciendo:

import org.javaguy.coolframework.*;

Entonces más adelante en tu programa cuando dices:

MyClass mine = new MyClass();

La máquina virtual Java sabrá dónde encontrar su clase compilada.

No sería práctico hacer que la VM revise todas las carpetas de su máquina, por lo que debe proporcionar a la VM una lista de lugares para buscar. Esto se hace colocando carpetas y archivos jar en tu classpath.

Antes de hablar sobre cómo se establece classpath, hablemos sobre archivos .class, paquetes y archivos .jar.

Primero, supongamos que MyClass es algo que creó como parte de su proyecto, y está en un directorio en su proyecto llamado output. El archivo .class estaría en output/org/javaguy/coolframework/MyClass.class(junto con cualquier otro archivo en ese paquete). Para llegar a ese archivo, su ruta simplemente necesitaría contener la carpeta 'salida', no toda la estructura del paquete, ya que su declaración de importación proporciona toda esa información a la VM.

Ahora supongamos que agrupa CoolFramework en un archivo .jar y coloca CoolFramework.jar en un directorio lib en su proyecto. Ahora deberías poner lib/CoolFramework.jaren tu classpath. La máquina virtual buscará la parte dentro del archivo jar y buscará org/javaguy/coolframeworksu clase.

Entonces, los classpaths contienen:

  • Archivos JAR y
  • Rutas hacia la parte superior de las jerarquías de paquetes.

¿Cómo configuras tu classpath?

La primera forma en que todos parecen aprender es con las variables de entorno. En una máquina Unix, puedes decir algo como:

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

En una máquina con Windows, debe ir a la configuración de su entorno y agregar o modificar el valor que ya está allí.

La segunda forma es usar el -cpparámetro al iniciar Java, de esta manera:

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

Una variante de esto es la tercera forma que a menudo se realiza con un archivo .sho .batque calcula el classpath y lo pasa a Java a través del -cpparámetro.

Hay un "gotcha" con todo lo anterior. En la mayoría de los sistemas (Linux, Mac OS, UNIX, etc.) el carácter de dos puntos (':') es el separador de classpath. En windowsm, el separador es el punto y coma (';')

Entonces, ¿cuál es la mejor manera de hacerlo?

Establecer cosas globalmente a través de variables de entorno es malo, generalmente por las mismas razones por las que las variables globales son malas. Cambia la variable de entorno CLASSPATH para que un programa funcione y termine rompiendo otro programa.

El -cp es el camino a seguir. Generalmente me aseguro de que mi variable de entorno CLASSPATH es una cadena vacía donde desarrollo, siempre que sea posible, para evitar problemas globales de classpath (aunque algunas herramientas no son felices cuando el classpath global está vacío; sé de dos mega miles comunes Servidores J2EE y Java con licencia en dólares que tienen este tipo de problema con sus herramientas de línea de comandos).

Bokmann
fuente
12
Otro blog bien explicado sobre What is PATH and CLASSPATH in Java - Path vs ClassPath
KNU
En python hay una carpeta llamada Lib donde puede almacenar cualquier módulo para usar en cualquier momento con una simple declaración de importación. ¿Es esto diferente de establecer la variable de entorno CLASSPATH en un directorio para paquetes java de terceros? Aunque sería global, no habría necesidad de cambiar la variable, aparte de agregar más paquetes.
Josie Thompson
Buena respuesta, pero para los tontos aquí: ¿Por qué no necesita usar el comando -cp para cada nueva clase que cree? Esto seguramente se resuelve automáticamente por su sistema ¿verdad? ¿Pero cómo? A veces encuentro un problema en el que "algo" no se puede encontrar en mi classpath. Supongo que es así porque no lo agregué al cp, pero ¿por qué ocurre ese error solo algunas veces en lugar de siempre? Pregunto esto porque, para ser honesto, nunca incluí nada manualmente con el comando -cp y no sabría qué hacer con un error como ese
Vic Torious
2
@Vic El classpath debe contener el directorio sobre la jerarquía de directorios correspondiente al nombre del paquete. Entonces, si tengo org.javaguy.coolfw, con la estructura de directorio correspondiente /path/to/org/javaguy/coolfw/, el classpath debería contener /path/to/. Si agrego un nuevo paquete org.javaguy.hotfwen el mismo proyecto, la clase resultante (generalmente) termina en /path/to/org/javaguy/hotfw/. Esto requiere que el classpath contenga /path/to/, lo que ya hace. Por lo tanto, el nuevo paquete (y las clases que contiene) no requieren nuevas adiciones al classpath.
tjalling
@Vic Para obtener un ejemplo y una explicación más concretos, consulte Dominar la CLASSPATH de Java (según el excelente comentario de KNU )
tjalling
67

Piense en ello como la respuesta de Java a la variable de entorno PATH: los sistemas operativos buscan EXE en PATH, Java busca clases y paquetes en classpath.

Stephen C
fuente
13

El classpath es el camino donde la máquina virtual Java busca clases, paquetes y recursos definidos por el usuario en los programas Java.

En este contexto, el format()método carga un archivo de plantilla desde esta ruta.

Desintegr
fuente
5

El classpath en este contexto es exactamente lo que es en el contexto general: en cualquier lugar donde la VM sepa que puede encontrar clases para cargar, y también recursos (como output.vm en su caso).

Entiendo que Velocity espera encontrar un archivo llamado output.vm en cualquier parte de "sin paquete". Puede ser un JAR, una carpeta normal, ... La raíz de cualquiera de las ubicaciones en el classpath de la aplicación.

Romain
fuente
2

Configuración de la variable del sistema CLASSPATH

Para mostrar la variable CLASSPATH actual, use estos comandos en Windows y UNIX (shell Bourne): En Windows: C:\> set CLASSPATH En UNIX: % echo $CLASSPATH

Para eliminar el contenido actual de la variable CLASSPATH, use estos comandos: En Windows: C:\> set CLASSPATH= en UNIX: % unset CLASSPATH; export CLASSPATH

Para establecer la variable CLASSPATH, use estos comandos (por ejemplo): en Windows: C:\> set CLASSPATH=C:\users\george\java\classes en UNIX: % CLASSPATH=/home/george/java/classes; export CLASSPATH

lft93ryt
fuente
1
Si bien estos comandos pueden ser útiles para trabajar con variables de entorno, esto no responde la pregunta
Hulk
1

Classpath es una variable de entorno del sistema. La configuración de esta variable se utiliza para proporcionar la raíz de cualquier jerarquía de paquetes al compilador de Java.

Bimalendu nath
fuente
1

CLASSPATH es una variable de entorno (es decir, variables globales del sistema operativo disponible para todos los procesos) necesaria para que el compilador y el tiempo de ejecución de Java ubiquen los paquetes Java utilizados en un programa Java. (¿Por qué no llamar a PACKAGEPATH?) Esto es similar a otra variable de entorno PATH, que es utilizada por el shell de CMD para encontrar los programas ejecutables.

CLASSPATH se puede configurar de una de las siguientes maneras:

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
Unnati Solanki
fuente
0

Se puede llamar directamente al miembro estático de una clase sin crear una instancia de objeto. Dado que el método principal es estático, Java Virtual Machine puede llamarlo sin crear ninguna instancia de una clase que contenga el método principal, que es el punto de inicio del programa.


fuente
0

Para los usuarios de Linux, y para resumir y agregar a lo que otros han dicho aquí, deben saber lo siguiente:

  1. $ CLASSPATH es lo que Java usa para buscar en varios directorios para encontrar todas las clases diferentes que necesita para su script (a menos que explícitamente le diga lo contrario con la anulación -cp). El uso de -cp requiere que realice un seguimiento de todos los directorios manualmente y copie y pegue esa línea cada vez que ejecute el programa (no es preferible la OMI).

  2. El carácter de dos puntos (":") separa los diferentes directorios. Solo hay un $ CLASSPATH y tiene todos los directorios. Entonces, cuando ejecuta "export CLASSPATH = ....", desea incluir el valor actual "$ CLASSPATH" para agregarlo. Por ejemplo:

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

    En la primera línea de arriba, comienzas CLASSPATH con solo un simple 'punto' que es la ruta a tu directorio de trabajo actual. Con eso, cada vez que ejecutes Java, buscará clases en el directorio de trabajo actual (en el que estás). En la segunda línea anterior, $ CLASSPATH toma el valor que ingresó previamente (.) Y agrega la ruta a un directorio mysql. Ahora, Java buscará el controlador Y para sus clases.

  3. echo $CLASSPATH

    es muy útil, y lo que devuelve debe leerse como una lista separada por dos puntos de todos los directorios y archivos .jar, desea que Java busque las clases que necesita.

  4. Tomcat no utiliza CLASSPATH. Lea qué hacer al respecto aquí: https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html

Adam Winter
fuente