Exportar estrutura do projeto complexo [RESOLVIDO]

15 respostas
Rodrigo_Ribaldo

Bom dia pessoal,

Novas dúvidas:

Tenho a seguinte estrutura no eclipse

Projeto
    |---src
    |---h2
    |---images
    |---lib
    |---messages
    |---print

Dentro do src tenho:

|---src
           |---br.com.empresa.comunicador
                       |---comunicador.java   // É a classe que contém o método man

Eu preciso da seguinte estrutura na pasta do cliente quando eu for instalar no pc dele:

Diretório do Cliente
    |---programa.jar  // esse seria o "executável do meu Sistema"
    |---h2 // esta seria a pasta onde ficam os arquivos do Banco de Dados
    |---images //aqui algumas imagens usadas pelo Sistema
    |---messages // aqui mensagens de internacionalização
    |---print // aqui arquivos compilados dos relatorios

Esta pasta messages precisa ficar acessível ao usuário, pois se ele quiser um novo idioma para o Sistema será apenas colocar um arquivo do tipo .properties ali.

Na pasta images ele tb poderá colocar novas imagens, que ficarão disponíveis no Sistema.

O problema é:

Se eu mando exportar com Jar File

O eclipse cria um único arquivo do tipo .jar

Portanto, a pergunta é:

Como se faz a exportação de um projeto para eu criar um CD com tudo o que o cliente precisa para apenas copiar para a máquina dele, clicar em um arquivo “executável” e o Sistema funcionar?

Desde já agradeço pela ajuda!

Obrigado

15 Respostas

E

Crie um projeto ANT que faça essas coisas exatamente do jeito que você quer.

Você precisa estudar o ANT (não adianta a gente só lhe passar a receita de bolo, porque você vai ter de mudar isso de qualquer jeito mesmo :frowning: )
e ter um pouco de paciência para que as coisas saiam exatamente do jeito que você quer.

Eu simplesmente não tenho a paciência suficiente e faço as coisas na mão. Mas se tiver de documentar o processo, prefiro escrever o script ANT em vez de ter de escrever um documento Word, cheio de telinhas e comandos, que faça a mesma coisa.

Rodrigo_Ribaldo

entanglement:
Crie um projeto ANT que faça essas coisas exatamente do jeito que você quer.

Você precisa estudar o ANT (não adianta a gente só lhe passar a receita de bolo, porque você vai ter de mudar isso de qualquer jeito mesmo :frowning: )
e ter um pouco de paciência para que as coisas saiam exatamente do jeito que você quer.

Eu simplesmente não tenho a paciência suficiente e faço as coisas na mão. Mas se tiver de documentar o processo, prefiro escrever o script ANT em vez de ter de escrever um documento Word, cheio de telinhas e comandos, que faça a mesma coisa.

Olá entanglement,

Obrigado pela dica…

Porém, o que eu precisaria era entender como funciona manualmente para depois entender essa ferramente ANT.

Por exemplo, eu queria entender o porquê e qual a diferença de criar uma pasta por exemplo a images da minha estrutura e através do eclipse colocá-la no classpath.

Vivo com problemas com o tal do classpath.

Quando eu tenho que colocá-la no classpath quando eu não tenho e quando eu não posso.

No meu Sistema tenho uma classe que criei para pegar arquivos de internacionalização:

public static String getI18nLabel(String label) {

		locale = IdiomaPadrao.getLocale();
		
		rb=ResourceBundle.getBundle("messages",locale); 
	    try{
	    	i18nlabel = rb.getString(label);
	    }catch(MissingResourceException e) {
	    	i18nlabel=""; 
	    }

		return i18nlabel;
	}

Só que ele pega os arquivos properties que estão no scr e não na minha pasta messages da estrutura que passei logo no começo do post.

Porque?

Essas coisas básicas estou com dúvidas.

Estou com muita dificuldade de entender isso, poderia me ajudar?

Obrigado

E

Você sabe fazer um shell script (no caso do Windows, uma batch?)
É que você não consegue setar um classpath assim do nada, quando for executar o seu JAR. No máximo, você pode indicar os paths relativos para as bibliotecas, mas não o classpath, dentro do MANIFEST.MF.

Rodrigo_Ribaldo

entanglement:
Você sabe fazer um shell script (no caso do Windows, uma batch?)
É que você não consegue setar um classpath assim do nada, quando for executar o seu JAR. No máximo, você pode indicar os paths relativos para as bibliotecas, mas não o classpath, dentro do MANIFEST.MF.

entanglement ,

Poderia descer mais um pouco o nivel…srsrs

Sou bem mais leigo que isso. O que não entendi até agora são esses termos, exemplo:

O que vc quer dizer com:

“indicar os paths relativos para as bibliotecas”

“mas não o classpath, dentro do MANIFEST.MF”

No caso, do arquivo batch, sei o que é, mas não sei fazer para esse propósito…

Bom se puder ir me orientando agradeço, mas claro, não é receita de bobo que quero, quero aprender mesmo…

Obrigado

ViniGodoy

Mande imprimir o seguinte canonical path:

new File(".").getCanonicalPath();

E veja se a aplicação está mesmo rodando com base no diretório que você pensa que está. A princípio, não é necessário fazer nada de diferente para o jar enxergar as subpastas.

Rodrigo_Ribaldo

ViniGodoy:
Mande imprimir o seguinte canonical path:

new File(".").getCanonicalPath();

E veja se a aplicação está mesmo rodando com base no diretório que você pensa que está. A princípio, não é necessário fazer nada de diferente para o jar enxergar as subpastas.

Onde coloco isso ?

System.out.println(new File(".").getCanonicalPath());

Rodrigo_Ribaldo

Rodrigo Ribaldo:
ViniGodoy:
Mande imprimir o seguinte canonical path:

new File(".").getCanonicalPath();

E veja se a aplicação está mesmo rodando com base no diretório que você pensa que está. A princípio, não é necessário fazer nada de diferente para o jar enxergar as subpastas.

Onde coloco isso ?

System.out.println(new File(".").getCanonicalPath());

Vini, errei colocando System…

Fiz assim:

JOptionPane.showMessageDialog(null,new File(".").getCanonicalPath(),"Testando",JOptionPane.ERROR_MESSAGE);

Coloquei isso dentro da classe que tem o metodo man

Resultado:

C:\Users\Rodrigo\Desktop\aplicacao

E agora?

ViniGodoy

De dentro do .jar, é esse o resultado? E as subpastas estão dentro dessa pasta aí?

Rodrigo_Ribaldo

Vini…

Realizei vários testes no meu programa, inclusive criei um outro projeto simples para testes…

Isolei o problema, mas não consigo resolver, já fiz de tudo. Dê uma olhada na classe abaixo, pois quando rodo a aplicação aparece a seguinte mensagem dada pelo JOptionPane que coloquei no catch:

C:\Users\RODRIGO\Desktop\exe

org.h2.Driver

[LJava.lang.StackTraceElement;@aa9835
public class FactoryConnection {
	
	public static FactoryConnection instance = new FactoryConnection();
	
	/**
	 * 
	 */
	private FactoryConnection() {

	}
	
	/**
	 * @return the instance
	 */
	public static FactoryConnection getInstance() {
		return instance;
	}
	
	
	public Connection conexao(){
		

		Connection conn = null;
		String path = "C:/Users/Rodrigo/Desktop/exe/h2/comunicador";
		try{
			Class.forName("org.h2.Driver");
			String url="jdbc:h2:file:" + path;
			String user = "sa";
			String password="";
			conn=DriverManager.getConnection(url,user,password);
		}catch (Exception e) {
			try {
				JOptionPane.showMessageDialog(null,new File(".").getCanonicalPath()+"\n\n"+e.getMessage()+"\n"+e.getStackTrace(),"teste",JOptionPane.ERROR_MESSAGE);
			} catch (HeadlessException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			e.getMessage();
		}
		
		return conn;
	}

}

Eu achei que seria class-path. Tentei adicionar pelo eclipse, porém estou com sérias dúvidas quanto ao como fazer isso. Acho que eu devo estar colocando errado no classpath.

Quando eu exporto o projeto pelo Eclipse, fazendo export ->JAR File, o eclipse cria um arquivo .jar, quando eu mando extrair ele cria uma pasta chamada META-INF, dentro dessa pasta tem o arquivo MANIFEST.MF e o conteudo é o seguinte:

Manifest-Version: 1.0

Main-Class: br.com.empresa.aplicacao.Aplicacao

O que posso estar fazendo errado?

Obrigado

ViniGodoy

O problema é só com o h2database?

E seu urlString não deveria ser: “jdbc:h2:file:h2” ?

Outra coisa, para imprimir o StackTrace completo, faça assim:

StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); String stackTrace = sw.toString();

O manifest, classpath, etc, refere-se apenas ao que tem dentro do jar, não fora. A única coisa que afeta o ambiente fora é o caminho onde a aplicação roda, e isso é definido pelo atalho que você criou para a aplicação. Se não criou nenhum atalho, então esse caminho refere-se ao local onde o .jar está.

O classpath só faz diferença no comando getClass().getResource(), pois ele procura por recursos no interior do seu .jar. Não é o caso aqui.

Rodrigo_Ribaldo

ViniGodoy:
O problema é só com o h2database?

E seu urlString não deveria ser: “jdbc:h2:file:h2” ?

Outra coisa, para imprimir o StackTrace completo, faça assim:

StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); String stackTrace = sw.toString();

O manifest, classpath, etc, refere-se apenas ao que tem dentro do jar, não fora. A única coisa que afeta o ambiente fora é o caminho onde a aplicação roda, e isso é definido pelo atalho que você criou para a aplicação. Se não criou nenhum atalho, então esse caminho refere-se ao local onde o .jar está.

O classpath só faz diferença no comando getClass().getResource(), pois ele procura por recursos no interior do seu .jar. Não é o caso aqui.

Vini, já estou ficando doente…

Agora faço as mudanças no eclipse e quando exporto ele não gera com as atualizações, o que pode ser?

Pq vc perguntou isso?

“E seu urlString não deveria ser: “jdbc:h2:file:h2” ?”

O que te levou a isso?

Obrigado

E

Vamos fazer umas perguntinhas. Digamos que você tenha o projeto compilado (as classes no diretório bin.)

  1. Você sabe montar o JAR na mão, usando uma linha de comando e o comando jar cvfm … ?
  2. Você sabe rodar seu programa com a linha de comando java -classpath biblioteca1.jar;biblioteca2.jar;biblioteca3.jar -jar SeuJar.jar ?

Se souber, é bem mais fácil entender o que deve ser feito. Senão, você precisa aprender urgentemente como fazer isso. O Eclipse sozinho não faz milagre.

Rodrigo_Ribaldo

entanglement:
Vamos fazer umas perguntinhas. Digamos que você tenha o projeto compilado (as classes no diretório bin.)

  1. Você sabe montar o JAR na mão, usando uma linha de comando e o comando jar cvfm … ?
  2. Você sabe rodar seu programa com a linha de comando java -classpath biblioteca1.jar;biblioteca2.jar;biblioteca3.jar -jar SeuJar.jar ?

Se souber, é bem mais fácil entender o que deve ser feito. Senão, você precisa aprender urgentemente como fazer isso. O Eclipse sozinho não faz milagre.

Confesso que achava ser mais fácil no eclipse, então não sei…mas vou ver isso tb. O pior é que me pegaram de surpresa e estou correndo contra o tempo, fiquei até as 3 da manhã de hj com isso e nada…Mas vou tentar ver isso com calma…

Obrigado

ViniGodoy

Melhor dar um clean, antes de continuar fazendo builds. E dormir um pouco.

Da documentação do h2. E do fato de vc ter um diretório chamado h2 na árvore que vc passou ali atrás.

Rodrigo_Ribaldo

Melhor dar um clean, antes de continuar fazendo builds. E dormir um pouco.

Da documentação do h2. E do fato de vc ter um diretório chamado h2 na árvore que vc passou ali atrás.

Vini / Pessoal…

Obrigado pela ajuda…

To começando a entender a exportação JAR File…

Com relação ao problema no banco de dados usei assim:

public Connection conexao(){
		
		Connection conn = null;
		String path = "./h2/comunicador";
		try{
			Class.forName("org.h2.Driver");
			String url="jdbc:h2:file:" + path + ";TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=0";
			String user = "sa";
			String password="";
			conn=DriverManager.getConnection(url,user,password);
		}catch (Exception e) {
			e.getMessage();
		}
		
		return conn;
	}

Isso está funcionando agora com o jar gerado

A estrutura dfica:

diretorioCliente
     |
     |---aplicacao.jar
     |
     |---h2
     |
     |---messages
     |
     |---images
     |
     |---print

Para conseguir usar properties fora do classpath, ou seja de um diretório externo ao projeto, fiz assim:

/**
	 * @return the label
	 */
	public static String getI18nLabel(String label) {

		locale = IdiomaPadrao.getLocale();

		String arquivo = "messages_" + locale + ".properties";
	
		FileInputStream fis = null;
		
		File file = new File("./messages/"+arquivo);

	    try{
	    	fis = new FileInputStream(file);
		rb = new PropertyResourceBundle(fis);
	    	i18nlabel = rb.getString(label);

	    }catch(MissingResourceException e) {
	    	i18nlabel=""; 
	    } catch (IOException e) {
			e.printStackTrace();
		}

		return i18nlabel;
	}

Obrigado a todos pela força!

Valeu!

Criado 30 de junho de 2010
Ultima resposta 5 de jul. de 2010
Respostas 15
Participantes 3