Diferenças entre “java -cp” e “java -jar”?

118

Qual é a diferença entre executar um aplicativo Java com
java -cp CLASSPATHe java -jar JAR_FILE_PATH? É preferível um deles ao outro para executar um aplicativo Java? Quero dizer, qual dessas formas é mais cara para JVM (de acordo com o uso de recursos de sua máquina)?

Qual deles fará com que a JVM gere mais threads ao tentar executar o aplicativo?

Reza
fonte

Respostas:

97

Eu prefiro a primeira versão para iniciar um aplicativo java apenas porque tem menos armadilhas ("bem-vindo ao inferno do classpath"). O segundo requer um arquivo jar executável e o classpath para esse aplicativo deve ser definido dentro do manifesto do jar (todas as outras declarações de classpath serão silenciosamente ignoradas ...). Assim, com a segunda versão, você teria que olhar para o jar, ler o manifesto e tentar descobrir se as entradas do classpath são válidas de onde o jar está armazenado ... Isso é evitável.

Não espero nenhuma vantagem ou desvantagem de desempenho para nenhuma das versões. É apenas dizer ao jvm qual classe usar para o thread principal e onde pode encontrar as bibliotecas.

Andreas Dolk
fonte
E os tópicos? Eles são iguais em termos de número de encadeamentos que a JVM gera ao tentar executar o aplicativo?
Reza
1
Sim. Ambas as versões irão localizar o método principal e executá-lo com uma única thread. A primeira versão passa o nome da classe como um argumento, com a segunda versão, o jvm vai encontrá-lo dentro do mainfest.
Andreas Dolk
@Andreas_D Por favor, dê uma olhada neste post , acho que estou usando -cp de forma errada, e não sei como corrigir meu erro.
fu DL
60

Com o -cpargumento, você fornece o caminho de classe, ou seja, caminho (s) para classes ou bibliotecas adicionais que seu programa pode exigir ao ser compilado ou executado. Com -jarvocê especifica o arquivo JAR executável que deseja executar.

Você não pode especificar os dois. Se você tentar correr java -cp folder/myexternallibrary.jar -jar myprogram.jar, não funcionará de verdade. O caminho de classe para esse JAR deve ser especificado em seu Manifesto, não como um -cpargumento.

Você pode encontrar mais sobre isso aqui e aqui .

PS: -cpe -classpathsão sinônimos.

Radu Murzea
fonte
Minha preocupação é com os recursos? existe uma diferença entre os recursos que eles usam?
Reza
@Hesam Se você está perguntando sobre as diferenças de desempenho entre -cpe -classpath, então não, não há diferença.
Radu Murzea
1
Não! Eu quis dizer a diferença de desempenho entre -cp (ou -classpath) e -jar
Reza
2
@Hesam Com -jarvocê especifica qual JAR executável deseja executar. Com -cpvocê especifica o (s) caminho (s) para classes / bibliotecas adicionais que seu programa pode exigir. Os 2 têm finalidades muito diferentes.
Radu Murzea
@RaduMurzea, O que quer dizer que não iria realmente trabalhar quando combiná-los? Por exemplojava -jar PATH -cp PATH2
Pacerier
18

Ao usar, java -cpé necessário fornecer um nome de classe principal totalmente qualificado, por exemplo

java -cp com.mycompany.MyMain

Ao usar java -jar myjar.jarseu arquivo jar deve fornecer as informações sobre a classe principal via manifest.mf contido no arquivo jar na pasta META-INF:

Main-Class: com.mycompany.MyMain

AlexR
fonte
Por favor, dê uma olhada neste post , acho que estou usando -cp de forma errada, e não sei como corrigir meu erro.
fu DL
10

java -cp CLASSPATH é necessário se você deseja especificar todo o código no classpath. Isso é útil para depurar código.

O formato executável jarred: java -jar JarFilepode ser usado se você deseja iniciar o aplicativo com um único comando curto. Você pode especificar arquivos jar dependentes adicionais em seu MANIFESTO usando jars separados por espaço em uma entrada Class-Path, por exemplo:

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

Ambos são comparáveis ​​em termos de desempenho.

Reimeus
fonte
Por favor, dê uma olhada neste post , acho que estou usando -cp de forma errada, e não sei como corrigir meu erro.
fu DL
2

Como já foi dito, o -cp serve apenas para dizer ao jvm na linha de comando qual classe usar para o thread principal e onde ele pode encontrar as bibliotecas (definir classpath). Em -jar, ele espera que o caminho da classe e a classe principal sejam definidos no manifesto do arquivo jar. Portanto, outro é para definir coisas na linha de comando, enquanto outro é encontrá-los dentro do manifesto jar. Não há diferença no desempenho. Você não pode usá-los ao mesmo tempo, -jar substituirá o -cp.

Embora mesmo se você usar -cp, ele ainda verificará o arquivo de manifesto. Portanto, você pode definir alguns dos caminhos de classe no manifesto e alguns na linha de comando. Isso é particularmente útil quando você tem uma dependência de algum jar de terceiros, que você pode não fornecer com sua compilação ou não deseja fornecer (esperando que já seja encontrado no sistema onde será instalado, por exemplo). Portanto, você pode usá-lo para fornecer jars externos. Sua localização pode variar entre os sistemas ou pode até ter uma versão diferente em um sistema diferente (mas com as mesmas interfaces). Desta forma, você pode construir o aplicativo com outra versão e adicionar a dependência real de terceiros ao caminho de classe na linha de comando ao executá-lo em sistemas diferentes.

Pehmolelu
fonte
1

Não haverá diferença em termos de desempenho. Usando java - cp, podemos especificar as classes necessárias e jar's no classpath para executar um arquivo de classe java.

Se for um arquivo jar executável. Quando o comando java -jar é usado, o jvm encontra a classe necessária para executar a partir do arquivo /META-INF/MANIFEST.MF dentro do arquivo jar.

Ravi Sankar Reddy
fonte