簡體   English   中英

在Java Maven項目中獲取當前的工作資源目錄

[英]Getting the current working resource directory in java maven project

我目前工作的一個JUnit測試,檢查功能負責裝載/從/到一些文件保存過程配置。 假定資源中存在特定的配置文件,該功能將從文件中加載參數。 否則,該功能將嘗試創建新的配置文件並保留該類中編碼的默認配置。 現在,我使用.class.getResource()方法來檢查,如果配置文件存在,並獲取必要的信息。 實踐證明,這種方法在maven的“ test-class”和“ class”目錄中都可以正常工作。 但是,當文件不存在時嘗試保存默認配置時遇到問題,即.class.getResource()方法返回null,因為該資源尚不存在。 這使我無法構建應該在其中保存文件的目標資源目錄(取決於上下文)。

有沒有一種方法可以對我的功能進行編碼,以評估特定對象是作為測試執行還是在生產中執行? 更准確地說,如何根據我的執行模式,為資源文件建立相對路徑,以指向生產資源(../ classes / ...)或測試資源(../test-classes/ ..)。目前是哪個項目?

我的問題是有點類似下面我應該怎么發現一個Maven管理Java項目測試的資源文件? 但是我認為保證新線程足夠不同。

如果我理解正確,那么本質上您的問題是您有一個Maven項目,該項目讀取一個特定文件(通常在單元測試期間),該文件確定應用程序的行為。 如果該文件不存在,則您的應用程序將創建它。

ClassLoader.getSystemResource(...)的問題在於它實際上沒有掃描單個目錄。 相反,它正在查看Java的類路徑來確定該特定資源的位置。 如果類路徑上有多個目錄,則文件中可能包含許多區域。

從某種意義上講, .getSystemResource(...)是一種方法。 您可以查找文件的位置,但無法找到合適的位置來放置它。

* 那么,當您需要將文件放置在正確的位置時呢? *

本質上,您有兩個選擇:

  1. 硬編碼文件的位置:沒有人喜歡這樣做。
  2. 在類路徑上掃描的位置將傳遞到類加載器中。 例如,您可以使用第一個文件並在那里創建文件。

第二種選擇實際上並不是一個壞選擇。 看看這個示例代碼。

    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

取決於您的工作; 如果您需要更多的提示和建議,我們很樂意為您提供更多建議。

聽起來您想執行以下操作:

代碼運行時,它將嘗試加載配置文件。 當找不到配置文件時,您要創建配置文件。 扭曲的是

  • 如果要在“生產模式”下執行代碼(根據代碼的性質,我假定使用exec-maven-plugin或jetty-maven-plugin之類的東西),則希望將配置文件放置在$ {project中。 build.outputDirectory}

  • 如果您以“測試模式”(例如通過surefire或故障安全)執行代碼,則希望將配置文件放置在$ {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()。

應該做你想做的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM