Execute um arquivo JAR a partir da linha de comando e especifique o classpath

115

Compilei um arquivo JAR e especifiquei a classe principal no manifesto (usei a função Exportar Eclipse ). Minhas dependências estão todas em um diretório rotulado lib. Não consigo obter uma resposta direta sobre como executar meu arquivo JAR enquanto especifico que ele deve usar o lib/*como o caminho de classe.

Eu tentei:

]$ java -jar -cp .:lib/* MyJar.jar
]$ java -cp .:lib/* -jar MyJar.jar
]$ java -cp .:lib/* com.somepackage.subpackage.Main

etc ...

Cada um dá um erro dizendo:

Error: Could not find or load main class ....

ou dá a NoClassDefFoundErrorindicação de que as bibliotecas não estão sendo encontradas.

Eu até tentei refazer o arquivo JAR e incluí o libdiretório e o conteúdo, mas ainda sem dados ...

Como posso executar um arquivo JAR na linha de comando e especificar o caminho de classe a ser usado?

SnakeDoc
fonte

Respostas:

204

Ao especificar -jar, o -cpparâmetro será ignorado.

Da documentação :

Quando você usa esta opção, o arquivo JAR é a origem de todas as classes de usuário e outras configurações de caminho de classe de usuário são ignoradas.

Você também não pode "incluir" os arquivos jar necessários em outro arquivo jar (você precisaria extrair seu conteúdo e colocar os arquivos .class em seu arquivo jar)

Você tem duas opções:

  1. incluir todos os arquivos jar do libdiretório no manifesto (você pode usar caminhos relativos lá)
  2. Especifique tudo ( incluindo seu jar) na linha de comando usando -cp:
    java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main
um cavalo sem nome
fonte
22
; em vez de: se você usar o Windows da seguinte forma java -cp MyJar.jar; lib / * com.somepackage.subpackage.Main
Erro de
Você também não pode "incluir" arquivos jar necessários em outro arquivo jar. Certamente você pode. Se for para uso interno (ou seja, você espera que o usuário tenha alguma habilidade técnica etc.), você pode simplesmente pedir que a etapa 1, antes de tentar executar o jar, seja executar unzip MyJar.jar lib/*.jar. Então, como você sugere, eles podem executarjava -cp MyJar.jar:lib/* ...
Roger
3
o que é chato é que é um caso de uso comum executar um uber jar "completo" com uma referência a um arquivo de propriedades específicas do servidor externo. Obviamente não é um bloqueador, mas certamente um comando menos prolixo se você pudesse usar o -jar e não precisar especificar o principal
Andrew Norman
Levei um tempo para descobrir. E leva cerca de 6 linhas para carregar um arquivo log4j explicitamente. Outro bug do Java que nunca será corrigido.
Tuntable
1
Observe que o Class-Path manifesst só pode ser usado para carregar arquivos jar. Não pode ser usado para pesquisar log4j3.xml, por exemplo. Você me pegou.
Tuntable
34

Execute um arquivo jar e especifique um caminho de classe como este:

java -cp <jar_name.jar:libs/*> com.test.App

jar_name.jar é o nome completo do JAR que você deseja executar

libs/* é um caminho para seus JARs de dependência

com.test.Appé o nome totalmente qualificado da classe do JAR que possui o main(String[])método

O jar e o jar dependente devem ter permissões de execução.

Sid
fonte
10

Você pode fazer isso no shell do Unix:

java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main

Você pode fazer isso no Windows PowerShell:

java -cp "MyJar.jar;lib\*" com.somepackage.subpackage.Main
alcatrões
fonte
4

Alternativamente, use o manifesto para especificar o caminho da classe e a classe principal, se desejar, então você não precisa usar -cpou especificar a classe principal. No seu caso, conteria linhas como esta:

Main-Class: com.test.App
Class-Path: lib/one.jar lib/two.jar

Infelizmente, você precisa soletrar cada jar no manifesto (não é nada demais, já que você faz apenas uma vez, e você pode usar um script para construir o arquivo ou usar uma ferramenta de construção como ANT ou Maven ou Gradle). E a referência deve ser um diretório relativo ou absoluto para onde você executa o java -jar MyJar.jar.

Em seguida, execute-o com

java -jar MyJar.jar
HankCa
fonte
Acho que o Class-Path precisa se referir a arquivos dentro do jar externo. Não consegui fazer isso funcionar em geral, para referir-se aos arquivos de configuração fora do MyJar.jar.
Tuntable
0

Você pode executar um Runtime.getRuntime.exec (comando) para reiniciar o jar incluindo classpath com args.

Tim de Vries
fonte