make - manifest jar java
Archivo Java Jar: use los errores de recursos: URI no es jerárquico (5)
Además de las respuestas generales, puede obtener "URI no es jerárquico" de la biblioteca de Unitils que intenta cargar un conjunto de datos de un archivo .jar
. Puede suceder cuando mantiene conjuntos de datos en un submódulo de Maven, pero las pruebas reales en otro.
Incluso hay un error UNI-197 archivado.
Implementé 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: el URI is not hierarchical
. Este error no me encuentro cuando se ejecuta en IDE.
Si cambio el código anterior como ayuda en otra publicación 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
//....
}
Aquí hay una solución para desarrolladores 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 utilizar FileLocator.toFileURL(fileURL)
lugar de resolve(fileURL)
, porque cuando el complemento se empaqueta en un resolve(fileURL)
, esto hará que Eclipse cree una versión desempaquetada 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/
No puedes hacer esto
File src = new File(resourceUrl.toURI()); //ERROR HERE
no es un archivo! Cuando se ejecuta desde ide, no tiene ningún error, porque no ejecuta un archivo jar. En las clases IDE y los recursos se extraen en el sistema de archivos.
Pero puede abrir un InputStream
de esta manera:
InputStream in = Model.class.getClassLoader().getResourceAsStream("/data.sav");
Eliminar "/resource"
. En general, los IDE se separan en las clases y recursos del sistema de archivos. Pero cuando se crea el tarro, se juntan todos. Por lo tanto, el nivel de carpeta "/resource"
se usa solo para la separación de clases y recursos.
Cuando obtiene un recurso del cargador de clases, debe especificar la ruta que tiene el recurso dentro del contenedor, que es la jerarquía del paquete real.
Si bien me encontré con este problema, me gustaría agregar otra opción (a la explicación perfecta de @ dash1e):
Exporte el complemento como una carpeta (no como un contenedor) 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.
Si por alguna razón necesita crear un objeto java.io.File
para apuntar a un recurso dentro de un archivo Jar, la respuesta está aquí: https://.com/a/27149287/155167
File f = new File(getClass().getResource("/MyResource").toExternalForm());