【问题标题】:Eclipse - Gradle sourceSets, how to manage my yaml property filesEclipse - Gradle sourceSets,如何管理我的 yaml 属性文件
【发布时间】:2021-04-30 14:13:00
【问题描述】:

我使用的是 Gradle 7.0,我使用任务 Gradle Init 制作了我的项目。然后我将它导入 Eclipse(2021-03 和 buildship 3.1.5)。一切都很好,但是当我尝试读取或在 java 方法中使用“/myfile.yaml”作为路径创建文件时,它会在 D:\ 根文件夹(其中的分区)中创建它(或尝试读取它)我的 Eclipse 已安装)。

如果我不使用斜杠(“myfile.yaml”而不是“/myfile.yaml”),该文件将在项目的根文件夹中创建。我认为它应该在 src/main/resources 中,直到它没有被构建。

我的目标并不是真正创建一个文件,它只是更容易测试。我的目标是阅读一些 Yaml 配置文件。我应该怎么做才能确保文件将在构建包中并在两个上下文(eclipse调试和构建包目录)中的正确位置读取?而且,设置文件路径的最佳做法是什么(sonarlint 提醒我我这样做的方式:在下面的方法中硬编码,我知道它不应该是这样的......我会使用一个常量但是sonarlint 也不喜欢)。

应用树:

- Project
    - app
        - src/main/java (containing java classes)
        - src/main/resources (supposing to contain resources, yaml in my case)
        - My build.gradle file
        - yaml file when I try "myfile.yaml" without any /
    - gradle/wrapper/gradle-wrapper.jar & gradle-wrapper.properies
    - gradlew & gradlew.bat
    - settings.gradle

我的 settings.gradle :

rootProject.name = 'myapp'
include('app')

我的 build.gradle:

plugins {
    // Apply the application plugin to add support for building a CLI application in Java.
    id 'application'
}
apply plugin:'java'
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
}

dependencies {
    implementation 'com.google.guava:guava:30.0-jre'
    // Yaml reader
    implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.12.3'
    testImplementation 'junit:junit:4.13.1'
}

//I tried with and without this sourceSets and the result was the same
sourceSets {
    main {
        java {
            srcDirs= ["src/main/java"]
        }
        resources {
            srcDirs= ["src/main/resources"]
        }
    }
}

application {
    // Define the main class for the application.
    mainClass = 'myapp.launchers.App'
}

这是使用 Jackson 库 (yaml) 写入文件的方法:

public static void writeConfiguration() throws JsonGenerationException, JsonMappingException, IOException {
    WorkerConfig wc = new WorkerConfig();
    WorkerPathConfig wpc = new WorkerPathConfig();
    wpc.setTmpdir("\\some\\uri\\file");
    wpc.setOutputdir("\\some\\other\\uri\\file");
    wc.setPathConfig(wpc);
    ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
    objectMapper.writeValue(new File("/application.yaml"), wc);
}

【问题讨论】:

    标签: java eclipse gradle configuration file-properties


    【解决方案1】:

    Java 读取资源文件

    您正在管理 Java 程序中的文件。 如果您使用 java.io.File 类来获取对特定文件的引用,它将把这些引用作为实际路径:

    • 绝对路径:“/myfile.yaml” -> 将指向硬盘驱动器的根目录,在您的情况下为 D:\myfile.yaml
    • 相对路径:“myfile.yaml” -> 将指向您的 java 项目的根目录

    现在您的目标应该是获取项目特定的路径来加载配置文件。这可以通过 ClassLoader 实例来实现。您可以像下面的示例中那样读取文件的内容。 classLoader.getResourceAsStream() 将在您的资源中搜索文件。

    String fileName = "myfile.yaml";
    
    ClassLoader classLoader = getClass().getClassLoader();
    
    try (InputStream inputStream = classLoader.getResourceAsStream(fileName);
         InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
         BufferedReader reader = new BufferedReader(streamReader)) {
    
      String line;
      while ((line = reader.readLine()) != null) {
        System.out.println(line);
      }
    
    } catch (IOException e) {
      e.printStackTrace();
    }
    

    2 Gradle 构建脚本

    如果你在“src/main/java”中有你的类,在“src/main/resources”中有资源文件,那么这符合convention of gradle java plugin,你不需要明确指定sourceSets 块在你的 Gradle 构建脚本中。

    1. 声纳警告

    您可以将文件名提取为常量,并在加载配置文件时将其作为参数传递。我想这个文件“myfile.yaml”是你的应用程序的约定。在最好的情况下,它会记录在某处。

    至少这将大大简化开发,如果您希望动态提供它,则需要从环境变量或 main 方法中提供的参数中读取文件名。

    如果 SonarQube 警告不适用于您的情况,您可以取消它,并解释您忽略它的原因。

    【讨论】:

    • 感谢您的宝贵时间;)完美的答案。如果它只是文件名(没有任何目录分隔符,sonarqube 将其作为常量接受,以便我处理它)。我将使用 getResourceAsStream 方法
    猜你喜欢
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-27
    • 1970-01-01
    • 2021-11-14
    相关资源
    最近更新 更多