Compilar e rodar via dos

19 respostas
vinihds

Boa tarde para todos…

Estou tentando rodar uma classe via dos, porem não consigo…podem me ajudar ?

Eu criei os .java na seguinte estrutura Projeto\com\foo

As classes:

package com.foo; 

public class MyClass {

	public MyClass(){}
	
	public void hi(){
		System.out.println("Ola Mundo");
	}
	
}
package com.foo; 

import com.foo.*;
import com.foo.MyClass;

public class Another {

	public void go(){
		MyClass m1 = new MyClass();
		com.foo.MyClass m2 = new com.foo.MyClass();
		m1.hi();
		m2.hi();
	}
	
	public static void main(String [] args){
		new Another().go();
	}
	
}

Usei os seguintes comandos para compilar:

javac -d classes com\foo\MyClass.java

javac -d classes com\foo\Another.java

E estou tentando rodar, ai entro na pasta: \Projeto\classes\com\foo e executo o seguinte comando:

java Another

Erro:

Exception in thread main java.lang.NoClassDefFoundError: Another (wrong name:

com/foo/Another)

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$000(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)

Could not find the main class: Another.  Program will exit.

Obrigado a todos !!!

19 Respostas

Eric_Yuzo

Entre na pasta “\Projeto\classes”, que é a raiz, e execute sua classe especificando o caminho completo.

java com.foo.Another
vinihds

Opa…funcionou !! Valeu !!!

Outra duvida.

Se a classe MyClass.class estivesse dentro de um jar (MyJar.jar) e o pacote fosse “goo”, como que eu rodaria a classe Another ?

package com.goo; 

public class MyClass {

	public MyClass(){}
	
	public void hi(){
		System.out.println("Ola Mundo");
	}
	
}

Seria ± assim: (dentro da pasta “\Projeto\classes”)

java -cp MyJar.jar com.foo.Another

?

Eric_Yuzo

[quote=vinihds]Seria ± assim: (dentro da pasta “\Projeto\classes”)

java -cp MyJar.jar com.foo.Another

Isso mesmo. Desta forma vai executar sua classe Another.

Agora se quiser executar diretamente seu jar, deve especificar o “Main-Class” no manifest e executar com o comando:

java -jar MyJar.jar
vinihds

Porem, toda vez q eu tendo rodar a classe Another (lembrando que a classe MyClass esta dentro do jar, ocorre esse erro:

Dentro da pasta classe

java -cp MyJar.jar com.foo.Another
Exception in thread "main" java.lang.NoClassDefFoundError: com/foo/Another
Caused by: java.lang.ClassNotFoundException: com.foo.Another
        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)
Could not find the main class: com.foo.Another.  Program will exit.
Eric_Yuzo

Deveria funcionar.

Dentro do jar deve haver os diretórios com os arquivos com/foo/Another.class e com/goo/MyClass.class, além do “META_INF”, que é gerado automaticamente.

Outro detalhe é que se o prompt está em “\Projeto\classes”, “MyJar.jar” também deve estar, caso contrário tem que passar o caminho do jar para o comando.

Eric_Yuzo

Para ter certeza que eu não estava falando besteira, resolvi testar o procedimento. Segue os passos que fiz:

Copiei as classes que você postou (já em pacotes separados):
package com.goo; 

public class MyClass {

	public MyClass(){}
	
	public void hi(){
		System.out.println("Ola Mundo");
	}
	
}
package com.foo; 

import com.goo.MyClass;

public class Another {

	public void go(){
		MyClass m1 = new MyClass();
		com.goo.MyClass m2 = new com.goo.MyClass();
		m1.hi();
		m2.hi();
	}
	
	public static void main(String [] args){
		new Another().go();
	}
	
}
Compilei e rodei:
javac -d classes com\goo\MyClass.java
javac -d classes com\foo\Another.java

cd classes

java com.foo.Another
Despois criei o jar e executei usando o java -cp:
jar cvf MyJar.jar com\goo\MyClass.class com\foo\Another.class

java -cp MyJar.jar com.foo.Another
Bom, testei desta forma e imprimiu certinho as mensagens.
Eric_Yuzo

Se quiser que o jar fique “executável”, tem que especificar a classe principal no manifest. Eu crio um arquivo de texto comum especificando as variáveis que interessarem:

Main-Class: com.foo.Another Só configurei qual vai ser a classe main do jar e salvei como “manifest.txt”
PS.: Não se pode esquecer teclar enter no fim da linha para que o comando jar encontre o “return” e considere a linha.

Para criar o jar, tem que adicionar o parâmetro “m” e passar o caminho do arquivo manifest (neste caso, salvei no diretório classes mesmo):

jar cvmf manifest.txt MyExecutableJar.jar com\goo\MyClass.class com\foo\Another.classE para executar:

java -jar MyExecutableJar.jar
vinihds

Se a classe MyClass estivesse dentro do jar e a classe Another não. É possivel rodar a classe Another desse modo ?

valeu pela ajuda!!!

Eric_Yuzo

Quando se executa o comando “java -cp …”, especificamos os diretórios ou pacotes (jar, zip) onde as classes devem ser procuradas.

java tooldocs:
-cp classpath
Specify a list of directories, JAR archives, and ZIP archives to search for class files. Class path entries are separated by semicolons ( ; ). Specifying -classpath or -cp overrides any setting of the CLASSPATH environment variable.

If -classpath and -cp are not used and CLASSPATH is not set, the user class path consists of the current directory (.).


Você pode especificar pelo parâmetro cp, o jar onde está MyClass.class e o outro onde está Another.class

java -cp MyJar.jar:AnotherJar.jar com.foo.AnotherSe quiser, pode especificar um diretório:

java -cp MyJar.jar:/caminhoDaClasse com.foo.AnotherO ponto representa o diretório atual onde está o prompt:

java -cp MyJar.jar:. com.foo.Another

PS.:Acho que no Windows terá que separar os pacotes com ponto e vírgula ao invés de dois pontos:

java -cp MyJar.jar;AnotherJar.jar com.foo.Another

Para verificar a função dos parâmetros, procure ler a documentação: http://download.oracle.com/javase/1.4.2/docs/tooldocs/windows/java.html

vinihds

Entao Eric, eu to lendo a documentação, porem eu estou com duvida de como se faz para rodar uma classe quando ela depende de um jar.

Valeu

Eric_Yuzo

Qual dúvida?

Tentou executar os exemplos que postei acima?

vinihds

Eu consegui executar sim os exemplos que você postou.

Eu estou com dúvida em dois exercícios que tem no livro da Katie Sierra (os dois últimos do capitulo 10)…vc tem o livro ?

Eric_Yuzo

Eu tenho o Head First, mas não me lembro de ter exercícios assim. Pelo jeito é o de Certificação né? Esse eu nunca li.

Nos exemplos que postei estava executando a classe Another, que depende do jar onde está a classe MyClass. Não seria isso?

vinihds

Isso mesmo, é para certificação.

O exercício é esse:

Data a estrutura do diretório a seguir:

teste -|
         | - GetJar.java
         |
         | - myApp - |
                           | - Foo.java

E dados os conteúdos de GetJar e Foo:

public class GetJar{
  public void static void main(String [] args){
    System.out.println(myApp.Foo.d);
    }
  }
}
package myApp;
public class Foo{public static int d = 8;}

Se o diretório atual é “teste” e myApp/Foo.class está localizado em um arquivo JAR chamado MyJar.jar localizado em “teste”, qual dos comandos abaixo ira compilar GetJar.java e exibir ?

A) javac -classpath MyJar.jar GetJar.java
java GetJar

B) javac MyJar.jar GetJar.java
java GetJar

C) javac -classpath MyJar.jar GetJar.java
java -classpath MyJar.jar GetJar

D) javac MyJar GetJar.java
java -classpath MyJar.jar GetJar

o que voce achar ?

Eric_Yuzo
Eu diria que nenhuma das combinações compilaria E rodaria corretamente.
A)
javac -classpath MyJar.jar GetJar.java // Compila corretamente, pois está sendo especificado o jar onde está a classe "myApp/Foo.class"
java GetJar // Executa a classe GetJar, mas não foi especificado o jar que contém "myApp.Foo". Deve lançar um ClassNoDefFound ou algo assim.

B)
javac MyJar.jar GetJar.java // Erro de sintaxe
java GetJar // Mesma coisa que o A

C)
javac -classpath MyJar.jar GetJar.java // Compila
java -classpath MyJar.jar GetJar // Não foi especificado o caminho de GetJar.class

D)
javac MyJar GetJar.java // Erro de sintaxe
java -classpath MyJar.jar GetJar // Mesmo que o C
Acho que para executar deveria ser:
javac -classpath MyJar.jar GetJar.java
java -classpath MyJar.jar:. GetJar
Ou se for Windows:
javac -classpath MyJar.jar GetJar.java
java -classpath MyJar.jar;. GetJar
Bom, acho que é isso. No livro não tem a resposta pra ver se bate? Já tentou executar as combinações de comandos pra ver na prática o que ocorre?
vinihds

Agora entra a minha dúvida. A resposta que o livro mostra é a resposta A.

Entendeu o problema ?!

Valeu

Eric_Yuzo

Hmm. Sinceramente não sei. A minha opinião é a que postei no comentário. Deve ter algo a mais que não estamos enxergando.

Acho que para executar com “java GetJar”, além de GetJar.class, myApp/Foo.class também deveria estar no diretório teste. Mas aí não teria a dependência do MyJar.

Enfim, chegou a executar pra ver se funciona mesmo?

vinihds

Acho que voce tem razao quando falou “além de GetJar.class, myApp/Foo.class também deveria estar no diretório teste”.

OBrigado pela ajuda.

Eric_Yuzo

Por nada.

Mas se for isso mesmo, acho que a pergunta está meio que mal formulada, pois assim, não há dependência de “MyJar.jar”. Não teria porque ficar referenciando-o na hora de compilar GetJar.

Criado 25 de dezembro de 2010
Ultima resposta 29 de dez. de 2010
Respostas 19
Participantes 2