Java Jar file: use resource errors: URI no es jerárquico


He implementado mi aplicación en el archivo jar. Cuando necesito copiar datos de un archivo de recursos al exterior del archivo jar, hago este código:

URL resourceUrl = getClass().getResource("/resource/data.sav");
File src = new File(resourceUrl.toURI()); //ERROR HERE
File dst = new File(CurrentPath()+"data.sav");  //CurrentPath: path of jar file don't include jar file name
FileInputStream in = new FileInputStream(src);
FileOutputStream out = new FileOutputStream(dst);
 // some excute code here

El error que he encontrado es: URI is not hierarchical. este error no me encuentro cuando se ejecuta en IDE.

Si cambio el código anterior como algo de ayuda en otro post en StackOverFlow:

InputStream in = Model.class.getClassLoader().getResourceAsStream("/resource/data.sav");
File dst = new File(CurrentPath() + "data.sav");
FileOutputStream out = new FileOutputStream(dst);
//....
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) { //NULL POINTER EXCEPTION
  //....
}
Author: cheffe, 2012-04-13

5 answers

No puedes hacer esto

File src = new File(resourceUrl.toURI()); //ERROR HERE

No es un archivo! Cuando se ejecuta desde el ide no tiene ningún error, porque no se ejecuta un archivo jar. En el IDE se extraen clases y recursos en el sistema de archivos.

Pero puedes abrir un InputStream de esta manera:

    InputStream in = Model.class.getClassLoader().getResourceAsStream("/data.sav");

Eliminar "/resource". Generalmente, los IDEs se separan en clases y recursos del sistema de archivos. Pero cuando se crea el frasco, se juntan todos. Por lo tanto, el nivel de carpeta "/resource" se usa solo para clases y recursos separación.

Cuando obtiene un recurso de classloader, debe especificar la ruta que el recurso tiene dentro del jar, es decir, la jerarquía real del paquete.

 75
Author: dash1e,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-13 16:38:48

Si por alguna razón realmente necesita crear un objeto java.io.File para apuntar a un recurso dentro de un archivo Jar, la respuesta está aquí: https://stackoverflow.com/a/27149287/155167

File f = new File(getClass().getResource("/MyResource").toExternalForm());
 9
Author: Mario,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:15

Aquí hay una solución para desarrolladores de Eclipse RCP / Plugin:

Bundle bundle = Platform.getBundle("resource_from_some_plugin");
URL fileURL = bundle.getEntry("files/test.txt");
File file = null;
try {
   URL resolvedFileURL = FileLocator.toFileURL(fileURL);

   // We need to use the 3-arg constructor of URI in order to properly escape file system chars
   URI resolvedURI = new URI(resolvedFileURL.getProtocol(), resolvedFileURL.getPath(), null);
   File file = new File(resolvedURI);
} catch (URISyntaxException e1) {
    e1.printStackTrace();
} catch (IOException e1) {
    e1.printStackTrace();
}

Es muy importante usar FileLocator.toFileURL(fileURL) en lugar de resolve(fileURL) , porque cuando el complemento se empaqueta en un jar, esto hará que Eclipse cree una versión descomprimida en una ubicación temporal para que se pueda acceder al objeto usando File. Por ejemplo, supongo que Lars Vogel tiene un error en su artículo - http://blog.vogella.com/2010/07/06/reading-resources-from-plugin /

 7
Author: Ilya Buziuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-06 15:19:25

Mientras me topé con este problema, me gustaría agregar otra opción (a la explicación perfecta de @dash1e):

Exporte el plugin como una carpeta (no un jar) agregando:

Eclipse-BundleShape: dir

A su MANIFEST.MF.

Al menos cuando exporta su aplicación RCP con el asistente de exportación (basado en un archivo *.product), esto se respeta y producirá una carpeta.

 0
Author: Jens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-10 16:32:43

Además de las respuestas generales, puede obtener "URI no es jerárquico" de la biblioteca Unitils que intenta cargar un conjunto de datos de un archivo .jar. Puede ocurrir cuando se mantienen conjuntos de datos en un submódulo maven, pero pruebas reales en otro.

Incluso hay un error UNI-197 archivado.

 0
Author: jediz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-12 14:22:31