¿Diferencias entre “java -cp” y “java -jar”?

118

¿Cuál es la diferencia entre ejecutar una aplicación Java con
java -cp CLASSPATHy java -jar JAR_FILE_PATH? ¿Se prefiere uno al otro para ejecutar una aplicación Java? Quiero decir, ¿cuál de estas formas es más cara para JVM (según el uso de recursos de su máquina)?

¿Cuál hará que JVM genere más subprocesos al intentar ejecutar la aplicación?

Reza
fuente

Respuestas:

97

Prefiero la primera versión para iniciar una aplicación Java solo porque tiene menos trampas ("bienvenido al infierno de classpath"). El segundo requiere un archivo jar ejecutable y la ruta de clase para esa aplicación debe definirse dentro del manifiesto del jar (todas las demás declaraciones de ruta de clase se ignorarán silenciosamente ...). Entonces, con la segunda versión, tendrías que mirar dentro del jar, leer el manifiesto e intentar averiguar si las entradas de classpath son válidas desde donde se almacena el jar ... Eso es evitable.

No espero ventajas o desventajas de rendimiento para ninguna de las versiones. Solo le dice a jvm qué clase usar para el hilo principal y dónde puede encontrar las bibliotecas.

Andreas Dolk
fuente
¿Qué pasa con los hilos? ¿Son iguales en términos de número de subprocesos que genera la JVM al intentar ejecutar la aplicación?
Reza
1
Si. Ambas versiones ubicarán el método principal y lo ejecutarán con un solo hilo. La primera versión pasa el nombre de la clase como argumento, con la segunda versión, el jvm lo encontrará dentro del mainfest.
Andreas Dolk
@Andreas_D Por favor, echa un vistazo a esta publicación , supongo que estoy usando -cp de manera incorrecta y no sé cómo corregir mi error.
fu DL
60

Con el -cpargumento, usted proporciona la ruta de clases, es decir, la (s) ruta (s) a clases o bibliotecas adicionales que su programa puede requerir cuando se compila o ejecuta. Con -jarusted especifica el archivo JAR ejecutable que desea ejecutar.

No puede especificarlos a ambos. Si intentas ejecutarlo java -cp folder/myexternallibrary.jar -jar myprogram.jar, no funcionará realmente. La ruta de clase para ese JAR debe especificarse en su manifiesto, no como un -cpargumento.

Puede encontrar más sobre esto aquí y aquí .

PD: -cpy -classpathson sinónimos.

Radu Murzea
fuente
¿Mi preocupación son los recursos? ¿Existe alguna diferencia entre los recursos que utilizan?
Reza
@Hesam Si pregunta acerca de las diferencias de rendimiento entre -cpy -classpath, entonces no, no hay diferencia.
Radu Murzea
1
¡No! Me refiero a la diferencia de rendimiento entre -cp (o -classpath) y -jar
Reza
2
@Hesam Con -jarusted especifica qué JAR ejecutable desea ejecutar. Con -cpusted especifica la (s) ruta (s) a clases / biblioteca adicionales que su programa pueda requerir. Los 2 tienen propósitos muy diferentes.
Radu Murzea
@RaduMurzea, ¿Qué quieres decir con que realmente no funcionaría cuando los combinamos? Por ejemplojava -jar PATH -cp PATH2
Pacerier
18

Al usar java -cp, debe proporcionar un nombre de clase principal completamente calificado, por ejemplo

java -cp com.mycompany.MyMain

Al usar java -jar myjar.jarsu archivo jar debe proporcionar la información sobre la clase principal a través de manifest.mf contenida en el archivo jar en la carpeta META-INF:

Main-Class: com.mycompany.MyMain

AlexR
fuente
Por favor, echa un vistazo a esta publicación , supongo que estoy usando -cp de manera incorrecta y no sé cómo corregir mi error.
fu DL
10

java -cp CLASSPATH es necesario si desea especificar todo el código en la ruta de clases. Esto es útil para depurar código.

El formato ejecutable jarred: java -jar JarFilese puede usar si desea iniciar la aplicación con un solo comando corto. Puede especificar archivos jar dependientes adicionales en su MANIFEST usando jarras separadas por espacios en una entrada de Class-Path, por ejemplo:

Class-Path: mysql.jar infobus.jar acme/beans.jar

Ambos son comparables en términos de rendimiento.

Reimeo
fuente
Por favor, echa un vistazo a esta publicación , supongo que estoy usando -cp de manera incorrecta y no sé cómo corregir mi error.
fu DL
2

Como ya se dijo, el -cp es solo para decirle al jvm en la línea de comando qué clase usar para el hilo principal y dónde puede encontrar las bibliotecas (definir classpath). En -jar, espera que la ruta de clase y la clase principal se definan en el manifiesto del archivo jar. Entonces, otro es para definir cosas en la línea de comando mientras que otro las encuentra dentro del manifiesto jar. No hay diferencia en el rendimiento. No puede usarlos al mismo tiempo, -jar anulará el -cp.

Aunque incluso si usa -cp, aún verificará el archivo de manifiesto. Así que puede definir algunas de las rutas de clases en el manifiesto y otras en la línea de comandos. Esto es particularmente útil cuando tiene una dependencia en algún jar de terceros, que es posible que no proporcione con su compilación o no quiera proporcionar (esperando que ya se encuentre en el sistema donde se instalará, por ejemplo). Entonces puedes usarlo para proporcionar frascos externos. Su ubicación puede variar entre sistemas o incluso puede tener una versión diferente en un sistema diferente (pero con las mismas interfaces). De esta manera, puede crear la aplicación con otra versión y agregar la dependencia real de terceros a la ruta de clase en la línea de comandos cuando la ejecuta en diferentes sistemas.

Pehmolelu
fuente
1

No habrá ninguna diferencia en términos de rendimiento. Usando java - cp podemos especificar las clases requeridas y los jar en la ruta de clases para ejecutar un archivo de clase java.

Si es un archivo jar ejecutable. Cuando se usa el comando java -jar, jvm busca la clase que necesita para ejecutar desde el archivo /META-INF/MANIFEST.MF dentro del archivo jar.

ravi sankar reddy
fuente