Estou com problemas quando tento executar um audio em .jar

36 respostas Resolvido
V

O problema é o seguinte quando eu só executo na IDE ele funciona o som normal mas quando eu compilo e tento executar aparece NullPointerException ou seja ele não achou o audio, mas
porque como resolvo isso? bom aqui está o codigo da classe do meu player:

import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;

public class Audio {
    URL fileUrl;
    AudioClip Som;

    public void Play(String qlms) {
        this.fileUrl = this.getClass().getResource(qlms);
        this.Som = Applet.newAudioClip(fileUrl);
    }
}

Eu gostaria de saber como resolver isso.

36 Respostas

Lucas_Camara

Qual o valor que está vindo no parâmetro qlms?

V

Ele está vindo de outra classe e o parametro é:
som.Play(“Sons/ThemeSong2.wav”);

Lucas_Camara

Esse arquivo está dentro do jar? Como está a estrutura de pastas do seu projeto?

V

Acho que você quis dizer isso e não as pastas em si tipo como se eu tivesse aberto um jar com winrar, se for o que eu estou pensando aqui esta uma imagem do meu projeto
AAAAA

V

Agora estou com 2 problema ele também não acha os arquivos dentro do pacote
mas se eu tirar de la de dentro deve voltar a funcionar mas continua o problema do .jar

Lucas_Camara

Em vez de usar:

"Sons/ThemeSong2.wav"

Tente assim:

"/PacoteJogo/Smarphone/Sons/SongTheme2.wav"

Update

Agora que reparei, vc está tentando carregar o arquivo ThemeSong2.wav, mas o nome dele no print que mandou é SongTheme2.wav. Está certo isso?

V

Nossa tinha escrito errado eu tinha escrito errado agora eu consertei mas continua o problema
AAAAAAAAAAAAAAAAAAAAA

Lucas_Camara

Tenta colocar da forma que falei agora

V

Continua com o mesmo problema :frowning:
image

Lucas_Camara

Foi mal, eu digitei errado, faltou o t em Smartphone. O certo é:

"/PacoteJogo/Smartphone/Sons/SongTheme2.wav"
V

Mesma coisa…

Lucas_Camara

Você está no windows ou no linux? Se for no windows, tente assim:

"\\PacoteJogo\\Smartphone\\Sons\\SongTheme2.wav"
V

O meu pc é windows, e continua não funcionado

Lucas_Camara

Mano, vc disse que soh dá erro quando executa através do jar, certo? Se sim, volte a utilizar a String “Sons/ThemeSong2.wav”.

Reparei agora, esse erro soh aparece quando vc gera o jar. Nesse caso, vc não pode usar: this.getClass().getResource(qlms);. Pois a JVM não vai conseguir determinar o path dentro do jar.

Para contornar isso, vc deve usar: this.getClass().getResourceAsStream(qlms);, que irá retornar um InputStream. Com esse stream, vc pode criar um arquivo temporário assim:

public static File stream2file (InputStream in) throws IOException {
	final File tempFile = File.createTempFile(PREFIX, SUFFIX);
	tempFile.deleteOnExit();
	
	try (FileOutputStream out = new FileOutputStream(tempFile)) {
		IOUtils.copy(in, out);
	}
	
	return tempFile;
}

obs: Esse exemplo usa uma lib externa (IOUtils da apache).

E, através do arquivo temporário criado (tempFile), vc consegue recuperar a URL desse arquivo e passar para o método newAudioClip.

V

Desculpe a demora tive que fazer uns negocio o que eu coloco no sufix?
Ele ta dizendo que o PREFIX é muito curto, E se eu deixo como está diz que que não achou nada atribuindo o SUFIX nenhuma variavel.

Lucas_Camara

PREFIX = “SongTheme2”
SUFFIX = “wav”

V

obrigado

V

ta dando nullPointerException
image

acho que o problema está aqui:

import static com.sun.xml.internal.fastinfoset.vocab.Vocabulary.PREFIX;
import java.applet.Applet;
import java.applet.AudioClip;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import org.apache.commons.io.IOUtils;

public class Audio {
    URL fileUrl;
    AudioClip Som;
    InputStream a;
	
    public void Play(String qlms) throws IOException {
        System.out.println(qlms);
        
        //Sinto que o problema esta aqui: 27
        
        this.a = this.getClass().getResourceAsStream(qlms);//Bem aqui
        
        //Aqui em cima ^^^^^^
        
        System.out.println(this.a);
        String b;
        b = stream2file(this.a).getPath();
        System.out.println(stream2file(this.a).getPath());
        URL url2 = new URL(b);
        this.fileUrl = url2;
        this.Som = Applet.newAudioClip(this.fileUrl);
    }
	
    public static File stream2file (InputStream in) throws IOException {
		final File tempFile = File.createTempFile("SongTheme2", ".wav");
		tempFile.deleteOnExit();
		
		try (FileOutputStream out = new FileOutputStream(tempFile)) {
			IOUtils.copy(in, out);
		}
		
		return tempFile;
	}
}
Lucas_Camara

Não se preocupe, vamos conseguir kkk

Agora tente passar um desses paths:

"\\PacoteJogo\\Smartphone\\Sons\\SongTheme2.wav"
"/PacoteJogo/Smartphone/Sons/SongTheme2.wav"
V

um avanço mas tenho uma pergunto de onde ele tirou tanto numero depois do 2? ksksksksk
image
pelo menos não aparece mais null

Lucas_Camara
Solucao aceita

Isso é automático to tempFile. Ao criar um tempFIle, ele é criado na pasta temp do usuário do sistema operacional. Esse numero garante que não haverá outro arquivo com o mesmo nome e evita erros.

Agora esse erro deve ser por conta dessa parte:

b = stream2file(this.a).getPath();
System.out.println(stream2file(this.a).getPath());
URL url2 = new URL(b);

Em vez disso, faça assim:

File file = stream2file(this.a);
this.fileUrl = file.toURI().toURL();
V

Uma pergunta esse problema de ele não achar coisas que esta dentro do pacote també serve para imagens?

Lucas_Camara

Sim, mas somente quando é executado através do JAR. Por isso é melhor usar getResourceAsStream em vez de getResource.

V

nossa kskskkssk vai demorar mais do que eu imaginava ksksk mas ok obrigado

V

E esse é o topico mais longo que eu ja vi skskksksks

Lucas_Camara

mas do jeito que seu código está, já está quase pronto. Acredito que vá funcionar depois que vc fizer o ajuste que passei.

V

Alguem sabe como faz isso com imagem?

staroski

Mesma coisa, sempre que for ler um recurso de dentro do JAR, utilize o getResourceAsStream.

Lucas_Camara

Faça como o @staroski disse, e depois de obter o InputStream, vc deve converter para um array de bytes (byte[]), assim: https://www.baeldung.com/convert-input-stream-to-array-of-bytes (várias formas de fazer isso nesse link)

V

obrigado

V

Eu fiz uns testes e como que eu vou conseguir conerter um inputStream para bytes[] com isso:

public void givenUsingPlainJava_whenConvertingAnInputStreamToAByteArray_thenCorrect()  throws 
IOException {
    InputStream initialStream = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
    byte[] targetArray = new byte[initialStream.available()];
    initialStream.read(targetArray);

    }

e também ja tentei converter em byte[] de outras formas mas não funcionou,
ja tentei converter em url também mas aconteceu alguma coisa que na hora do IOutilitys.copy(in, out); ele recebia null.

staroski

Eu costumo fazer com o método readBytes abaixo:

public byte[] readBytes(InputStream input) throws IOException {
	ByteArrayOutputStream output = new ByteArrayOutputStream();
	copy(input, output);
	return output.toByteArray();
}

public void copy(InputStream source, OutputStream target) throws IOException {
	byte[] buffer = new byte[8192];
	for (int read = -1; (read = source.read(buffer)) != -1; target.write(buffer, 0, read)) { /* corpo deste for é vazio mesmo */ }
	target.flush();
}
V

Então eu estou com o mesmo problema do som mas agora é com imagem, parece que é so fazer igual ao solção do som mas não é parece ser bem mais complicado pois quando eu compilo tento abrir o jar mostra o erro NullPointerException, e nesse caso o problema foi esse:

<strong>Exception in thread “main” java.lang.NullPointerException

at PacoteJogo.ImageLoader.copy(ImageLoader.java:114)

at PacoteJogo.ImageLoader.readBytes(ImageLoader.java:108)

at PacoteJogo.Jogo.Tela(Jogo.java:122)

at PacoteJogo.Main.main(Main.java:26)</strong>

de varios problemas com NullPointerException:

staroski

O InputStream que você está passando pro readBytes está null.

Posta seu fonte.

V
InputStream inp2 = this.getClass().getResourceAsStream("../Sprites/Botão.png");
    byte[] readBytes1 = imageLoader.readBytes(inp2);//Note que o readBytes está dentro da classe ImageLoader
    ImageIcon bb2Im = new ImageIcon(readBytes1);
    JButton bb2 = new JButton(bb2Im);
staroski

Esse caminho está errado.

  1. Coloca o ser arquivo em uma pasta (ou pacote) que faça parte do classpath de sua aplicação.

  2. Assegure que esta pasta e arquivos estão dentro do JAR. (Qualquer coisa, posta como está a estrutura dentro do seu JAR)

  3. Não utilize .. no caminho, comece o caminho com / para procurar a partir da raíz do classpath.

Criado 29 de março de 2020
Ultima resposta 31 de mar. de 2020
Respostas 36
Participantes 3