Copiar arquivos de dentro do Jar

18 respostas
R

Pessoal, eu estou fazendo um projeto java e tem alguns arquivos que eu gostaria de unir ao .jar para que eu pudesse copia-los usando o jar que foi gerado do projeto.

Alguém poderia me dizer como fazer isso? minha intenção é que todos os arquivos necessários para o programa estejam dentro do próprio .jar.

Grato.

18 Respostas

heliofrota

Boa noite robsonrpg,

Se você estiver usando maven pode atingir seus objetivos com o auxílio do http://maven.apache.org/plugins/maven-shade-plugin/

Hebert_Coelho

Caso não esteja utilizando o maven.

Vc sabe como gerar um jar? Vai gerar pelo Ant? Na unha como guerreiro mesmo? Por alguma IDE?

heliofrota

Bom questionamento jakefrog.

R

Heliofrota e Jakefrog

Eu estou gerando um runnable jar file, usando o export do eclipse (creio que ele use o ant, mas n tenho certeza), eu até consegui gerar o jar e o aplicativo está rodando sem problemas, fiz com que um botão dele executasse um comando de copia usando o Runtime.getRuntime().exec(comando), teste mandando copiar de um diretório para outro e funcionou, tanto testando no projeto quanto pelo jar que gerei.

Após isso eu adicionei os arquivos que eu queria ao build path para tentar copiá-los de dentro do jar posteriormente, mas não consegui, não sei se a sintaxe do comando está errado ou se para fazer isso eu precisaria usar alguma outra forma.
Infelizmente ainda não uso o maven, já vi um bocado de posts falando dele mas ainda não tentei usá-lo.

Para gerar o jar na unha eu precisaria ir pelo prompt navegar até a pasta do projeto e dar um Java ?jar cvf MeuProjeto.jat *.class não é? Pois tentando dessa forma sempre dá erro =/

Obrigado pela ajuda.

ribclauport

Bom, esses dias vi um post aqui mesmo falando a respeito de copiar arquivos, olhe o código abaixo:

package pack1;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.io.FileUtils;

public class Teste1 {
	public static void main(String[] args) {
		
		Teste1 t = new Teste1();
		t.copia();
	}
	public void copia(){
		InputStream source = getClass().getResourceAsStream("/resources/teste.txt");      
	    File file = new File("C:\\abc\\teste.txt");  
	          
	    try {  
	        FileUtils.copyInputStreamToFile(source, file);  
	    } catch (IOException e1) {  
	        throw new RuntimeException(e1);  
	    }  
	}
	
}

executei de dentro do jar e copiou o arquivo de dentro do jar para fora... funcionou belezinha... com relação ao runable se abrir o jar vai ver que ele usa o maven para gerar o jar runable...

heliofrota

Sim para gerar na unha é por ai mesmo.

por exemplo:

$ touch teste1.txt teste2.txt teste3.txt
$ jar cvf teste_all.jar teste1.txt teste2.txt teste3.txt

cria 3 arquivos
cria um jar com os 3 arquivos

ribclauport

Não se esqueça que ser for gerar o jar na unha terá que criar um arquivo Manifest dizendo qual sua classe que possue o metodo Main…
exemplo:

jar cvfm Ola.jar MANIFEST.MF

R

Aqui está dando erro no FileUtils , não está reconhecendo esse import import org.apache.commons.io.FileUtils

ribclauport

Você tem que baixar essa biblioteca…
Se quiser manda seu email em MP que te mando…

R

Desculpem a demora em responder, estive doente e acabei não podendo continuar o projeto durante alguns dias.

ribclauport, obrigado pela biblioteca e pela dica funcionou a cópia é feita de dentro do .jar, mas 1 dos arquivos não é copiado, ele é o unico arquivo .exe e também o maior dos arquivos (845 bytes), rodei a aplicação em modo debug e notei que é no ponto da cópia desse arquivo que está dando erro (ele é o ultimo, o demais nesse ponto já foram copiados), e as seguintes mensagens são exibidas no console

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1383)
	at org.apache.commons.io.IOUtils.copy(IOUtils.java:1357)
	at org.apache.commons.io.FileUtils.copyInputStreamToFile(FileUtils.java:1309)
	at EditarBGInfo.actionPerformed(EditarBGInfo.java:170)
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.awt.EventQueue.access$000(Unknown Source)
	at java.awt.EventQueue$3.run(Unknown Source)
	at java.awt.EventQueue$3.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue$4.run(Unknown Source)
	at java.awt.EventQueue$4.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)

E pelo que eu pesquisei parece que arquivos são considerados grandes apenas acima dos 2Gb.

Alguém imagina o que pode ser?

Obrigado

Hebert_Coelho

EditarBGInfo.actionPerformed(EditarBGInfo.java:170)
Essa classe é sua? Se sim, o que tem nessa linha?

ribclauport

Bom, eu olhei ae a dúvida do amigo, e decompilei o jar aqui... pela chamada do seu método, acredito que deve estar passando source nulo...

Olha a fonte do metodo:

public static void copyInputStreamToFile(InputStream source, File destination)
    throws IOException
  {
    FileOutputStream output;
    try
    {
      output = openOutputStream(destination);
      try {
        IOUtils.copy(source, output);
      } finally {
        IOUtils.closeQuietly(output);
      }
    } finally {
      IOUtils.closeQuietly(source);
    }
  }

Repare que no fonte abaixo do metodo copy, existe a manipulação dos dois objetos InputStream e File:

public static int copy(InputStream input, OutputStream output)
    throws IOException
  {
    long count = copyLarge(input, output);
    if (count > [telefone removido])
      return -1;

    return (int)count;
  }

depois ira chamar o copyLarge na pilha para esse fluxo, mas de qualquer forma todos os metodos estão manipulando input e output, acredito que voce deva estar passando um dos dois parametros nulos, mas como as vezes a pilha é meio complicada de acompanhar pode ser outro null pointer dentro do seu método,
da uma confirmada se quando voce ta fazendo algo do tipo:

InputStream source = getClass().getResourceAsStream("/resources/teste.txt");

seu source esta conseguindo obter o inputStrema para o arquivo a ser copiado.

S

Aproveitando o gancho do amigo. Eu não estou conseguindo inserir dados no banco quando eu crio o jar. O conector está na área de trabalho e eu crio o jar na área de trabalho também.

Antes, quando clicava em um botão do meu formulário de cadastro, ele exibia uma mensagem como se não tivesse encontrado o banco, pq coloquei isso num catch, mas agora eu clico e não aparece nenhum JOptionPane com erro. Mas ele também não chega a gravar nada.

ribclauport

Soruji, rode seu jar pelo cmd, pois ae você vai ver a saída do console certo…

java -jar seujar.jar

e poste a saída.

R

jakefrog, é sim minha classe, na linha 170 eu faço a chamada do metodo copyInputStreamToFile (dentro do actionPerformed)da forma como está abaixo:

FileUtils.copyInputStreamToFile(nomeFigura, dirDestino3);

Aqui é onde eu monto os argumentos que serão passados

String resolu = (String) resol.getSelectedItem();
			resolu = "Oficial" + resolu + ".jpg";
			InputStream nomeFigura = getClass().getResourceAsStream(resolu);
			System.out.println(resolu);
			String dir3;
			dir3 = uni + ":\\Users\\Public\\Info\\" + resolu;
			File dirDestino3 = new File(dir3);

Mas esse arquivo é copiado normalmente, o arquivo que não está sendo copiado é o que vem logo após ele, e estou fazendo da mesma forma, já refiz esse pedaço do código algumas vezes, já apelei até pro crtl+c ctrlv de outro trecho e continuo na mesma, e o mais estranho é que eu até dei um systrace na String que eu estava passando da seguinte forma:

String exec = "Info.exe";
InputStream executavel = getClass().getResourceAsStream(exec);
System.out.println(exec);

E o nome exato estava aparecendo, eu pensei então que pudesse ser problemas por eu estar passando o nome errado e mesmo copiando e colando o nome do arquivo continuei na mesma =/

ribclauport

Coloca ae um read para ver se ta lendo algum byte deste arquivo:

String exec = "Info.exe";  
InputStream executavel = getClass().getResourceAsStream(exec);  
System.out.println(executavel .read()); //Reads the next byte of data from the input stream. The value byte is returned as an int in the range 0 to 255

Qual a saída?

R

A saída foi 77.

_Zell_

Show! Tudo isso foi muito útil para mim galera… muito legal a partilhamento da informação.

Abraço a todos!

Criado 24 de fevereiro de 2012
Ultima resposta 22 de mar. de 2012
Respostas 18
Participantes 6