Ajuda para criar e usar pacotes em JAR

Não consegui entender direito como usar os JAR para criar meus pacotes. Alguém pode me dar uma mãozinha?

Tenho o Pergunta.class no diretório: D:/java/packages/ricgrego/util

[code]package ricgrego.util;

import java.io.*;

public class Pergunta{
public static String comando(String question) {
String answer = new String();
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.print(question + " ");
try { answer = in.readLine(); }
catch(IOException e) {
System.out.println(“aconteceu uma IOException:/n”+e);
System.exit(1);
}
return answer;
}

public static String comando() {
	return comando("Enter text:");
}

public static class Tester {
	public static void main (String[] args) {
		System.out.println(Pergunta.comando("E aí?"));
		System.out.println("

");
System.out.println(Pergunta.comando());
}
}
}[/code]

A classe interna Tester é só para testar a classe Pergunta, e está funcionando.

Criei o JAR a partir de: D:/java/packages/ricgrego
com a seguinte linha de comando: jar cf0 util.jar util
Não criei o manifest file, mas entendi que não colocando parâmetro ‘m’ é criado um default.

Então tenho o seguinte resultado: D:/java/packages/ricgrego/util.jar
E inseri no ClassPath: D:/java/packages/ricgrego/util.jar

Criei a classe TestPergunta em D:/java/ex :

[code]import ricgrego.util

public class TestPergunta {
public static void main (String[] args) {
System.out.println(Pergunta.comando(“E aí?”));
System.out.println("
");
System.out.println(Pergunta.comando());
}
}[/code]

Mas ao tentar executá-la dá erro na linha do import.

Onde eu errei? Como que devo fazer para conseguir usar meus pacotes por import?

  1. Coloque a mensagem de erro, quando ha alguma. Isso ajuda MUITO.
  2. Voce fez
import ricgrego.util 

quando deveria ter feito

import ricgrego.util.*;

Rafael

hmmmm…

O TestPergunta.java que coloquei aqui estava desatualizado: eu já havia colocado o ‘;’ no import, mas não o ‘.*’.

Outra: eu estava usando o Eclipse, e ele gera o .class mesmo com erros de compilação, então resolvi fazer na mão mesmo, em linha de comando de DOS:

D:/java/packages/ricgrego/util> javac Pergunta.java
e
D:/java/packages/ricgrego> jar cf0 util.jar util
funcionaram sem erro

[code]package ricgrego.util;

import java.io.*;

public class Pergunta{

}[/code]

Mas ao tentar compilar o TestPergunta

[code]import ricgrego.util.*;

public class TestPergunta {
public static void main (String[] args) {
System.out.println(Pergunta.comando(“E aí?”));
System.out.println("
");
System.out.println(Pergunta.comando());
}
}[/code]

, tive os seguintes erros:

D:javaex>javac TestPergunta.java TestPergunta.java:9: package ricgrego.util does not exist import ricgrego.util.*; ^ TestPergunta.java:13: cannot resolve symbol symbol : variable Pergunta location: class TestPergunta System.out.println(Pergunta.comando("E aÝ?")); ^ TestPergunta.java:15: cannot resolve symbol symbol : variable Pergunta location: class TestPergunta System.out.println(Pergunta.comando()); ^ 3 errors

Porque ele não está reconhecendo o pacote?

Aqui está meu Path:
blablabla D:/java/packages/ricgrego/util.jar

Obs: ‘/’ está substituindo a barra invertida porque ela não está aparecendo no texto do fórum.

hmm… abra o teu .jar com o winzip e veja a estutura… se vc fez

a estrutura devera estar a partir do “util”, quando deveria estar na forma “ricrego/util”… ou seja, voce deveria ter feito

cd D:/java/packages
jar cf0 util.jar ricrego

Rafael

isso mesmo!

[quote=“Rafael Steil”]ou seja, voce deveria ter feito

cd D:/java/packages jar cf0 util.jar ricrego [/quote]
Mas daí iria inserir mais coisas do que gostaria.

Então eu fiz

cd D:/java/packages jar cf0 util.jar ricrego/util
e a estrutura ficou a partir de ricgrego/util.

Depois, movi o util.jar para dentro de D:/java/packages/ricgrego.

Mas mesmo assim não consigo compilar o TestPergunta a partir de D:/java/ex

D:javaex>javac TestPergunta.java TestPergunta.java:9: package ricgrego.util does not exist import ricgrego.util.*; ^ TestPergunta.java:13: cannot resolve symbol symbol : variable Pergunta location: class TestPergunta System.out.println(Pergunta.comando("E aÝ?")); ^ TestPergunta.java:15: cannot resolve symbol symbol : variable Pergunta location: class TestPergunta System.out.println(Pergunta.comando()); ^ 3 errors

isso mesmo!

[quote=“Rafael Steil”]ou seja, voce deveria ter feito

cd D:/java/packages jar cf0 util.jar ricrego [/quote]
Mas daí iria inserir mais coisas do que gostaria.
[/quote]

Voce nao tem escolha ;). A especificacao do Java para packages diz que tem que ser assim. Se voce nao quser algo, tire do jar depois.

Voce atualizou o jar no classpath depois? tente compilar com

javac -cp .;d:/path/do/teu.jar ProgramaDeTeste.java

Rafael

Mas qual a diferença de incluir todo o ricgrego e depois tirar o que não for do util, e fazer como fiz, colocando ricgrego/util. A estrutura de diretórios no jar não ficaria a mesma?

Eu editei minha msg depois, pois esqueci de falar que movi o util.jar para dentro de ricgrego.
Então fiquei com Path = blablabla ; D:javapackages
icgregoutil.jar
e com o util.jar exatamente nessa localização, dentro de ricgrego.

Talvez eu não tenha entendido o modo como deve ser a estrutura de diretórios. Estou fazendo assim:

  • Dentro de ricgrego quero colocar diretórios para ccada pacote: util, testes, grafico, etc
  • Dentro de cada um desses subdiretórios ficam as classes dos pacotes
  • Em paralelo a eles, ou seja, dentro de ricgrego, ficam os jar correspondentes: util.jar, testes.jar, etc

Isso está certo?

:frowning: tô todo confuso!

Assim:

Digamos que o teu pacote se chame “meu.pacote”. Todas as classes que voce quer que facam parte eo “meu.pacote” devem estar dentro do diretorio “pacote”, que por sua vez deve estar dentro do diretorio “meu”. Ou seja, se voce tem uma classe chamada “FazAlgumaCoisa.java”, ela deve estar localizada em

meu/pacote/FazAlgumaCoisa.java

a diretiva package dessa classe deve ser “meu.pacote”, como em

package meu.pacote.

public class FazAlgumaCoisa { ... }

Agora digamos que voce ainda tenha o pacote “meu.utilidades”. Seguindo a especificacao, o diretorio “utilidadades” estara dentro do diretorio “meu”, ou seja, no mesmo nivel do diretorio “pacote”. Tendo uma classe chamada “Calcula.java” em utilidades, ela deve se encontrar em

meu/utilidades/Calcula.java

sem esquecer a declaracao do package:

package meu.utilidades;

public class Calcula { ... }

Agora digamos que na tua classe “FazAlgumaCoisa” voce deseja usar os metodos da classe “Calcula”. Entao ficaria assiM;

// meu/pacote/FazAlgumaCoisa.java
package meu.pacote;

import meu.utilidades.Calcula;

public class FazAlgumaCoisa { ... }

Para jogar tudo isso em um jar, voce precisar ter a estrutura a partir do diretorio “meu”, ja que ele eh o inicio do pacote. Apos gerar o .jar, a estrutura do arquivo deve ser

meu/pacote/FazAlgumaCoisa.java
meu/utilidades/Calcula.java

Vamos chamar o .jar de “meuJar.jar”. Para usar ele, voce precisa colocar no classpath:

set CLASSPATH=.;%CLASSPATH%;c:/meuJar.jar

entao vc faz alguma outra classe e deseja usar a FazAlgumaCoisa. Ficaria assim:

import meu.pacote.FazAlgumaCoisa;

public class SeiLa { ... }

Moral? o Java vai se perder se vc comecar a querer “inventar” estruturas de diretorios ou simplesmente jogar JARs dentro de outros JARs. Se voce quiser criar milhares de jarzinhos, eh necessarios criar eles com a estrutura de diretorios correta ( completa ), com o path absoluto representando o package, ao inves de usar diretorios relatotivos apenas.

Rafael

[quote=“Rafael Steil”]Para jogar tudo isso em um jar, voce precisar ter a estrutura a partir do diretorio “meu”, ja que ele eh o inicio do pacote. Apos gerar o .jar, a estrutura do arquivo deve ser

meu/pacote/FazAlgumaCoisa.java meu/utilidades/Calcula.java [/quote]
Ok. Isso eu tenho:

  • Dentro de util.jar tenho estrutura ricgrego/util/Pergunta.class
  • O util.jar está dentro de D:/java/packages/ricgrego

[quote=“Rafael Steil”]Vamos chamar o .jar de “meuJar.jar”. Para usar ele, voce precisa colocar no classpath:

set CLASSPATH=.;%CLASSPATH%;c:/meuJar.jar

opa! É isso mesmo? No meu Path tenho:

D:/java/packages/ricgrego/util.jar

Cabe aqui um parênteses. Quando eu falo Path, é mesmo a variável Path do W2k, a mesma que tem: %SystemRoot%system32;%SystemRoot%; etc

De qualquer forma, já que a estrutura do meu util.jar começa em ricgrego, mudei no Path o caminho para
D:/java/packages/util.jar

Se entendi direito, o caminho da estrutura de diretórios tem que ser igual ao pacote da classe. Então se na classe está

package ricgrego.util

A estrutura de diretórios no jar tem que ser exatamente essa: ricgrego/util.
E no Path tem que ter a estrutura que falta para que seja encontrado o pacote, mais o pacote, pulando a estrutura, que seria:
D:/java/packages/util.jar

aaaahhhhh!!! que bagunça!!!

Que saco! Aparentemente está tudo certo. Não sei porque não reconhece o pacote!

Mudei tudo então para o seguinte:

[quote]package ricgrego.util; import java.io.*; public class Pergunta{ ... }
No JAR:

meta-inf/Manifest.mf ricgrego/util/Pergunta.class
Localização do JAR:

D:/java/packages/util.jar

Path:

%SystemRoot%system32;%SystemRoot%;%SystemRoot%System32Wbem; blablabla ;D:/java/packages/util.jar

Classe que usa o pacote, mas está fora do pacote:

import ricgrego.util.*; public class TestPergunta { ... }
Localização da Classe que usa o pacote (que deveria ser irrelevante):

D:/java/ex

Com tudo isso, tenho o seguinte erro:

D:/>cd java D:/java>cd ex D:/java/ex>javac TestPergunta.java TestPergunta.java:9: package ricgrego.util does not exist import ricgrego.util.*; ^ TestPergunta.java:13: cannot resolve symbol symbol : variable Pergunta location: class TestPergunta System.out.println(Pergunta.comando("E aÝ?")); ^ TestPergunta.java:15: cannot resolve symbol symbol : variable Pergunta location: class TestPergunta System.out.println(Pergunta.comando()); ^ 3 errors

[quote=“grego”][quote=“Rafael Steil”]Vamos chamar o .jar de “meuJar.jar”. Para usar ele, voce precisa colocar no classpath:

set CLASSPATH=.;%CLASSPATH%;c:/meuJar.jar

opa! É isso mesmo? No meu Path tenho:

D:/java/packages/ricgrego/util.jar

Cabe aqui um parênteses. Quando eu falo Path, é mesmo a variável Path do W2k, a mesma que tem: %SystemRoot%system32;%SystemRoot%; etc
[/quote]

naaaaaaaaaaaao :slight_smile:

eh CLASSPATH, e nao PATH :wink:

classpath eh a variavel de ambiente com os diretorios / jars onde o java ira procurar coisas… PATH eh onde o SO procura por programas executaveis… sao totalmente distintas.

Rafael

[quote=“Rafael Steil”]naaaaaaaaaaaao :slight_smile:

eh CLASSPATH, e nao PATH :wink:

classpath eh a variavel de ambiente com os diretorios / jars onde o java ira procurar coisas… PATH eh onde o SO procura por programas executaveis… sao totalmente distintas.

Rafael[/quote]

Cara, que paciência que vc tem!! :slight_smile:
Vou trocar minha imagem. Tô procurando uma com close de uma anta!

Mas aproveitando o encejo, então se eu não for usar pacotes fora dos que são padrões da linguagem, ou colocar tudo como parâmetro do javac, não precisaria nem criar essa variável?

Voce precisa criar os pacotes da forma correta, senao vai comecar a ter um monte de erro de import.

Em relacao ao outro ponto, vc nao eh obrigado a colocar tudo no CLASSPATH, se passar como parametro para os comandos javac E java.

Rafael