获取java maven项目中的当前工作资源目录

时间:2012-08-13 21:44:41

标签: java maven junit

我目前正在进行JUnit测试,该测试检查负责从/向某个文件加载/保存进程配置的功能。鉴于资源中存在特定配置文件,该功能从文件加载参数。否则,该功能会尝试创建新配置文件并保留在类中编码的默认配置。现在我使用.class.getResource()方法检查配置文件是否存在,并检索必要的信息。事实证明,这种方法可以从maven的“测试级”和“类”目录中正常工作。但是,当文件不存在时尝试保存默认配置时遇到问题,即.class.getResource()方法返回null,因为资源尚不存在。这使我无法构建应保存文件的目标资源目录(依赖于上下文)。

有没有办法对我的功能进行编码,以评估特定对象是作为测试执行还是在生产中执行?更确切地说,我如何构建资源文件的相对路径以指向生产资源(../ classes / ...)或测试资源(../test-classes/ ..),具体取决于执行模式该项目目前是哪个?

我的问题有点类似于以下How should I discover test-resource files in a Maven-managed Java project?,但我认为它足以保证新线程。

2 个答案:

答案 0 :(得分:0)

如果我理解你的话,基本上你的问题是你有一个Maven项目,它读取一个特定的文件(通常在单元测试期间),它决定了应用程序的行为。如果该文件不存在,则应用程序会创建该文件。

ClassLoader.getSystemResource(...)的问题在于它实际上并没有扫描单个目录。相反,它正在查看Java的类路径以确定该特定资源的位置。如果类路径上有多个目录,则它将具有该文件可能位于的许多区域。

从某种意义上说,.getSystemResource(...)是一种方式。您可以查找文件的位置,但无法获得放置文件的适当位置。

* 那么当您需要将文件放在正确的位置时呢? *

您基本上有两种选择:

  1. 硬编码文件的位置:没人喜欢这样做。
  2. 在类路径上扫描的位置将传递到类加载器中。例如,您可以使用第一个并在那里创建文件。
  3. 第二种选择实际上并不是一种糟糕的选择;看看这个示例代码。

        final Enumeration<URL> urls = ClassLoader.getSystemClassLoader().getResources("");
        if(! urls.hasMoreElements()) {
            LOG.error("No entries exist on the class path!");
            System.exit(1);
        }
        final File configFile = new File(urls.nextElement().getFile(), "config.xml");
        configFile.createNewFile();
        LOG.info("Create a new configuration file: " + configFile.getPath());
        System.exit(0);
    

    这解决了配置文件在我的目标文件夹中的问题:..\target\classes\config.xml

    由你做的事情;很高兴提供更多提示&amp;如果您觉得需要更多,请提供建议。

答案 1 :(得分:0)

听起来你想要做以下事情:

当您的代码运行时,它会尝试加载配置文件。找不到配置文件时,您要创建配置文件。扭曲是

  • 如果您正在“生产模式”执行代码(我假设使用类似exec-maven-plugin或jetty-maven-plugin的内容,具体取决于您的代码的性质),您希望配置文件是放在$ {project.build.outputDirectory}

  • 如果您在“测试模式”下执行代码(例如,通过surefire或failsafe),您希望将配置文件放在$ {project.build.testOutputDirectory}

我要做的是使用ServiceLoader模式。

您创建一个ConfigFileStore接口,负责存储您的配置。

ConfigFileStoreFactory枚举实现该接口的所有服务(使用ServiceLoader API获取所有/META-INF/services/com.yourpackage.ConfigFileStore资源并从中提取类名。如果没有实现注册然后它将实例化一个默认实现,该实现将文件存储在基于getClass()的路径中(即向后工作以获取$ {project.build.outputDirectory}注意它应该处理类捆绑的情况进入JAR,我认为在这种情况下配置文件可能存储在JAR附近)

注意:默认实现不会在/ META-INF / services中注册

然后在src / test / java中扩展默认实现并在src / test / resources / META-INF / services / com.yourpackage.ConfigFileStore中注册扩展实现

现在,当运行在类路径上包含测试代码的代码时,将找到测试版本,它将从$ {project.build.testOutputDirectory}获取类的getClass(),因为它来自测试类路径/ META-INF /服务。

当运行在类路径上没有测试代码的代码时,默认实现将从$ {project.build.outputDirectory}中获取类的getClass()

应该做你想做的事。