如何访问Java中的调用程序的资源目录

时间:2014-04-24 22:32:23

标签: java jar classloader

我有一个程序使用的库。该库在resources文件夹中加载一个特殊目录。

库中的

我有方法

public class DataRegistry{

    public static File getSpecialDirectory(){
        String resourceName = Thread.currentThread().getContextClassLoader().getResource("data").getFile().replace("%20", " ");
        File file = new File(resourceName);
        return file;
    }

}

在我的程序中我有主要方法

public static void main(String args[]){
    System.out.println(Data.getSpecialDirectory());
}

当我在数据程序中的junit测试中执行getSpecialDirectory()时,将获取资源并且一切正常。

当我在数据程序(导入的jar)之外的main方法中执行getSpecialDirectory()时,我得到了jar数据目录,而不是执行该程序的程序所期望的目录。

我认为让父类加载器解决了这个问题......我相信我的理解可能会有一个根本问题。

为清楚起见:

(库) 该文件的第15行:https://gist.github.com/AnthonyClink/11275442

(用法) 该文件的第31行: https://gist.github.com/AnthonyClink/11275661

我的poms可能与它有关,所以分享它们可能很重要:\

(图书馆) https://github.com/Clinkworks/Neptical/blob/master/pom.xml

(用法) https://github.com/Clinkworks/Neptical-Maven-Plugin/blob/master/pom.xml

4 个答案:

答案 0 :(得分:5)

  1. Maven使用target / classes和target / test-classes目录来组成用于运行单元测试的类路径。 src / main / resources和src / test / resources的内容将与编译的java源(.class文件)一起复制到这些位置。
  2. java.lang.ClassLoader.getResource返回java.net.URL
  3. 在单元测试情况下,ClassLoader.getResource返回一个file:// schemed URL,您的代码按预期工作。
  4. 当您在jar文件中打包时执行代码时,ClassLoader.getResource不再返回file:// schemed URL。它不能,因为资源不再是文件系统中的单独实体 - 它隐藏在jar文件中。你实际得到的是一个jar:file:// schemed URL。
  5. jar:无法通过[java.io.File]对象访问URL。
  6. 如果您只需要阅读资源的内容,请使用java.lang.ClassLoader.getResourceAsStream(...)并阅读其中的内容。

    请注意,无法更新类加载器资源的内容。

答案 1 :(得分:1)

  1. 您想要加载Java程序的目录吗?可以尝试

    文件f =新文件(“。”)。getCanconicalFile();

  2. 或者,如果您希望所有地方都可以尝试从System.env解析类路径或使用默认的类加载器

  3. 如果您想要一个相对于加载类的jar的目录:从http://www.nakov.com/blog/2008/06/11/finding-the-directory-where-your-java-class-file-is-loaded-from/引用

    URL classesRootDir = getClass()。getProtectionDomain()。getCodeSource()。getLocation();

  4.   

    以上内容返回加载.class时使用的基本目录   文件。它不包含包。它包含类路径   仅限目录。例如,在上面的控制台应用程序中   返回像这样的东西:

         

    文件:/ C:/文件%20于是%20Settings /管理员/工作区/ TestPrj / bin中/

         

    在Web应用程序中,它会返回如下内容:

         

    文件:/ C:/ Tomcat的/ web应用/ MyApp的/ WEB-INF /类/

    仅供参考如果运行程序的用户ID无法读取所有文件夹,则可能适用:http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getProtectionDomain%28%29

    1. 或将调用类的.class对象作为参数传递并获取其类加载器

答案 2 :(得分:1)

据我所知,无法保证您的资源目录。 Java提供了将资源作为InputStream获取的方法,但没有任何方法可以轻松获取资源的文件,尽管对于给定资源可以get the URL

如果您的应用程序中需要一个特殊的工作目录,我建议您将其作为系统属性,程序参数,Web应用程序参数或其他可以让您知道应用程序文件位置的内容传递。您甚至可以使用作为资源包含在应用程序中的ZIP文件填充此目录,因为Java中的ZIP库确实接受输入流作为参数。

答案 3 :(得分:0)

虽然用户@t​​gkprog是对的并且他的答案是正确的,但我很难想象你真的想要你想要的东西以及他在(3)中正确回答的内容。请编辑您的问题并解释

  • 如果resourceName将打印到控制台,输出应该是什么样的,
  • 如果你真的想要JAR文件的位置(在我的测试用例中就像是文件:/ C:/Users/Alexander/.m2/repository/com/clinkworks/neptical/0.0 .1-SNAPSHOT / data ,这是没有意义的,因为你不想读取甚至写入本地Maven缓存),
  • 或者您是否想要直接从JAR文件或任何其他位置(如当前工作目录等)读取资源。

否则我担心没有好办法回答这个问题。