Olá… preciso percorrer um diretorio que está dentro do jar, quando rodo pela IDE ele roda normal, quando exporto para jar o seguinte erro é retornado.
Caused by: java.lang.IllegalArgumentException: URI is not hierarchical
at java.io.File.<init>(Unknown Source)
at jgf.imaging.loader.DirLoader.load(DirLoader.java:74)
at jgf.imaging.ImagePallete.reload(ImagePallete.java:102)
at jgf.imaging.ImagePallete.<init>(ImagePallete.java:51)
at td.cfg.GameConfig.<clinit>(GameConfig.java:17)
... 9 more
O código para carregar é esse:
URL resource = getClass().getResource(param.getAttribute("src"));//isso retorna /resource/images
File file = null;
try {
file = new File(resource.toURI());
} catch (URISyntaxException e1) {
e1.printStackTrace();
}
List<File> files = getAll((file), null);//Aqui listo os arquivos do diretorio
Alguém sabe como resolver esse problema ou percorrer o diretorio de dentro do jar?
tente fazer um método que “saia” da estrutura de navegação do seu JAR e pegue o arquivo “em sí”. Depois, vc navega nele usando os métodos da classe JarFile.
(Eu tenho um método que faz isso, mas infelizmente eu não tenho ele aqui , agora).
Se der um System.out.println(resource), qual a saída (se executado da IDE e do JAR)?
if (uri.isOpaque())
throw new IllegalArgumentException("URI is not hierarchical");
http://java.sun.com/javase/6/docs/api/java/net/URI.html#isOpaque()
A Uniform Resource Identifier (URI) is a string of characters that unambiguously identifies a particular resource. To guarantee uniformity, all URIs follow a predefined set of syntax rules, but also maintain extensibility through a separately defined hierarchical naming scheme (e.g. http://).
Such identification enables interaction with representations of the resource over a network, typically the World Wide Web, using specific protocols. Schemes specifying a concrete syntax and associated pro...
Eu já tinha lido isso sobre opaque mas não consegui resolver mesmo assim.
Eu li tambéms obre o scheme que voce colocou o link mas mesmo assim não entendi como vou acessar dentro do jar.
IDE:
file:/D:/softdev/workspace/jse/TD%20Game/bin/resource/images/
Jar:
jar:file:/C:/TDGame.jar!/resource/images/
tente fazer um método que “saia” da estrutura de navegação do seu JAR e pegue o arquivo “em sí”. Depois, vc navega nele usando os métodos da classe JarFile.
(Eu tenho um método que faz isso, mas infelizmente eu não tenho ele aqui , agora).
Pensei em fazer algo assim… mas é que a solução que eu tenho é mais genérica. Mas pelo visto essa é a solução.
Mark, veja essa classe:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class ImageLoader {
public Map<String, InputStream> getAll(File file,
Map<String, InputStream> result) throws IOException {
if (result == null) {
result = new HashMap<String, InputStream>();
}
if (file.isDirectory()) { // é diretório comum; usa recursividade
for (File f : file.listFiles()) {
getAll(f, result);
}
} else if (file.getName().endsWith(".png")) { // é um png; adiciona
result.put(getName(file.getName()), new FileInputStream(file));
} else if (file.getName().endsWith(".jar")) { // é um jar; vamos
// brincar!
JarFile jar = new JarFile(file);
Enumeration<JarEntry> e = jar.entries();
while (e.hasMoreElements()) {
JarEntry entry = e.nextElement();
if (!entry.isDirectory() && entry.getName().endsWith(".png")) {
String path = "jar:file://" + file.getAbsolutePath() + "!/"
+ entry.getName();
URL url = new URL(path);
JarURLConnection jarConn = (JarURLConnection) url
.openConnection();
String name = entry.getName();
result.put(getName(name
.substring(name.lastIndexOf('/') + 1)), jarConn
.getInputStream());
}
}
}
return result;
}
private String getName(String s) {
return s.substring(0, s.lastIndexOf("."));
}
public static void main(String[] args) throws IOException,
URISyntaxException {
ImageLoader il = new ImageLoader();
URLClassLoader urlLoader = (URLClassLoader) ClassLoader
.getSystemClassLoader();
URL[] urls = urlLoader.getURLs();
System.out.println(il.getAll(new File(urls[0].toURI()), null));
}
}
Com pequenas mudanças na sua classe original e usando esses métodos acho que resolve.
O resultado do meu teste foi exatamente o mesmo para a IDE e para o JAR. Como você terá o InputStream de cada arquivo “.png” fica fácil carregá-los via ImageIO.
No seu código creio que ficaria algo como:
URLClassLoader urlLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
URL[] urls = urlLoader.getURLs();
Map<String, InputStream> map = getAll(new File(urls[0].toURI()), null);
for (Entry<String, InputStream> e : map.entrySet()) {
iml.add(new ImageItem(e.getKey(), ImageIO.read(e.getValue())));
}
java.io.FileNotFoundException: \C\TDGame.jar (O caminho da rede nÒo foi encontr
ado)
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.<init>(Unknown Source)
at java.util.jar.JarFile.<init>(Unknown Source)
at java.util.jar.JarFile.<init>(Unknown Source)
at sun.net.www.protocol.jar.URLJarFile.<init>(Unknown Source)
at sun.net.www.protocol.jar.URLJarFile.getJarFile(Unknown Source)
at sun.net.www.protocol.jar.JarFileFactory.get(Unknown Source)
at sun.net.www.protocol.jar.JarURLConnection.connect(Unknown Source)
at sun.net.www.protocol.jar.JarURLConnection.getInputStream(Unknown Sour
ce)
at jgf.imaging.loader.DirLoader.getAll(DirLoader.java:149)
at jgf.imaging.loader.DirLoader.load(DirLoader.java:90)
at jgf.imaging.ImagePallete.reload(ImagePallete.java:102)
at jgf.imaging.ImagePallete.<init>(ImagePallete.java:51)
at td.cfg.GameConfig.<clinit>
Qual linha é a 149 no seu código?
result.put(getName(name
.substring(name.lastIndexOf('/') + 1)), jarConn
.getInputStream());
jarConn.getInputStream
Está retornando isso.
Era para ser:
/* o começo... */name.lastIndexOf(File.separator) // continua...
Esqueci que o separador no Windows é o .
Não… falei besteira. Isso vai resolver o problema do nome, mas não do InputStream.
Antes da linha que dá erro adicione um:
System.out.println(jarConn.getURL());
E poste a saída.
Estou sem tempo agora e resolvi para ele procurar na pasta a partir de onde está o jar. Acredito que agora funcione no linux.
Depois eu vejo isso com mais detalhes por que de qualquer forma eu quero criar um arquivo zipado com as imagens invés do diretorio.
No topico do jogo vou colocar agora essa versao que funciona em linux.
Bom, parece que funciona agora. Mas depois, quanto puder, poste os resultados aqui para tentarmos solucionar.
Mark_Ameba, qual é a estrutura de diretórios dentro do teu jar?
Se a imagem estiver dentro de resource/images, tenta colocar esse parametro src para resource/imagens, sem o / no começo.
Está /resource/images/
Já tentei com:
“resource/images”
“resource/images/”
“/resource/images”
“/resource/images/”
Isso não resolveu o problema. =/
brnfd
Março 31, 2010, 2:10pm
#19
Opa,
meio tarde pra responder mas uma maneira fácil de resolver este problema é usar
ClassLoader.getSystemResourceAsStream("br/com/pacote/arquivo.txt");
Agora é só ler o InputStream.
Abraço
[quote=brnfd]Opa,
meio tarde pra responder mas uma maneira fácil de resolver este problema é usar
ClassLoader.getSystemResourceAsStream("br/com/pacote/arquivo.txt");
Agora é só ler o InputStream.
Abraço[/quote]
O problema não é esse.
Eu consigo pegar arquivos isolados.
O meu problema é conseguir pegar diretorios de dentro do jar para poder percorre-los e ver todos arquivos dentro dele.