Como faço uma aula numa guerra a partir da linha de comando?
eu tenho uma classe Java que tem uma main e eu costumava correr como um aplicativo autônomo a partir da linha de comandos, por exemplo
java -jar myjar.jar params
eu precisava de reembalar o código para correr com o apache e todo o meu código, incluindo a classe do ponto de entrada do antigo jar, acabou num ficheiro de guerra para fácil deplyment no servidor web.
No entanto, eu ainda quero ser capaz de executá-lo a partir da linha de comando e o código não mudou e está tudo lá dentro, eu só não consigo descobrir como levá-lo para executar. Eis o que eu tentei... Presumi que a guerra era como um frasco, por isso ...java -jar mywar.war params
Que falhou em dizer que não havia nenhuma classe principal definida no manifesto.
Adicionei manualmente um manifesto à guerra e tentei de novo, com o mesmo efeito.
Reparei que na minha guerra tinha uma pasta chamada META-INF que continha um manifesto.mf, então eu adicionei uma linha a isso declarando minha classe principal como eu faria a um manifesto normal...
Manifest-Version: 1.0
Main-Class: mypackage.MyEntryPointClass
Isto deu a noClassDefFoundError mypackage.MyEntryPointClass
, que é algum progresso. Isso me levou a acreditar que era apenas uma questão de caminho, então eu tentei [[8]}
Manifest-Version: 1.0
Main-Class: WEB-INF.classes.mypackage.MyEntryPointClass
Agora tenho o mesmo erro, mas com uma pilha de vestígios...
Exception in thread "main" java.lang.NoClassDefFoundError: WEB-INF/classes/mypackage/MyEntryPointClass (wrong name: mypackage/MyEntryPointClass)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
Pesquisei um pouco no Google, mas não encontro nada que responda à minha pergunta, e li algumas outras perguntas que são ligeiramente diferentes, então pensei em postar.
Java 1.5, Não que eu ache que isso faça alguma diferença.
9 answers
Podes fazer o queHudson (projecto de integração contínua) faz. você descarrega uma guerra que pode ser implantada no tomcat ou para executar usando
java -jar hudson.war
(porque tem um motor de jacto embutido, executando - o a partir da linha de comando faz com que um servidor seja lançado. De qualquer forma, olhando para o manifesto de hudson, Eu entendo que eles colocaram uma classe principal na raiz do arquivo. No seu caso, o seu esquema de guerra deve ser parecido com:
Em raiz:
- mypackage / MyEntryPointClass.Classe
- WEB-INF / lib
- WEB-INF / classes
- META-INF/MANIFESTO.MF
Enquanto o manifesto deve incluir a seguinte linha:
Main-Class: mypackage.MyEntryPointClass
Por favor, note que o mypackage/MyEntryPointClass.a classe é acessível apenas a partir da linha de comando, e as classes sob WEB-INF/classes são acessáveis apenas a partir do servidor de Aplicação.
HTH
Semelhante ao que Richard Detsch, mas com um pouco mais fácil de seguir (também funciona com pacotes) {[[5]} Passo 1: desembrulhar o ficheiro de guerra.
jar -xvf MyWar.war
Passo 2: Mover para a pasta
cd WEB-INF
Passo 3: Execute o seu principal com todas as dependendecies
java -classpath "lib/*:classes/." my.packages.destination.FileToRun
WEB-INF/lib
. Então usa o frasco da linha de comando.
Assim, você obtém tanto a sua aplicação de console, e você pode usar as mesmas classes em seus servlets, sem fazer dois pacotes diferentes.
Isto, é claro, é verdade quando a guerra explode.
para executar um SomeClass.main (String [] args) de um ficheiro de guerra Enviado do:
Passo 1: escrever classe SomeClass.java that has a main method method i.e. (public static void main (String [] args) {...})
Passo 2:Passo 3: cd /usr/local/yourprojectsname/tomcat/webapps/projectName/WEB-INF
Passo 4: java-cp " lib / jar1.jar: lib / jar2.frasco: ... : lib / jarn.jar " com.mypackage.SomeClass arg1 arg2 ... arg3
Nota 1: (para ver se a classe alguma outra classe.a classe está em /usr / tomcat/webapps/projectName/WEB-INF/lib)
Executar -- > cd / usr/tomcat/webapps/projectName/WEB-INF/lib && encontrar . -nome '*.jar ' / while read jarfile; do if jar tf "$jarfile" | grep some Otherclass.class; then echo "$jarfile"; fi; done
Note2: escreva de acordo com o padrão para que você possa ver se o seu principal realmente funciona através de declarações de impressão para a consola. Isto chama-se uma porta das Traseiras.
Note3: o comentário acima de Bozhidar Bozhanov parece correcto
As regras para localizar classes num ficheiro de arquivo é que a localização da declaração de pacote do ficheiro e a localização do ficheiro dentro do arquivo têm de corresponder. Uma vez que sua classe está localizada em WEB-INF/classes, ele acha que a classe não é válida para correr no contexto atual.
A única forma de fazer o que está a pedir é reacondicionar a guerra para que o ficheiro .class
permaneça no directório mypackage
na raiz do arquivo, em vez do directório WEB-INF/classes. Entanto, se você fizer isso, você não será capaz de acessar o arquivo a partir de qualquer uma de suas classes web mais.
Se quiser reutilizar esta classe tanto na guerra como fora da linha de comandos java, considere a criação de um jar executável que possa executar a partir da linha de comandos, colocando então esse jar na pasta WEB-INF/lib do ficheiro war
.
No projecto Maven , poderá construir o jar automaticamente com 'plugin' de guerra Maven , definindo archiveClasses
Para true
. Exemplo abaixo.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archiveClasses>true</archiveClasses>
</configuration>
</plugin>
Se está a usar o Maven, basta seguir a documentação {[[1]} sobre " Como é que crio um frasco que contém as classes no meu webapp?": adicionar <attachClasses>true</attachClasses>
para o <configuration>
do plugin:
<project>
...
<artifactId>mywebapp</artifactId>
<version>1.0-SNAPSHOT</version>
...
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
Terá 2 produtos na pasta target/
:
- O
project.war
em si - o {[6] } que contém todas as classes compiladas num jar
Então você será capaz de executar uma classe principal usando o método clássico: java -cp target/project-classes.jar 'com.mycompany.MainClass' param1 param2
Bem, de acordo com Wikipedia, com um ficheiro de guerra, As classes que são carregadas no claspath estão no directório "/WEB-INF/classes" e "/WEB-INF/lib".
Você pode tentar simplesmente colocar uma cópia das classes no sistema de arquivos de raiz do arquivo zip (que é o que um war/jar é). Mas não sei se funcionaria.
Podes sempre criar dois ficheiros separados.
Para encontrar as classes java relacionadas, exporta-as (forma preferida de usar o ant) como o Jar o coloca no seu web app lib.
Então você pode usar o arquivo jar como normal para executar o programa java. O mesmo jar também foi referido na aplicação web (se você colocar este jar na web app lib)