Problema ao carregar imagem a partir do jar

40 respostas
A

Criei um código simples que carrega uma imagem, no SWT… Quando executo a aplicação pelo Eclipse a imagem carrega perfeitamente e tudo funciona, porém após gerar o JAR e tentar executar pelo Sistema Operacional ele está dizendo que não encontra a imagem, sendo que a pasta e a imagem estão dentro do jar, é ridículo!

Caused by: java.io.FileNotFoundException: imagens\tabuleiro.png (O sistema não pode encontrar o arquivo especificado)

dentro do jar tenho uma pasta chamada imagens, e dentro dessa pasta tenho um arquivo chamado tabuleiro.png

O que estou fazendo de errado? Pela lógica nada!

Obrigado

40 Respostas

A

Minha dúvida é tão ridícula, o erro é tão estúpido que até pra vocês fica foda responder né? :confused:

Que droga, alguém por favor chuta ae!

Obrigado!

G

Cara, antes de fazer um post eu acho melhor vocêdá uma pesquisada pra vê se alguém já postou alguma coisa parecida com o seu problema, eu acho que na semana passada já respondi a dois posts como esse mesmo problema.
O que tá acontecendo é que não está encontrando o path da imagem, dá uma conferida no path e se tu tá carregando a imagem tipo:

new ImageIcon(getResource("path/image.ext"));

ou algo parecido faz assim

new ImageIcon("path/image.ext"));

se ele não conseguir carregar a imagem não vai dar erro, só não vai mostrar a imagem.

L

Se a imagem está dentro de um jar tem que usar o getResource

M

Em 20 min voce já que a resposta… calma aew…

Então.

Como voce carrega a imagem?

new File("imagens/tabuleiro.png");
//ou
getClass().getResourceAsStream("imagens/tabuleiro.png");
A

eu estava fazendo assim:

tabuleiroComposite.setBackgroundImage(new Image(Display.getDefault(),“imagens/tabuleiro.png”));

mas quando coloquei assim:

tabuleiroComposite.setBackgroundImage(new Image(Display.getDefault(),getClass().getResourceAsStream(“imagens/tabuleiro.png”)));

passou a dar este erro, e no proprio eclipse, nem gerando jar

Exception in thread “main” java.lang.IllegalArgumentException: Argument cannot be null

Obrigado por enquanto

G

Não é obrigatório, pode sim colocar somente o path sem o getResource(), mas o problema dele com certeza é path que está errado, quando comecei a programar em java e criava os arquivos .jar tive esse mesmo problema quando comecei a usar getResource() até que descobri que era o path.

A

Não é obrigatório, pode sim colocar somente o path sem o getResource(), mas o problema dele com certeza é path que está errado, quando comecei a programar em java e criava os arquivos .jar tive esse mesmo problema quando comecei a usar getResource() até que descobri que era o path.

mas eu não comecei a programar ontem… Sou programador C há anos e tenho certeza que o path está certo! existe a pasta e a imagem dentro dela!

A

Se o path está errado, prq q de dentro do eclipse funciona? incrível neh!

V

ATENÇÃO:

  1. O path é relativo ao classpath da sua aplicação: O getResourceAsStream leva o ClassPath como raiz, não o path do disco;
  2. Que o caminho é idêntico, levando em consideração letras maiúsculas e minúsculas. O sistema de arquivos não é case sensitive, no caso do Windows, mas no caso do .jar é;
V

É problema de path sim. A questão é que o path do eclipse baseia-se no sistema de arquivos, e o do .jar no jar. Um é case sensitive, outro não. Um está com a raiz na raiz do seu classpath, outro pode estar em qualquer pasta de execução do eclipse configurada em seu projeto.

Como você mesmo comprovou, rodar no eclipse não é garantia de nada.

G

Depois das palavras do Vinicius (ViniGodoy), você se convenceu que é o path.

A

Ta certo! é o path… mas qual a solução afinal? ta tudo minusculo!

A

Minha mentalidade é de C, eu penso apenas logicamente, não consigo interpretar conceitos do java. Pra mim se funciona no eclipse teria de funcionar fora também, aprece obvio! Eu não nasci pro java mesmo, só que na faculdade o java é a linguagem escolhida pelos professores :confused:

Obrigado por enquanto!

A

Pelo que li tenho que colocar no classpath o caminho do meu jar, mas isso não tem fundamento pois se eu colocar em outra pasta ele nao ira funcionar!

por favor alguem ajuda ae!

valew

V

aloha:
Minha mentalidade é de C, eu penso apenas logicamente, não consigo interpretar conceitos do java. Pra mim se funciona no eclipse teria de funcionar fora também, aprece obvio! Eu não nasci pro java mesmo, só que na faculdade o java é a linguagem escolhida pelos professores :confused:

Obrigado por enquanto!

Aloha… eu também fui programador C. O Java é tão lógico quanto o C.

É bem simples. Crie uma pasta para os recursos do seu projeto, dentro do seu classpath. Você simplesmente criar um novo pacote entre os seus fontes, mas colocar recursos (jpgs, wavs, etc) lá dentro, ao invés de código.

Vamos supor que seu pacote seja:
aloha.imagens

E que dentro dessa pasta você tenha colocado a imagem “tabuleiro.png”.

Para carregar essa imagem você faz:

BufferedImage tabuleiro = ImageIO.read(getClass().getResource("/aloha/imagens/tabuleiro.png"));

Com esse método o Java irá seguir as regras de classpath para procurar a sua imagem. Ou seja, no eclipse, ele procurará nos seus arquivos ali onde ele compilou os .class. No caso do .jar, o próprio .jar faz parte do classpath, e ele procurará lá também.

Você não pode é esperar que o construtor default de image, que aceita um “file”, faça a busca dentro do .jar para você. Ali sim, é feito para trabalhar com unidades de disco, e seria ilógico se isso fizesse uma busca dentro de um arquivo .jar.

A

ViniGodoy,

Não posso usar o BufferedImage, tirando isso não entendi mais nada…

“Crie uma pasta para os recursos do seu projeto, dentro do seu classpath” (mas o classpath nao eh um arquivo q fica dentro do jar?)

Ahhhh q droga, ta chegando a hora de entregar o jogo que é em rede e não consigo fazer o “mais facil” que é gerar o jar…

Valew cara, mas se puder ser mais especifico, eu nao quero aprender isso soh kero fazer funcionar!

Abraço

A

Consegui, mas mesmo assim ficou muito estranho…

na pasta imagens eu tenho varias imagens, e todas eu estava carregando assim:

labelStatus.setImage(new Image(Display.getDefault(),“imagens/status2.png”));

porem estava dando erro na imagem do tabuleiro, entao fiz oq ViniGodoy falou, ateh a extencao q estava PNG maiusculo tava dando erro :confused:

tabuleiroComposite.setBackgroundImage(new Image(Display.getDefault(),getClass().getResourceAsStream("/imagens/tabuleiro.PNG")));

entao eu apenas alterei a linha do tabuleiro e funcionou o JAR, eu clico 2x e ele executa perfeitamente, mas pera ae, e as outras imagens? prq nao precisou fazer o mesmo codigo pras demais? essa parte: getClass().getResourceAsStream("/imagens/tabuleiro.PNG")

agora sim nao entendo mais!

Obrigado a todos!

V

Como não? O BufferedImage é um Image! Você pode usar sim, senão não teria sugerido!

Não, classpath não é um arquivo. Você está confundindo com o manifest, não?
ClassPath é o caminho onde suas classes estão.

É o mais fácil, desde que você tome alguns cuidados, como usar o getResource() ao invés de ler as imagens direto do disco. Se você ler do disco, faça um zip do seu .jar com a pasta de imagens, e deixe que o usuário descompacte os dois juntos.

Para eu ser mais específico, só se vc zipar seu projeto e colar aqui no GUJ. Aí posso dar uma olhada e ajeitar o que estiver errado.

M

ViniGodoy! Aproveitando que voce vai ler esse post me mande o JGF plz. Eu tava procurando a versão que tem o pacote de network mas eu perdi.

A

ViniGodoy,

quanto usar o “getResource()” tudo bem, quando coloquei ele para carregar o tabuleiro funcionou, mas prq as demais imagens (que eu nao estava usando o getResource()) não estão dando o mesmo erro?

outra dúvida, agora que esta funcionando o JAR (estou clicando 2x e ele abre em qualquer pasta do meu windows) eu passei ele pra outro computador e quando clico 2x la da uma msg de erro dizendo que não achou o main class. Mas como nao se em 1 pc ele acha deveria achar no outro tbm, q desgraça na minha vida!

Obrigado Vinicius

A

Desculpem-me se eu ofender mas, as pessoas dizem que o java é portavel e tudo mais, mas até hoje só tive dor de cabeça não consigo executar o mesmo programa nem em outro PC de mesma plataforma :confused:

Obrigado!

V

Qual é a versão do Java no outro computador? É a mesma?

O Java é sim, super portável. Aqui rodamos em diversas máquinas, incluindo algumas Linux. Não culpe o Java por sua falta de conhecimento.

Mas você realmente precisa tomar alguns cuidados, para que a portabilidade ocorra sem traumas. Fique tranquilo, são regras mais simples e mais intuitivas do que as de alocação de memória do C. Em pouco tempo, você vencerá essa curva de aprendizado e terá menos estresse.

A

Vini, em relação a imagem, eu estava com o mesmo problema… vou tentar contextualizar um pouco: Utilizei o NetBeans 6.7 para desenvolver um projetinho, matar a curiosidade em java. Sei que o classpath é um path relativo o qual matenho toda minha referência de projeto. Sei também que tudo na pasta lib pode estar dentro deste classpath. Levando isso em consideração: coloquei minha pasta /Imagem dentro de um jar, pois ao tentar colocar a pasta /Imagem na lib do meu projeto dentro do net beans durante a construção, a pasta lib desaparecia, não era construida e mesmo que com a sua criação manualmente com todas as dependências a referência não era mantida, mudei até mesmo o manifest.mf para tentar a referência, porém não foi mantida.
Felizmente resolvi o problema com getClass().getResource("/Imagem/imagem.JPG"), porém - mesmo não sendo uma imagem, mas acredito estar dentro do mesmo contexto - o mesmo raciocínio não funcionou para um arquivo help.exe que tentei executar com Runtime.getRuntime().exec("/Help/Help tcc_Help.exe").

nota: Colocar somente o caminho de referência relativo do classpath até os meus arquivos .exe e .JPG não funciona. A imagem consegui carregá-la utilizando o getResource(), porém o .exe nem mesmo assim…

Valeu, espero respostas…

M
ViniGodoy:
aloha:
Se o path está errado, prq q de dentro do eclipse funciona? incrível neh!

É problema de path sim. A questão é que o path do eclipse baseia-se no sistema de arquivos, e o do .jar no jar. Um é case sensitive, outro não. Um está com a raiz na raiz do seu classpath, outro pode estar em qualquer pasta de execução do eclipse configurada em seu projeto.

Como você mesmo comprovou, rodar no eclipse não é garantia de nada.
Boa tarde, Vini. Estou com o mesmo problema!
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;

public class Volante{
	
	private BufferedImage bufferedImage = null;
	
	public Volante(){
		try {
            URL imgUrl = this.getClass().getResource("/image/volante.png");
            if (imgUrl == null) {
                System.out.println("Imagem não encontrada!");
            } else {
                bufferedImage = ImageIO.read(imgUrl);
            }
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
	}
	
	public BufferedImage getBufferedImage(){
		return bufferedImage;
	}
}

Você algum erro nesse código? Essa é uma classe para carregar a imagem.

V

Nenhum problema. Como está a estrutura de pacotes do seu projeto? E dá algum erro?

M

A estrutura é a seguinte:
src (Source Folder)
res (Source Folder), contendo um package com as imagens.

Não ocorre nenhum erro. Inclusive ele retorna um endereço de onde o .jar se encontra tudo correto, porém não exibe as imagens no frame.
As classes Volante e Cangaceiro, estão em res. Elas carregam as imagens.

M

Coloquei para imprimir o endereço que é gerado através do getClass().getResource() e o endereço é jar:file:/C:/Users/Michel/Desktop/application.jar!/image/volante.png que ao que me parece está correto e mesmo assim não exibi no frame.

V

Posta o código de como vc está fazendo para mostrar isso no frame.

M

imgPersonC, imgPersonV e imgSeta são do tipo BufferedImage.

public void loadImg() {
		imgPersonC = new Cangaceiro().getBufferedImage();
		imgPersonV = new Volante().getBufferedImage();
		imgSeta = new Seta().getBufferedImage();
	}

public void onRender(Graphics2D graphics2d) {
		graphics2d.drawImage(imgPersonC, personC.x, personC.y, null);
		graphics2d.drawImage(imgPersonV, personV.x, personV.y, null);
		
		graphics2d.translate((imgSeta.getWidth()) + seta.x, (imgSeta.getHeight()) + seta.y);
		graphics2d.rotate(angle * (Math.PI/180));
		graphics2d.translate(-((imgSeta.getWidth()) + seta.x), -((imgSeta.getHeight()) + seta.y));
		graphics2d.drawImage(imgSeta, seta.x, seta.y, null);
		
		graphics2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f));
		
		
	}

public void render() {
        Graphics2D graphics2d = (Graphics2D) bufferStrategy.getDrawGraphics();
        graphics2d.setColor(Color.WHITE);
        graphics2d.fillRect(0, 0, frame.getWidth(), frame.getHeight());
        onRender(graphics2d);
        graphics2d.dispose();
        bufferStrategy.show();
    }

public void onRender(Graphics2D graphics2d) {
		graphics2d.drawImage(imgPersonC, personC.x, personC.y, null);
		graphics2d.drawImage(imgPersonV, personV.x, personV.y, null);
		
		graphics2d.translate((imgSeta.getWidth()) + seta.x, (imgSeta.getHeight()) + seta.y);
		graphics2d.rotate(angle * (Math.PI/180));
		graphics2d.translate(-((imgSeta.getWidth()) + seta.x), -((imgSeta.getHeight()) + seta.y));
		graphics2d.drawImage(imgSeta, seta.x, seta.y, null);
		
		graphics2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f));
		
		
	}
V

Dica: No rotate, use Math.toRadians no lugar de multiplicar por PI/180, fica mais claro.

Quem chama os métodos onRender e render?

M

render chama onRender!

public void executeApp(){
active = true;

load();
	
	while(active){
		update();
		render();
	}
	
	unload();
}
V

E quem chama o render? Tem uma thread para isso?

M

Tem sim!

V

Onde você chamou o loadImg? Pode postar o código dessa thread.

M

Posso mandar o código completo! Fica mais fácil para identificar o erro! Eu particularmente tento desde ontem e não consigo!

M

Assim que baixar me sinaliza, por favor! Para testar é só executar a classe server primeiro e depois a classe application

M

Muitos problemas no código?

M

Enfim, consegui!

V

E qual foi a solução? O que você estava fazendo de errado?

M

Por incrível que parece a solução foi bastante simples. Esse projeto de inicialmente não continha um Source Folder para conter os recursos da aplicação. Fiz isso depois. Copiei e colei os recursos. Porém, tinha certeza que o código não estava errado, tanto é que ele retornava o endereço do .jar sem problemas. Então, decidi criar um novo projeto e dessa vez fazer os procedimentos corretos, isto é, criar outra Source Folder através do menu Propreties e adicionar as imagens logo em seguida através da Workspace. Logo após só fiz copiar e color o código e para meu espanto deu certíssimo. Acho que foi algum problema com a IDE Eclipse.

Criado 1 de abril de 2009
Ultima resposta 17 de jan. de 2014
Respostas 40
Participantes 7