Saltar al contenido

¿Cómo obtener la ruta de un archivo JAR en ejecución?

Hemos recabado en todo internet y así brindarte la respuesta para tu dilema, en caso de alguna difcultad deja la duda y responderemos con mucho gusto.

Solución:

return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation()
    .toURI()).getPath();

Reemplace “MyClass” con el nombre de su clase.

Obviamente, esto hará cosas raras si su clase se cargó desde una ubicación que no es un archivo.

La mejor solución para mi:

String path = Test.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(path, "UTF-8");

Esto debería resolver el problema con espacios y caracteres especiales.

Para obtener el File para una dada Class, hay dos pasos:

  1. Convierta el Class a un URL
  2. Convierta el URL a un File

Es importante comprender ambos pasos y no combinarlos.

Una vez que tenga el File, Puedes llamar getParentFile para obtener la carpeta contenedora, si eso es lo que necesita.

Paso 1: Class para URL

Como se discutió en otras respuestas, hay dos formas principales de encontrar un URL relevante para un Class.

  1. URL url = Bar.class.getProtectionDomain().getCodeSource().getLocation();

  2. URL url = Bar.class.getResource(Bar.class.getSimpleName() + ".class");

Ambos tienen pros y contras.

los getProtectionDomain El enfoque produce la ubicación base de la clase (por ejemplo, el archivo JAR que la contiene). Sin embargo, es posible que la política de seguridad del tiempo de ejecución de Java arroje SecurityException al llamar getProtectionDomain(), por lo que si su aplicación necesita ejecutarse en una variedad de entornos, es mejor probar en todos ellos.

los getResource El enfoque produce la ruta completa de recursos de la URL de la clase, desde la cual necesitará realizar más string manipulación. Puede ser un file: camino, pero también podría ser jar:file: o incluso algo más desagradable como bundleresource://346.fwk2106232034:4/foo/Bar.class cuando se ejecuta dentro de un marco OSGi. Por el contrario, el getProtectionDomain enfoque correctamente produce un file: URL incluso desde dentro de OSGi.

Tenga en cuenta que ambos getResource("") y getResource(".") falló en mis pruebas, cuando la clase residía dentro de un archivo JAR; ambas invocaciones regresaron null. Por lo tanto, recomiendo la invocación n. ° 2 que se muestra arriba, ya que parece más segura.

Paso 2: URL para File

De cualquier manera, una vez que tenga un URL, el siguiente paso es convertir a File. Este es su propio desafío; consulte la publicación del blog de Kohsuke Kawaguchi al respecto para obtener detalles completos, pero en resumen, puede usar new File(url.toURI()) siempre que la URL esté completamente formada.

Por último, lo haría altamente desanimado utilizando URLDecoder. Algunos caracteres de la URL, : y / en particular, no son caracteres codificados en URL válidos. Desde el Javadoc URLDecoder:

Se supone que todos los caracteres del código string son uno de los siguientes: “a” a “z”, “A” a “Z”, “0” a “9” y “-“, “_”, “.” y “*”. El carácter “%” está permitido pero se interpreta como el inicio de una secuencia de escape especial.

Hay dos formas posibles en las que este decodificador podría lidiar con cadenas ilegales. Podría dejar los caracteres ilegales en paz o podría lanzar una IllegalArgumentException. El enfoque que adopte el decodificador se deja a la implementación.

En la práctica, URLDecoder generalmente no lanza IllegalArgumentException como se amenazó anteriormente. Y si su ruta de archivo tiene espacios codificados como %20, este enfoque puede parecer que funciona. Sin embargo, si la ruta del archivo tiene otros caracteres no alfabéticos, como + tendrás problemas con URLDecoder alterar la ruta del archivo.

Código de trabajo

Para lograr estos pasos, es posible que tenga métodos como los siguientes:

/**
 * Gets the base location of the given class.
 * 

* If the class is directly on the file system (e.g., * "/path/to/my/package/MyClass.class") then it will return the base directory * (e.g., "file:/path/to"). *

*

* If the class is within a JAR file (e.g., * "/path/to/my-jar.jar!/my/package/MyClass.class") then it will return the * path to the JAR (e.g., "file:/path/to/my-jar.jar"). *

* * @param c The class whose location is desired. * @see FileUtils#urlToFile(URL) to convert the result to a @link File. */ public static URL getLocation(final Class c) if (c == null) return null; // could not load the class // try the easy way first try final URL codeSourceLocation = c.getProtectionDomain().getCodeSource().getLocation(); if (codeSourceLocation != null) return codeSourceLocation; catch (final SecurityException e) // NB: Cannot access protection domain. catch (final NullPointerException e) // NB: Protection domain or code source is null. // NB: The easy way failed, so we try the hard way. We ask for the class // itself as a resource, then strip the class's path from the URL string, // leaving the base path. // get the class's raw resource path final URL classResource = c.getResource(c.getSimpleName() + ".class"); if (classResource == null) return null; // cannot find class resource final String url = classResource.toString(); final String suffix = c.getCanonicalName().replace('.', '/') + ".class"; if (!url.endsWith(suffix)) return null; // weird URL // strip the class's path from the URL string final String base = url.substring(0, url.length() - suffix.length()); String path = base; // remove the "jar:" prefix and "!/" suffix, if present if (path.startsWith("jar:")) path = path.substring(4, path.length() - 2); try return new URL(path); catch (final MalformedURLException e) e.printStackTrace(); return null; /** * Converts the given @link URL to its corresponding @link File. *

* This method is similar to calling @code new File(url.toURI()) except that * it also handles "jar:file:" URLs, returning the path to the JAR file. *

* * @param url The URL to convert. * @return A file path suitable for use with e.g. @link FileInputStream * @throws IllegalArgumentException if the URL does not correspond to a file. */ public static File urlToFile(final URL url) return url == null ? null : urlToFile(url.toString()); /** * Converts the given URL string to its corresponding @link File. * * @param url The URL to convert. * @return A file path suitable for use with e.g. @link FileInputStream * @throws IllegalArgumentException if the URL does not correspond to a file. */ public static File urlToFile(final String url) String path = url; if (path.startsWith("jar:")) // remove "jar:" prefix and "!/" suffix final int index = path.indexOf("!/"); path = path.substring(4, index); try if (PlatformUtils.isWindows() && path.matches("file:[A-Za-z]:.*")) path = "file:/" + path.substring(5); return new File(new URL(path).toURI()); catch (final MalformedURLException e) // NB: URL is not completely well-formed. catch (final URISyntaxException e) // NB: URL is not completely well-formed. if (path.startsWith("file:")) // pass through the URL as-is, minus "file:" prefix path = path.substring(5); return new File(path); throw new IllegalArgumentException("Invalid URL: " + url);

Puede encontrar estos métodos en la biblioteca común de SciJava:

  • org.scijava.util.ClassUtils
  • org.scijava.util.FileUtils.

Si haces scroll puedes encontrar los informes de otros gestores de proyectos, tú igualmente eres capaz mostrar el tuyo si te gusta.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *