如何获得运行JAR文件的路径?

时间:2023-01-13 12:59:35

My code runs inside a JAR file, say foo.jar, and I need to know, in the code, in which folder the running foo.jar is.

我的代码运行在一个JAR文件中,比如foo。jar,我需要知道,在代码中,在哪个文件夹中运行foo。jar。

So, if foo.jar is in C:\FOO\, I want to get that path no matter what my current working directory is.

所以,如果foo。jar在C:\FOO\,无论我当前的工作目录是什么,我都希望得到那条路径。

29 个解决方案

#1


434  

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

Obviously, this will do odd things if your class was loaded from a non-file location.

显然,如果您的类是从非文件位置加载的,这将会做一些奇怪的事情。

#2


172  

Best solution for me:

对我来说最好的解决方案:

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

This should solve the problem with spaces and special characters.

这将解决空间和特殊字符的问题。

#3


130  

To obtain the File for a given Class, there are two steps:

要获取给定类的文件,有两个步骤:

  1. Convert the Class to a URL
  2. 将类转换为URL。
  3. Convert the URL to a File
  4. 将URL转换为文件。

It is important to understand both steps, and not conflate them.

理解这两个步骤是很重要的,不要把它们混为一谈。

Once you have the File, you can call getParentFile to get the containing folder, if that is what you need.

一旦您有了这个文件,您就可以调用getParentFile来获取包含的文件夹,如果您需要的话。

Step 1: Class to URL

As discussed in other answers, there are two major ways to find a URL relevant to a Class.

正如在其他答案中所讨论的,找到一个与类相关的URL有两种主要方法。

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

    .getLocation .getCodeSource网址URL = Bar.class.getProtectionDomain()()();

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

    URL = Bar.class.getResource(Bar.class.getSimpleName() +“.class”);

Both have pros and cons.

两者都有利有弊。

The getProtectionDomain approach yields the base location of the class (e.g., the containing JAR file). However, it is possible that the Java runtime's security policy will throw SecurityException when calling getProtectionDomain(), so if your application needs to run in a variety of environments, it is best to test in all of them.

getProtectionDomain方法生成类的基本位置(例如,包含JAR文件)。然而,当调用getProtectionDomain()时,Java运行时的安全策略可能会抛出SecurityException,因此,如果您的应用程序需要在各种环境中运行,那么最好在所有环境中进行测试。

The getResource approach yields the full URL resource path of the class, from which you will need to perform additional string manipulation. It may be a file: path, but it could also be jar:file: or even something nastier like bundleresource://346.fwk2106232034:4/foo/Bar.class when executing within an OSGi framework. Conversely, the getProtectionDomain approach correctly yields a file: URL even from within OSGi.

getResource方法生成类的完整URL资源路径,您将需要执行额外的字符串操作。它可能是一个文件:path,但它也可能是jar:文件:或者甚至更像bundleresource://346.fwk2106232034:4/foo/Bar。在OSGi框架中执行的类。相反,getProtectionDomain方法可以正确地生成一个文件:甚至来自OSGi内部的URL。

Note that both getResource("") and getResource(".") failed in my tests, when the class resided within a JAR file; both invocations returned null. So I recommend the #2 invocation shown above instead, as it seems safer.

注意,getResource(“”)和getResource(“。”)在我的测试中失败,当类在一个JAR文件中保存;这两个调用返回null。因此,我推荐上面显示的#2调用,因为它看起来更安全。

Step 2: URL to File

Either way, once you have a URL, the next step is convert to a File. This is its own challenge; see Kohsuke Kawaguchi's blog post about it for full details, but in short, you can use new File(url.toURI()) as long as the URL is completely well-formed.

无论哪种方式,一旦有了URL,下一步就是将其转换为文件。这是它自己的挑战;请参阅Kohsuke Kawaguchi的博客文章,了解详细信息,但简短地说,只要URL完全正确,您就可以使用新文件(URL . touri())。

Lastly, I would highly discourage using URLDecoder. Some characters of the URL, : and / in particular, are not valid URL-encoded characters. From the URLDecoder Javadoc:

最后,我强烈反对使用URLDecoder。URL的某些字符:特别是,不是有效的URL编码字符。从URLDecoder Javadoc:

It is assumed that all characters in the encoded string are one of the following: "a" through "z", "A" through "Z", "0" through "9", and "-", "_", ".", and "*". The character "%" is allowed but is interpreted as the start of a special escaped sequence.

它假定编码字符串中的所有字符都是以下的一个:“a”通过“z”,“a”通过“z”,“0”通过“9”,“-”,“_”,“。”、“*”。字符“%”是允许的,但是被解释为一个特殊转义序列的开始。

...

There are two possible ways in which this decoder could deal with illegal strings. It could either leave illegal characters alone or it could throw an IllegalArgumentException. Which approach the decoder takes is left to the implementation.

这个解码器可能有两种处理非法字符串的方法。它可以单独留下非法字符,也可以抛出非法的异常。解码器采用的方法是留给实现的。

In practice, URLDecoder generally does not throw IllegalArgumentException as threatened above. And if your file path has spaces encoded as %20, this approach may appear to work. However, if your file path has other non-alphameric characters such as + you will have problems with URLDecoder mangling your file path.

在实践中,URLDecoder一般不会抛出IllegalArgumentException作为威胁。如果您的文件路径被编码为%20,那么这种方法可能会起作用。但是,如果您的文件路径中有其他非字母的字符,例如+,那么您将会遇到与URLDecoder混淆文件路径的问题。

Working code

To achieve these steps, you might have methods like the following:

为了实现这些步骤,您可能有如下方法:

/**
 * 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);
}

You can find these methods in the SciJava Common library:

您可以在SciJava公共库中找到这些方法:

#4


43  

You can also use:

您还可以使用:

CodeSource codeSource = YourMainClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
String jarDir = jarFile.getParentFile().getPath();

#5


23  

Use ClassLoader.getResource() to find the URL for your current class.

使用ClassLoader.getResource()查找当前类的URL。

For example:

例如:

package foo;

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

(This example taken from a similar question.)

(这个例子取自一个类似的问题。)

To find the directory, you'd then need to take apart the URL manually. See the JarClassLoader tutorial for the format of a jar URL.

要找到该目录,您需要手动将URL拆开。有关jar URL的格式,请参阅JarClassLoader教程。

#6


15  

I'm surprised to see that none recently proposed to use Path. Here follows a citation: "The Path class includes various methods that can be used to obtain information about the path, access elements of the path, convert the path to other forms, or extract portions of a path"

我很惊讶地发现,最近没有人建议使用Path。引用如下:“Path类包含了各种方法,可用于获取关于路径的信息、路径的访问元素、将路径转换为其他形式或提取路径的部分”。

Thus, a good alternative is to get the Path objest as:

因此,一个好的替代方法是:

Path path = Paths.get(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI());

#7


12  

The only solution that works for me on Linux, Mac and Windows:

在Linux、Mac和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();
}

#8


6  

I had the the same problem and I solved it that way:

我遇到了同样的问题,我解决了这个问题:

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

I hope I was of help to you.

我希望我对你有帮助。

#9


6  

Here's upgrade to other comments, that seem to me incomplete for the specifics of

这里是对其他评论的升级,这对我来说是不完整的。

using a relative "folder" outside .jar file (in the jar's same location):

使用一个相对的“文件夹”在.jar文件(在jar的相同位置):

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"));

#10


5  

the selected answer above is not working if you run your jar by click on it from Gnome desktop environment (not from any script or terminal).

如果您通过单击Gnome桌面环境(而不是来自任何脚本或终端)来运行您的jar,那么上面所选的答案不会起作用。

Instead, I have fond that the following solution is working everywhere:

相反,我喜欢以下的解决方案:

    try {
        return URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
    } catch (UnsupportedEncodingException e) {
        return "";
    }

#11


5  

For getting the path of running jar file I have studied the above solutions and tried all methods which exist some difference each other. If these code are running in Eclipse IDE they all should be able to find the path of the file including the indicated class and open or create an indicated file with the found path.

为了获得运行jar文件的路径,我研究了以上的解决方案,并尝试了所有的方法,它们之间存在一些差异。如果这些代码在Eclipse IDE中运行,那么它们都应该能够找到文件的路径,包括指定的类,并打开或创建带有找到路径的指定文件。

But it is tricky, when run the runnable jar file directly or through the command line, it will be failed as the path of jar file gotten from the above methods will give an internal path in the jar file, that is it always gives a path as

但是,如果直接或通过命令行运行runnable jar文件,它将会失败,因为从上面的方法获得的jar文件路径将在jar文件中给出一个内部路径,这就是它总是给出一条路径。

rsrc:project-name (maybe I should say that it is the package name of the main class file - the indicated class)

rsrc:项目名称(也许我应该说它是主类文件的包名——指示类)

I can not convert the rsrc:... path to an external path, that is when run the jar file outside the Eclipse IDE it can not get the path of jar file.

我不能转换rsrc:…路径到外部路径,即在Eclipse IDE之外运行jar文件时,它无法获得jar文件的路径。

The only possible way for getting the path of running jar file outside Eclipse IDE is

在Eclipse IDE之外获得运行jar文件的路径的惟一方法是。

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

this code line may return the living path (including the file name) of the running jar file (note that the return path is not the working directory), as the java document and some people said that it will return the paths of all class files in the same directory, but as my tests if in the same directory include many jar files, it only return the path of running jar (about the multiple paths issue indeed it happened in the Eclipse).

这段代码行可能返回的生活路径(包括文件名)运行jar文件(注意,返回路径不是工作目录),作为java文档,有些人说,它将返回所有类文件在同一个目录的路径,但随着我的测试中,如果在相同的目录中包括许多jar文件,它只返回运行jar的路径(约多条路径问题确实发生在Eclipse)。

#12


3  

Actually here is a better version - the old one failed if a folder name had a space in it.

实际上,这里有一个更好的版本——如果文件夹名有一个空格,旧的版本就失败了。

  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);
  }

As for failing with applets, you wouldn't usually have access to local files anyway. I don't know much about JWS but to handle local files might it not be possible to download the app.?

对于applet的失败,您通常无法访问本地文件。我不太了解JWS,但是处理本地文件可能不可能下载这个应用程序。

#13


3  

String path = getClass().getResource("").getPath();

The path always refers to the resource within the jar file.

路径总是引用jar文件中的资源。

#14


3  

The simplest solution is to pass the path as an argument when running the jar.

最简单的解决方案是在运行jar时将路径作为参数传递。

You can automate this with a shell script (.bat in Windows, .sh anywhere else):

您可以使用shell脚本(。蝙蝠在窗户,.sh在其他地方):

java -jar my-jar.jar .

I used . to pass the current working directory.

我使用。以传递当前工作目录。

UPDATE

更新

You may want to stick the jar file in a sub-directory so users don't accidentally click it. Your code should also check to make sure that the command line arguments have been supplied, and provide a good error message if the arguments are missing.

您可能希望将jar文件保存在子目录中,这样用户就不会不小心点击它。您的代码还应该检查是否提供了命令行参数,如果缺少参数,则提供一个好的错误消息。

#15


3  

Other answers seem to point to the code source which is Jar file location which is not a directory.

其他答案似乎指向代码源,它是Jar文件位置,而不是目录。

Use

使用

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

#16


3  

I had to mess around a lot before I finally found a working (and short) solution.
It is possible that the jarLocation comes with a prefix like file:\ or jar:file\, which can be removed by using String#substring().

在我最终找到一个有效的解决方案之前,我不得不到处乱搞。jarLocation可能带有一个类似于文件的前缀:\或jar:file\,可以使用String#substring()来删除它。

URL jarLocationUrl = MyClass.class.getProtectionDomain().getCodeSource().getLocation();
String jarLocation = new File(jarLocationUrl.toString()).getParent();

#17


2  

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;}

Works good on Windows

Windows上的好工作

#18


2  

I tried to get the jar running path using

我试图让jar运行路径使用。

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

c:\app>java -jar application.jar

c:\ app > java jar application.jar

Running the jar application named "application.jar", on Windows in the folder "c:\app", the value of the String variable "folder" was "\c:\app\application.jar" and I had problems testing for path's correctness

运行名为“应用程序”的jar应用程序。在“c:\app”文件夹的Windows上,字符串变量“文件夹”的值为“\c:\app\应用程序”。我在测试路径的正确性时遇到了问题。

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

So I tried to define "test" as:

所以我试着把“测试”定义为:

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

to get path in a right format like "c:\app" instead of "\c:\app\application.jar" and I noticed that it work.

以“c:\app”而不是“\c:\app\应用程序”这样的正确格式获取路径。我注意到它起作用了。

#19


1  

Something that is frustrating is that when you are developing in Eclipse MyClass.class.getProtectionDomain().getCodeSource().getLocation() returns the /bin directory which is great, but when you compile it to a jar, the path includes the /myjarname.jar part which gives you illegal file names.

令人沮丧的是,当您在Eclipse MyClass.class.getProtectionDomain()中开发时,getcodesource (). getlocation()返回/bin目录很好,但是当您将它编译到一个jar时,路径包括/myjarname。jar部分,它给你非法的文件名。

To have the code work both in the ide and once it is compiled to a jar, I use the following piece of code:

为了让代码在ide中同时工作,并且一旦它被编译成一个jar,我使用下面的代码:

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");
}

#20


1  

Not really sure about the others but in my case it didn't work with a "Runnable jar" and i got it working by fixing codes together from phchen2 answer and another from this link :How to get the path of a running JAR file? The code:

不太确定其他的,但是在我的例子中,它没有使用一个“可运行的jar”,并且我通过从phchen2的答案和这个链接的另一个链接中修复代码来工作:如何获得一个运行的jar文件的路径?代码:

               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");

#21


0  

Mention that it is checked only in Windows but i think it works perfect on other Operating Systems [Linux,MacOs,Solaris] :).

提到它只在Windows中进行检查,但我认为它在其他操作系统(Linux、MacOs、Solaris)上是完美的。


I had 2 .jar files in the same directory . I wanted from the one .jar file to start the other .jar file which is in the same directory.

我在同一个目录中有两个.jar文件。我希望从一个.jar文件开始另一个.jar文件,它在同一个目录中。

The problem is that when you start it from the cmd the current directory is system32.

问题是,当从cmd开始时,当前目录是system32。


Warnings!

警告!

  • The below seems to work pretty well in all the test i have done even with folder name ;][[;'57f2g34g87-8+9-09!2#@!$%^^&() or ()%&$%^@# it works well.
  • 下面能够出色地执行所有的测试我即使文件夹名称;][[,“57 f2g34g87-8 + 9-09 ! 2 # @ ! $ % ^ ^ &()或()% & $ % ^ @ #它好用。
  • I am using the ProcessBuilder with the below as following:
  • 我正在使用以下的ProcessBuilder:

????..

????..

//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):

????getBasePathForClass(Class 、):

    /**
     * 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[* user] + bachden [* 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;
    }

#22


0  

This code worked for me:

这段代码为我工作:

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;
  }

#23


-1  

Ignore backup lad answer, it may look ok sometimes but has several problems:

忽略后备孩子的回答,有时看起来不错,但有几个问题:

here both should be +1 not -1:

这里两者都应该是+1而不是-1:

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

Very dangerous because is not immediately evident if the path has no white spaces, but replacing just the "%" will leave you with a bunch of 20 in each white space:

非常危险,因为如果路径没有空格,就不明显了,但是只替换“%”会让你在每个空格中有20个字节:

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

There are better ways than that loop for the white spaces.

对于空白区域,有更好的方法。

Also it will cause problems at debugging time.

同时也会在调试时间造成问题。

#24


-1  

This method, called from code in the archive, returns the folder where the .jar file is. It should work in either Windows or Unix.

这个方法,从归档的代码中调用,返回.jar文件所在的文件夹。它应该在Windows或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);
  } 

Derived from code at: Determine if running from JAR

从代码中派生出来的:确定是否从JAR运行。

#25


-1  

I write in Java 7, and test in Windows 7 with Oracle's runtime, and Ubuntu with the open source runtime. This works perfect for those systems:

我在Java 7中编写,在Windows 7中使用Oracle的运行时进行测试,而Ubuntu则使用开源运行时。这对那些系统非常适用:

The path for the parent directory of any running jar file (assuming the class calling this code is a direct child of the jar archive itself):

任何运行jar文件的父目录的路径(假设这个类调用此代码是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

So, the path of foo.jar would be:

所以,foo的路径。jar将:

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

Again, this wasn't tested on any Mac or older Windows

同样,这在任何Mac或旧的Windows上都没有测试过。

#26


-1  

The getProtectionDomain approach might not work sometimes e.g. when you have to find the jar for some of the core java classes (e.g in my case StringBuilder class within IBM JDK), however following works seamlessly:

有时,当您必须为一些核心java类找到jar时,getProtectionDomain方法可能不会起作用。在我的案例中,在IBM JDK中使用StringBuilder类),但是以下工作是无缝的:

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, "");
}

#27


-1  

I have another way to get the String location of a class.

我有另一种方法来获取类的字符串位置。

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

The output String will have the form of

输出字符串的形式为。

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

The spaces and other characters are handled, and in the form without file:/. So will be easier to use.

空格和其他字符被处理,并且在表单中没有文件:/。这样更容易使用。

#28


-1  

Or you can pass throw the current Thread like this :

或者你也可以像这样通过抛出当前线程:

String myPath = Thread.currentThread().getContextClassLoader().getResource("filename").getPath();

#29


-2  

This one liner works for folders containing spaces or special characters (like ç or õ). The original question asks for the absolute path (working dir), without the JAR file itself. Tested in here with Java7 on Windows7:

这一行程序适用于包含空格或特殊字符(如c或o)的文件夹。原始问题要求绝对路径(工作目录),没有JAR文件本身。在这里用Java7在Windows7上测试:

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

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

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

#1


434  

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

Obviously, this will do odd things if your class was loaded from a non-file location.

显然,如果您的类是从非文件位置加载的,这将会做一些奇怪的事情。

#2


172  

Best solution for me:

对我来说最好的解决方案:

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

This should solve the problem with spaces and special characters.

这将解决空间和特殊字符的问题。

#3


130  

To obtain the File for a given Class, there are two steps:

要获取给定类的文件,有两个步骤:

  1. Convert the Class to a URL
  2. 将类转换为URL。
  3. Convert the URL to a File
  4. 将URL转换为文件。

It is important to understand both steps, and not conflate them.

理解这两个步骤是很重要的,不要把它们混为一谈。

Once you have the File, you can call getParentFile to get the containing folder, if that is what you need.

一旦您有了这个文件,您就可以调用getParentFile来获取包含的文件夹,如果您需要的话。

Step 1: Class to URL

As discussed in other answers, there are two major ways to find a URL relevant to a Class.

正如在其他答案中所讨论的,找到一个与类相关的URL有两种主要方法。

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

    .getLocation .getCodeSource网址URL = Bar.class.getProtectionDomain()()();

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

    URL = Bar.class.getResource(Bar.class.getSimpleName() +“.class”);

Both have pros and cons.

两者都有利有弊。

The getProtectionDomain approach yields the base location of the class (e.g., the containing JAR file). However, it is possible that the Java runtime's security policy will throw SecurityException when calling getProtectionDomain(), so if your application needs to run in a variety of environments, it is best to test in all of them.

getProtectionDomain方法生成类的基本位置(例如,包含JAR文件)。然而,当调用getProtectionDomain()时,Java运行时的安全策略可能会抛出SecurityException,因此,如果您的应用程序需要在各种环境中运行,那么最好在所有环境中进行测试。

The getResource approach yields the full URL resource path of the class, from which you will need to perform additional string manipulation. It may be a file: path, but it could also be jar:file: or even something nastier like bundleresource://346.fwk2106232034:4/foo/Bar.class when executing within an OSGi framework. Conversely, the getProtectionDomain approach correctly yields a file: URL even from within OSGi.

getResource方法生成类的完整URL资源路径,您将需要执行额外的字符串操作。它可能是一个文件:path,但它也可能是jar:文件:或者甚至更像bundleresource://346.fwk2106232034:4/foo/Bar。在OSGi框架中执行的类。相反,getProtectionDomain方法可以正确地生成一个文件:甚至来自OSGi内部的URL。

Note that both getResource("") and getResource(".") failed in my tests, when the class resided within a JAR file; both invocations returned null. So I recommend the #2 invocation shown above instead, as it seems safer.

注意,getResource(“”)和getResource(“。”)在我的测试中失败,当类在一个JAR文件中保存;这两个调用返回null。因此,我推荐上面显示的#2调用,因为它看起来更安全。

Step 2: URL to File

Either way, once you have a URL, the next step is convert to a File. This is its own challenge; see Kohsuke Kawaguchi's blog post about it for full details, but in short, you can use new File(url.toURI()) as long as the URL is completely well-formed.

无论哪种方式,一旦有了URL,下一步就是将其转换为文件。这是它自己的挑战;请参阅Kohsuke Kawaguchi的博客文章,了解详细信息,但简短地说,只要URL完全正确,您就可以使用新文件(URL . touri())。

Lastly, I would highly discourage using URLDecoder. Some characters of the URL, : and / in particular, are not valid URL-encoded characters. From the URLDecoder Javadoc:

最后,我强烈反对使用URLDecoder。URL的某些字符:特别是,不是有效的URL编码字符。从URLDecoder Javadoc:

It is assumed that all characters in the encoded string are one of the following: "a" through "z", "A" through "Z", "0" through "9", and "-", "_", ".", and "*". The character "%" is allowed but is interpreted as the start of a special escaped sequence.

它假定编码字符串中的所有字符都是以下的一个:“a”通过“z”,“a”通过“z”,“0”通过“9”,“-”,“_”,“。”、“*”。字符“%”是允许的,但是被解释为一个特殊转义序列的开始。

...

There are two possible ways in which this decoder could deal with illegal strings. It could either leave illegal characters alone or it could throw an IllegalArgumentException. Which approach the decoder takes is left to the implementation.

这个解码器可能有两种处理非法字符串的方法。它可以单独留下非法字符,也可以抛出非法的异常。解码器采用的方法是留给实现的。

In practice, URLDecoder generally does not throw IllegalArgumentException as threatened above. And if your file path has spaces encoded as %20, this approach may appear to work. However, if your file path has other non-alphameric characters such as + you will have problems with URLDecoder mangling your file path.

在实践中,URLDecoder一般不会抛出IllegalArgumentException作为威胁。如果您的文件路径被编码为%20,那么这种方法可能会起作用。但是,如果您的文件路径中有其他非字母的字符,例如+,那么您将会遇到与URLDecoder混淆文件路径的问题。

Working code

To achieve these steps, you might have methods like the following:

为了实现这些步骤,您可能有如下方法:

/**
 * 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);
}

You can find these methods in the SciJava Common library:

您可以在SciJava公共库中找到这些方法:

#4


43  

You can also use:

您还可以使用:

CodeSource codeSource = YourMainClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
String jarDir = jarFile.getParentFile().getPath();

#5


23  

Use ClassLoader.getResource() to find the URL for your current class.

使用ClassLoader.getResource()查找当前类的URL。

For example:

例如:

package foo;

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

(This example taken from a similar question.)

(这个例子取自一个类似的问题。)

To find the directory, you'd then need to take apart the URL manually. See the JarClassLoader tutorial for the format of a jar URL.

要找到该目录,您需要手动将URL拆开。有关jar URL的格式,请参阅JarClassLoader教程。

#6


15  

I'm surprised to see that none recently proposed to use Path. Here follows a citation: "The Path class includes various methods that can be used to obtain information about the path, access elements of the path, convert the path to other forms, or extract portions of a path"

我很惊讶地发现,最近没有人建议使用Path。引用如下:“Path类包含了各种方法,可用于获取关于路径的信息、路径的访问元素、将路径转换为其他形式或提取路径的部分”。

Thus, a good alternative is to get the Path objest as:

因此,一个好的替代方法是:

Path path = Paths.get(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI());

#7


12  

The only solution that works for me on Linux, Mac and Windows:

在Linux、Mac和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();
}

#8


6  

I had the the same problem and I solved it that way:

我遇到了同样的问题,我解决了这个问题:

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

I hope I was of help to you.

我希望我对你有帮助。

#9


6  

Here's upgrade to other comments, that seem to me incomplete for the specifics of

这里是对其他评论的升级,这对我来说是不完整的。

using a relative "folder" outside .jar file (in the jar's same location):

使用一个相对的“文件夹”在.jar文件(在jar的相同位置):

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"));

#10


5  

the selected answer above is not working if you run your jar by click on it from Gnome desktop environment (not from any script or terminal).

如果您通过单击Gnome桌面环境(而不是来自任何脚本或终端)来运行您的jar,那么上面所选的答案不会起作用。

Instead, I have fond that the following solution is working everywhere:

相反,我喜欢以下的解决方案:

    try {
        return URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
    } catch (UnsupportedEncodingException e) {
        return "";
    }

#11


5  

For getting the path of running jar file I have studied the above solutions and tried all methods which exist some difference each other. If these code are running in Eclipse IDE they all should be able to find the path of the file including the indicated class and open or create an indicated file with the found path.

为了获得运行jar文件的路径,我研究了以上的解决方案,并尝试了所有的方法,它们之间存在一些差异。如果这些代码在Eclipse IDE中运行,那么它们都应该能够找到文件的路径,包括指定的类,并打开或创建带有找到路径的指定文件。

But it is tricky, when run the runnable jar file directly or through the command line, it will be failed as the path of jar file gotten from the above methods will give an internal path in the jar file, that is it always gives a path as

但是,如果直接或通过命令行运行runnable jar文件,它将会失败,因为从上面的方法获得的jar文件路径将在jar文件中给出一个内部路径,这就是它总是给出一条路径。

rsrc:project-name (maybe I should say that it is the package name of the main class file - the indicated class)

rsrc:项目名称(也许我应该说它是主类文件的包名——指示类)

I can not convert the rsrc:... path to an external path, that is when run the jar file outside the Eclipse IDE it can not get the path of jar file.

我不能转换rsrc:…路径到外部路径,即在Eclipse IDE之外运行jar文件时,它无法获得jar文件的路径。

The only possible way for getting the path of running jar file outside Eclipse IDE is

在Eclipse IDE之外获得运行jar文件的路径的惟一方法是。

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

this code line may return the living path (including the file name) of the running jar file (note that the return path is not the working directory), as the java document and some people said that it will return the paths of all class files in the same directory, but as my tests if in the same directory include many jar files, it only return the path of running jar (about the multiple paths issue indeed it happened in the Eclipse).

这段代码行可能返回的生活路径(包括文件名)运行jar文件(注意,返回路径不是工作目录),作为java文档,有些人说,它将返回所有类文件在同一个目录的路径,但随着我的测试中,如果在相同的目录中包括许多jar文件,它只返回运行jar的路径(约多条路径问题确实发生在Eclipse)。

#12


3  

Actually here is a better version - the old one failed if a folder name had a space in it.

实际上,这里有一个更好的版本——如果文件夹名有一个空格,旧的版本就失败了。

  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);
  }

As for failing with applets, you wouldn't usually have access to local files anyway. I don't know much about JWS but to handle local files might it not be possible to download the app.?

对于applet的失败,您通常无法访问本地文件。我不太了解JWS,但是处理本地文件可能不可能下载这个应用程序。

#13


3  

String path = getClass().getResource("").getPath();

The path always refers to the resource within the jar file.

路径总是引用jar文件中的资源。

#14


3  

The simplest solution is to pass the path as an argument when running the jar.

最简单的解决方案是在运行jar时将路径作为参数传递。

You can automate this with a shell script (.bat in Windows, .sh anywhere else):

您可以使用shell脚本(。蝙蝠在窗户,.sh在其他地方):

java -jar my-jar.jar .

I used . to pass the current working directory.

我使用。以传递当前工作目录。

UPDATE

更新

You may want to stick the jar file in a sub-directory so users don't accidentally click it. Your code should also check to make sure that the command line arguments have been supplied, and provide a good error message if the arguments are missing.

您可能希望将jar文件保存在子目录中,这样用户就不会不小心点击它。您的代码还应该检查是否提供了命令行参数,如果缺少参数,则提供一个好的错误消息。

#15


3  

Other answers seem to point to the code source which is Jar file location which is not a directory.

其他答案似乎指向代码源,它是Jar文件位置,而不是目录。

Use

使用

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

#16


3  

I had to mess around a lot before I finally found a working (and short) solution.
It is possible that the jarLocation comes with a prefix like file:\ or jar:file\, which can be removed by using String#substring().

在我最终找到一个有效的解决方案之前,我不得不到处乱搞。jarLocation可能带有一个类似于文件的前缀:\或jar:file\,可以使用String#substring()来删除它。

URL jarLocationUrl = MyClass.class.getProtectionDomain().getCodeSource().getLocation();
String jarLocation = new File(jarLocationUrl.toString()).getParent();

#17


2  

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;}

Works good on Windows

Windows上的好工作

#18


2  

I tried to get the jar running path using

我试图让jar运行路径使用。

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

c:\app>java -jar application.jar

c:\ app > java jar application.jar

Running the jar application named "application.jar", on Windows in the folder "c:\app", the value of the String variable "folder" was "\c:\app\application.jar" and I had problems testing for path's correctness

运行名为“应用程序”的jar应用程序。在“c:\app”文件夹的Windows上,字符串变量“文件夹”的值为“\c:\app\应用程序”。我在测试路径的正确性时遇到了问题。

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

So I tried to define "test" as:

所以我试着把“测试”定义为:

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

to get path in a right format like "c:\app" instead of "\c:\app\application.jar" and I noticed that it work.

以“c:\app”而不是“\c:\app\应用程序”这样的正确格式获取路径。我注意到它起作用了。

#19


1  

Something that is frustrating is that when you are developing in Eclipse MyClass.class.getProtectionDomain().getCodeSource().getLocation() returns the /bin directory which is great, but when you compile it to a jar, the path includes the /myjarname.jar part which gives you illegal file names.

令人沮丧的是,当您在Eclipse MyClass.class.getProtectionDomain()中开发时,getcodesource (). getlocation()返回/bin目录很好,但是当您将它编译到一个jar时,路径包括/myjarname。jar部分,它给你非法的文件名。

To have the code work both in the ide and once it is compiled to a jar, I use the following piece of code:

为了让代码在ide中同时工作,并且一旦它被编译成一个jar,我使用下面的代码:

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");
}

#20


1  

Not really sure about the others but in my case it didn't work with a "Runnable jar" and i got it working by fixing codes together from phchen2 answer and another from this link :How to get the path of a running JAR file? The code:

不太确定其他的,但是在我的例子中,它没有使用一个“可运行的jar”,并且我通过从phchen2的答案和这个链接的另一个链接中修复代码来工作:如何获得一个运行的jar文件的路径?代码:

               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");

#21


0  

Mention that it is checked only in Windows but i think it works perfect on other Operating Systems [Linux,MacOs,Solaris] :).

提到它只在Windows中进行检查,但我认为它在其他操作系统(Linux、MacOs、Solaris)上是完美的。


I had 2 .jar files in the same directory . I wanted from the one .jar file to start the other .jar file which is in the same directory.

我在同一个目录中有两个.jar文件。我希望从一个.jar文件开始另一个.jar文件,它在同一个目录中。

The problem is that when you start it from the cmd the current directory is system32.

问题是,当从cmd开始时,当前目录是system32。


Warnings!

警告!

  • The below seems to work pretty well in all the test i have done even with folder name ;][[;'57f2g34g87-8+9-09!2#@!$%^^&() or ()%&$%^@# it works well.
  • 下面能够出色地执行所有的测试我即使文件夹名称;][[,“57 f2g34g87-8 + 9-09 ! 2 # @ ! $ % ^ ^ &()或()% & $ % ^ @ #它好用。
  • I am using the ProcessBuilder with the below as following:
  • 我正在使用以下的ProcessBuilder:

????..

????..

//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):

????getBasePathForClass(Class 、):

    /**
     * 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[* user] + bachden [* 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;
    }

#22


0  

This code worked for me:

这段代码为我工作:

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;
  }

#23


-1  

Ignore backup lad answer, it may look ok sometimes but has several problems:

忽略后备孩子的回答,有时看起来不错,但有几个问题:

here both should be +1 not -1:

这里两者都应该是+1而不是-1:

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

Very dangerous because is not immediately evident if the path has no white spaces, but replacing just the "%" will leave you with a bunch of 20 in each white space:

非常危险,因为如果路径没有空格,就不明显了,但是只替换“%”会让你在每个空格中有20个字节:

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

There are better ways than that loop for the white spaces.

对于空白区域,有更好的方法。

Also it will cause problems at debugging time.

同时也会在调试时间造成问题。

#24


-1  

This method, called from code in the archive, returns the folder where the .jar file is. It should work in either Windows or Unix.

这个方法,从归档的代码中调用,返回.jar文件所在的文件夹。它应该在Windows或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);
  } 

Derived from code at: Determine if running from JAR

从代码中派生出来的:确定是否从JAR运行。

#25


-1  

I write in Java 7, and test in Windows 7 with Oracle's runtime, and Ubuntu with the open source runtime. This works perfect for those systems:

我在Java 7中编写,在Windows 7中使用Oracle的运行时进行测试,而Ubuntu则使用开源运行时。这对那些系统非常适用:

The path for the parent directory of any running jar file (assuming the class calling this code is a direct child of the jar archive itself):

任何运行jar文件的父目录的路径(假设这个类调用此代码是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

So, the path of foo.jar would be:

所以,foo的路径。jar将:

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

Again, this wasn't tested on any Mac or older Windows

同样,这在任何Mac或旧的Windows上都没有测试过。

#26


-1  

The getProtectionDomain approach might not work sometimes e.g. when you have to find the jar for some of the core java classes (e.g in my case StringBuilder class within IBM JDK), however following works seamlessly:

有时,当您必须为一些核心java类找到jar时,getProtectionDomain方法可能不会起作用。在我的案例中,在IBM JDK中使用StringBuilder类),但是以下工作是无缝的:

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, "");
}

#27


-1  

I have another way to get the String location of a class.

我有另一种方法来获取类的字符串位置。

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

The output String will have the form of

输出字符串的形式为。

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

The spaces and other characters are handled, and in the form without file:/. So will be easier to use.

空格和其他字符被处理,并且在表单中没有文件:/。这样更容易使用。

#28


-1  

Or you can pass throw the current Thread like this :

或者你也可以像这样通过抛出当前线程:

String myPath = Thread.currentThread().getContextClassLoader().getResource("filename").getPath();

#29


-2  

This one liner works for folders containing spaces or special characters (like ç or õ). The original question asks for the absolute path (working dir), without the JAR file itself. Tested in here with Java7 on Windows7:

这一行程序适用于包含空格或特殊字符(如c或o)的文件夹。原始问题要求绝对路径(工作目录),没有JAR文件本身。在这里用Java7在Windows7上测试:

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

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

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