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


Mi código se ejecuta dentro de un archivo JAR, digamos foo.jar, y necesito saber, en el código, en qué carpeta el foo en ejecución.jar es.

Entonces, si foo.jar está en C:\FOO\, quiero obtener esa ruta sin importar cuál sea mi directorio de trabajo actual.

Author: informatik01, 2008-11-26

29 answers

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

Reemplace "MyClass" con el nombre de su clase

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

 458
Author: Zarkonnen,
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
2018-05-12 21:53:13

La mejor solución para mí:

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.

 177
Author: Fab,
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
2011-10-12 13:12:24

Para obtener el File para un Class dado, hay dos pasos:

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

Es importante entender ambos pasos, y no combinarlos.

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

Paso 1: Class a URL

Como se discutió en otras respuestas, hay dos maneras 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.

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

El enfoque getResource produce la ruta completa del recurso URL de la clase, desde la que tendrá que realizar una manipulación de cadena adicional. Puede ser una ruta file:, 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 framework OSGi. Por el contrario, el enfoque getProtectionDomain produce correctamente una URL file: incluso desde dentro de OSGi.

Tenga en cuenta que tanto getResource("") como getResource(".") fallaron en mis pruebas, cuando la clase residía dentro de un archivo JAR; ambas invocaciones devolvieron null. Así que recomiendo la invocación #2 que se muestra arriba, ya que parece más seguro.

Paso 2: URL a File

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

Por último, yo desaconsejaría usar URLDecoder. Algunos caracteres de la URL, : y / en particular, no son caracteres codificados de URL válidos. Desde el URLDecoder Javadoc:

Se asume que todos los caracteres en la cadena codificada 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 maneras posibles en que este decodificador podría tratar con cadenas ilegales. Podría dejar a los personajes ilegales en paz o podría lanzar un Excepción ilegal. Qué enfoque toma el decodificador se deja a la implementación.

En la práctica, URLDecoder generalmente no lanza IllegalArgumentException como amenazado 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 alfaméricos, como +, tendrá problemas con URLDecoder para modificar la ruta del archivo.

Código de trabajo

Para lograr estos pasos, es posible que tenga métodos como lo siguiente:

/**
 * Gets the base location of the given class.
 * <p>
 * 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").
 * </p>
 * <p>
 * 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").
 * </p>
 *
 * @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}.
 * <p>
 * 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.
 * </p>
 * 
 * @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);
}

Puedes encontrar estos métodos en la biblioteca SciJava Common :

 138
Author: ctrueden,
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-02-28 19:31:56

También puedes usar:

CodeSource codeSource = YourMainClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
String jarDir = jarFile.getParentFile().getPath();
 47
Author: Benny Neugebauer,
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-07-04 22:49:54

Utilice ClassLoader.getResource () para encontrar la URL de tu clase actual.

Por ejemplo:

package foo;

public class Test
{
    public static void main(String[] args)
    {
        ClassLoader loader = Test.class.getClassLoader();
        System.out.println(loader.getResource("foo/Test.class"));
    }
}

(Este ejemplo tomado de una pregunta similar.)

Para encontrar el directorio, tendrás que desmontar la URL manualmente. Vea el tutorial JarClassLoader para el formato de una URL jar.

 23
Author: Jon Skeet,
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 11:33:26

Me sorprende ver que ninguno propuso recientemente usar Path. Aquí sigue una cita: " La clase Path incluye varios métodos que se pueden usar para obtener información sobre la ruta, acceder a elementos de la ruta, convertir la ruta a otras formas o extraer partes de una ruta "

Por lo tanto, una buena alternativa es obtener el Path objeto como:

Path path = Paths.get(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI());
 16
Author: mat_boy,
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
2013-08-28 12:53:00

La única solución que funciona para mí en Linux, Mac y Windows:

public static String getJarContainingFolder(Class aclass) throws Exception {
  CodeSource codeSource = aclass.getProtectionDomain().getCodeSource();

  File jarFile;

  if (codeSource.getLocation() != null) {
    jarFile = new File(codeSource.getLocation().toURI());
  }
  else {
    String path = aclass.getResource(aclass.getSimpleName() + ".class").getPath();
    String jarFilePath = path.substring(path.indexOf(":") + 1, path.indexOf("!"));
    jarFilePath = URLDecoder.decode(jarFilePath, "UTF-8");
    jarFile = new File(jarFilePath);
  }
  return jarFile.getParentFile().getAbsolutePath();
}
 13
Author: Dmitry Trofimov,
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
2013-08-20 17:41:55

Tuve el mismo problema y lo resolví de esa manera:

File currentJavaJarFile = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().getPath());   
String currentJavaJarFilePath = currentJavaJarFile.getAbsolutePath();
String currentRootDirectoryPath = currentJavaJarFilePath.replace(currentJavaJarFile.getName(), "");

Espero haber sido de ayuda para ti.

 6
Author: Charlie,
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
2013-06-12 07:33:36

Aquí está la actualización a otros comentarios, que me parecen incompletos para los detalles de

Usando una "carpeta" relativa fuera .archivo jar (en el mismo jar ubicación):

String path = 
  YourMainClassName.class.getProtectionDomain().
  getCodeSource().getLocation().getPath();

path = 
  URLDecoder.decode(
    path, 
    "UTF-8");

BufferedImage img = 
  ImageIO.read(
    new File((
        new File(path).getParentFile().getPath()) +  
        File.separator + 
        "folder" + 
        File.separator + 
        "yourfile.jpg"));
 6
Author: Zon,
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
2015-12-05 16:43:38

La respuesta seleccionada anteriormente no funciona si ejecuta su jar haciendo clic en él desde el entorno de escritorio Gnome (no desde ningún script o terminal).

En cambio, me gusta que la siguiente solución esté funcionando en todas partes:

    try {
        return URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
    } catch (UnsupportedEncodingException e) {
        return "";
    }
 5
Author: lviggiani,
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
2011-09-28 08:18:58

Para obtener la ruta de ejecución del archivo jar he estudiado las soluciones anteriores y probado todos los métodos que existen alguna diferencia entre sí. Si este código se está ejecutando en Eclipse IDE, todos deberían poder encontrar la ruta del archivo, incluida la clase indicada, y abrir o crear un archivo indicado con la ruta encontrada.

Pero es complicado, cuando se ejecuta el archivo jar ejecutable directamente o a través de la línea de comandos, fallará como la ruta del archivo jar obtenida de los métodos anteriores dará una ruta interna en el archivo jar, es decir, siempre da una ruta como

Rsrc: project-name (tal vez debería decir que es el nombre del paquete del archivo de clase principal - la clase indicada)

No puedo convertir el rsrc:... ruta a una ruta externa, es decir, cuando se ejecuta el archivo jar fuera del IDE de Eclipse no se puede obtener la ruta del archivo jar.

La única forma posible de obtener la ruta de acceso del archivo jar fuera del IDE de Eclipse es

System.getProperty("java.class.path")

Esta línea de código puede devuelve la ruta viva (incluido el nombre del archivo) del archivo jar en ejecución (tenga en cuenta que la ruta de retorno no es el directorio de trabajo), ya que el documento java y algunas personas dijeron que devolverá las rutas de todos los archivos de clase en el mismo directorio, pero como mis pruebas si en el mismo directorio incluyen muchos archivos jar, solo devolverá la ruta de jar en ejecución (sobre el problema de múltiples rutas de hecho sucedió en el Eclipse).

 5
Author: phchen2,
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-05-11 12:00:41

En realidad aquí hay una versión mejor - la antigua fallaba si el nombre de una carpeta tenía un espacio en ella.

  private String getJarFolder() {
    // get name and path
    String name = getClass().getName().replace('.', '/');
    name = getClass().getResource("/" + name + ".class").toString();
    // remove junk
    name = name.substring(0, name.indexOf(".jar"));
    name = name.substring(name.lastIndexOf(':')-1, name.lastIndexOf('/')+1).replace('%', ' ');
    // remove escape characters
    String s = "";
    for (int k=0; k<name.length(); k++) {
      s += name.charAt(k);
      if (name.charAt(k) == ' ') k += 2;
    }
    // replace '/' with system separator char
    return s.replace('/', File.separatorChar);
  }

En cuanto a fallar con los applets, normalmente no tendría acceso a los archivos locales de todos modos. No se mucho acerca de JWS, pero para manejar archivos locales podría no ser posible descargar la aplicación.?

 3
Author: bacup lad,
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
2011-04-15 16:43:29
String path = getClass().getResource("").getPath();

La ruta siempre se refiere al recurso dentro del archivo jar.

 3
Author: ZZZ,
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
2011-09-18 06:14:21

La solución más sencilla es pasar la ruta como argumento al ejecutar el jar.

Puede automatizar esto con un script de shell (.bat en Windows,. sh en cualquier otro lugar):

java -jar my-jar.jar .

Usé . para pasar el directorio de trabajo actual.

UPDATE

Es posible que desee pegar el archivo jar en un subdirectorio para que los usuarios no hagan clic accidentalmente en él. Su código también debe comprobar para asegurarse de que los argumentos de la línea de comandos se han proporcionado, y proporcionar un buen error mensaje si faltan los argumentos.

 3
Author: Max Heiber,
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-03-30 19:50:38

Otras respuestas parecen apuntar a la fuente de código que es la ubicación del archivo Jar que no es un directorio.

Use

return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile();
 3
Author: F.O.O,
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-06-10 11:57:39

Tuve que perder mucho tiempo antes de encontrar finalmente una solución de trabajo (y corta).
Es posible que el jarLocation viene con un prefijo como file:\ o jar:file\, que se puede eliminar usando String#substring().

URL jarLocationUrl = MyClass.class.getProtectionDomain().getCodeSource().getLocation();
String jarLocation = new File(jarLocationUrl.toString()).getParent();
 3
Author: Jelle,
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-08-30 13:58:45
public static String dir() throws URISyntaxException
{
    URI path=Main.class.getProtectionDomain().getCodeSource().getLocation().toURI();
    String name= Main.class.getPackage().getName()+".jar";
    String path2 = path.getRawPath();
    path2=path2.substring(1);

    if (path2.contains(".jar"))
    {
        path2=path2.replace(name, "");
    }
    return path2;}

Funciona bien en Windows

 2
Author: Denton,
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
2013-04-05 10:09:48

Traté de obtener la ruta de ejecución jar usando

String folder = MyClassName.class.getProtectionDomain().getCodeSource().getLocation().getPath();

c:\app>aplicación java-jar.jar

Ejecutando la aplicación jar llamada " aplicación.jar", en Windows en la carpeta " c:\app", el valor de la variable de cadena "folder" era " \c:\app\application.jar " y tuve problemas para probar la corrección de path

File test = new File(folder);
if(file.isDirectory() && file.canRead()) { //always false }

Así que traté de definir "prueba" como:

String fold= new File(folder).getParentFile().getPath()
File test = new File(fold);

Para obtener la ruta en un formato correcto como " c:\app " en lugar de "\c:\app\application.jar " y me di cuenta de que funciona.

 2
Author: TheGreatPsychoticBunny,
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-02-21 15:23:28

Algo que es frustrante es que cuando se está desarrollando en Eclipse MyClass.class.getProtectionDomain().getCodeSource().getLocation() devuelve el directorio /bin que es genial, pero cuando se compila en un jar, la ruta incluye la parte /myjarname.jar que le da nombres de archivo ilegales.

Para que el código funcione tanto en el ide como una vez compilado en un jar, utilizo la siguiente pieza de código:

URL applicationRootPathURL = getClass().getProtectionDomain().getCodeSource().getLocation();
File applicationRootPath = new File(applicationRootPathURL.getPath());
File myFile;
if(applicationRootPath.isDirectory()){
    myFile = new File(applicationRootPath, "filename");
}
else{
    myFile = new File(applicationRootPath.getParentFile(), "filename");
}
 1
Author: Alexander,
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
2015-12-14 06:34:54

No estoy muy seguro de los demás, pero en mi caso no funcionó con un "jar ejecutable" y lo conseguí arreglando códigos juntos de la respuesta phchen2 y otro de este enlace : ¿Cómo obtener la ruta de un archivo JAR en ejecución? El código:

               String path=new java.io.File(Server.class.getProtectionDomain()
                .getCodeSource()
                .getLocation()
                .getPath())
          .getAbsolutePath();
       path=path.substring(0, path.lastIndexOf("."));
       path=path+System.getProperty("java.class.path");
 1
Author: Fahad Alkamli,
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:34:59

Este método, llamado desde el código en el archivo, devuelve la carpeta donde el.el archivo jar lo es. Debería funcionar en Windows o Unix.


  private String getJarFolder() {
    String name = this.getClass().getName().replace('.', '/');
    String s = this.getClass().getResource("/" + name + ".class").toString();
    s = s.replace('/', File.separatorChar);
    s = s.substring(0, s.indexOf(".jar")+4);
    s = s.substring(s.lastIndexOf(':')-1);
    return s.substring(0, s.lastIndexOf(File.separatorChar)+1);
  } 

Derivado del código en: Determinar si se ejecuta desde JAR

 0
Author: Bacup Lad,
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-06-19 13:10:19

Mencione que solo está comprobado en Windows pero creo que funciona perfectamente en otros sistemas operativos[Linux,MacOs,Solaris] :).


Yo tenía 2 .jar archivos en el mismo directorio . Quería que desde un archivo .jar se iniciara el otro archivo .jar que está en el mismo directorio.

El problema es que cuando se inicia desde el cmd el directorio actual es system32.


Advertencias!

  • Lo siguiente parece funcionar bastante bien en todas las pruebas que he hecho, incluso con nombre de carpeta ;][[;'57f2g34g87-8+9-09!2#@!$%^^&() o ()%&$%^@# funciona bien.
  • Estoy usando el ProcessBuilder con lo siguiente:

..

//The class from which i called this was the class `Main`
String path = getBasePathForClass(Main.class);
String applicationPath=  new File(path + "application.jar").getAbsolutePath();


System.out.println("Directory Path is : "+applicationPath);

//Your know try catch here
//Mention that sometimes it doesn't work for example with folder `;][[;'57f2g34g87-8+9-09!2#@!$%^^&()` 
ProcessBuilder builder = new ProcessBuilder("java", "-jar", applicationPath);
builder.redirectErrorStream(true);
Process process = builder.start();

//...code

getBasePathForClass(Class<?> classs):

    /**
     * Returns the absolute path of the current directory in which the given
     * class
     * file is.
     * 
     * @param classs
     * @return The absolute path of the current directory in which the class
     *         file is.
     * @author GOXR3PLUS[StackOverFlow user] + bachden [StackOverFlow user]
     */
    public static final String getBasePathForClass(Class<?> classs) {

        // Local variables
        File file;
        String basePath = "";
        boolean failed = false;

        // Let's give a first try
        try {
            file = new File(classs.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());

            if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
                basePath = file.getParent();
            } else {
                basePath = file.getPath();
            }
        } catch (URISyntaxException ex) {
            failed = true;
            Logger.getLogger(classs.getName()).log(Level.WARNING,
                    "Cannot firgue out base path for class with way (1): ", ex);
        }

        // The above failed?
        if (failed) {
            try {
                file = new File(classs.getClassLoader().getResource("").toURI().getPath());
                basePath = file.getAbsolutePath();

                // the below is for testing purposes...
                // starts with File.separator?
                // String l = local.replaceFirst("[" + File.separator +
                // "/\\\\]", "")
            } catch (URISyntaxException ex) {
                Logger.getLogger(classs.getName()).log(Level.WARNING,
                        "Cannot firgue out base path for class with way (2): ", ex);
            }
        }

        // fix to run inside eclipse
        if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
                || basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
            basePath = basePath.substring(0, basePath.length() - 4);
        }
        // fix to run inside netbeans
        if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
            basePath = basePath.substring(0, basePath.length() - 14);
        }
        // end fix
        if (!basePath.endsWith(File.separator)) {
            basePath = basePath + File.separator;
        }
        return basePath;
    }
 0
Author: GOXR3PLUS,
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-19 13:12:36

Este código funcionó para mí:

private static String getJarPath() throws IOException, URISyntaxException {
    File f = new File(LicensingApp.class.getProtectionDomain().().getLocation().toURI());
    String jarPath = f.getCanonicalPath().toString();
    String jarDir = jarPath.substring( 0, jarPath.lastIndexOf( File.separator ));
    return jarDir;
  }
 0
Author: John Lockwood,
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-09-08 11:58:34

Ignore backup lad answer, puede parecer correcto a veces pero tiene varios problemas:

Aquí ambos deben ser +1 no -1:

name = name.substring(name.lastIndexOf(':')-1, name.lastIndexOf('/')+1).replace('%', ' ');

Muy peligroso porque no es inmediatamente evidente si el camino no tiene espacios en blanco, pero reemplazar solo el "%" te dejará con un montón de 20 en cada espacio en blanco:

name = name.substring(name.lastIndexOf(':')-1, name.lastIndexOf('/')+1).replace('%', ' ');

Hay mejores maneras que ese bucle para los espacios en blanco.

También causará problemas en el momento de la depuración.

 -1
Author: rciafardone,
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
2011-04-28 01:51:21

Escribo en Java 7, y pruebo en Windows 7 con el tiempo de ejecución de Oracle, y Ubuntu con el tiempo de ejecución de código abierto. Esto funciona perfecto para esos sistemas:

La ruta para el directorio padre de cualquier archivo jar en ejecución (suponiendo que la clase que llama a este código es un hijo directo del propio archivo jar):

try {
    fooDir = new File(this.getClass().getClassLoader().getResource("").toURI());
} catch (URISyntaxException e) {
    //may be sloppy, but don't really need anything here
}
fooDirPath = fooDir.toString(); // converts abstract (absolute) path to a String

Entonces, el camino de foo.jar sería:

fooPath = fooDirPath + File.separator + "foo.jar";

Nuevamente, esto no se probó en ningún Mac o Windows anterior

 -1
Author: sudoBen,
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-03 23:54:53

El enfoque getProtectionDomain puede no funcionar a veces, por ejemplo, cuando tiene que encontrar el jar para algunas de las clases java principales (por ejemplo, en mi caso, la clase StringBuilder dentro de IBM JDK), sin embargo, lo siguiente funciona sin problemas:

public static void main(String[] args) {
    System.out.println(findSource(MyClass.class));
    // OR
    System.out.println(findSource(String.class));
}

public static String findSource(Class<?> clazz) {
    String resourceToSearch = '/' + clazz.getName().replace(".", "/") + ".class";
    java.net.URL location = clazz.getResource(resourceToSearch);
    String sourcePath = location.getPath();
    // Optional, Remove junk
    return sourcePath.replace("file:", "").replace("!" + resourceToSearch, "");
}
 -1
Author: Vasu,
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
2015-05-14 18:10:30

Tengo otra forma de obtener la ubicación de la cadena de una clase.

URL path = Thread.currentThread().getContextClassLoader().getResource("");
Path p = Paths.get(path.toURI());
String location = p.toString();

La cadena de salida tendrá la forma de

C:\Users\Administrator\new Workspace\...

Los espacios y otros caracteres se manejan, y en la forma sin file:/. Así será más fácil de usar.

 -1
Author: NoSegfault,
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
2015-05-21 18:41:50

O puedes pasar throw el Hilo actual así:

String myPath = Thread.currentThread().getContextClassLoader().getResource("filename").getPath();
 -1
Author: Assem BARDI,
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
2015-09-23 12:38:40

Este liner funciona para carpetas que contienen espacios o caracteres especiales (como ç o õ). La pregunta original pide la ruta absoluta (dir de trabajo), sin el archivo JAR en sí. Probado aquí con Java7 en Windows7:

String workingDir = System.getProperty("user.dir");

Referencia: http://www.mkyong.com/java/how-to-get-the-current-working-directory-in-java/

 -2
Author: Rodrigo N. Hernandez,
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
2015-04-16 20:37:37