从外部模块访问资源文件

2023-12-13

到目前为止,在非模块化 java 之前,您只需将文件放入src/main/java/resources确保它在类路径中,然后加载它

file = getClass().getClassLoader().getResourceAsStream("myfilename"); 

几乎来自类路径中的任何地方。

现在有了模块,情节就变得更加复杂了。

我的项目设置如下:

module playground.api {
    requires java.base;
    requires java.logging;
    requires framework.core;
}

配置文件放在里面src/main/resources/config.yml.

项目运行于

java -p target/classes:target/dependency -m framework.core/com.framework.Main

由于主类并不驻留在我自己的项目中,而是驻留在外部框架模块中,因此它看不到config.yml。现在的问题是,有没有办法以某种方式将我的配置文件放入模块或打开它?我是否必须更改上游框架加载文件的方式?

我尝试在 module-info 中使用“exports”或“opens”,但它想要一个包名称,而不是文件夹名称。

如何以最实用的方式实现这一目标,使其像 Java 8 一样工作并尽可能少地进行更改?


// to scan the module path
ClassLoader.getSystemResources(resourceName)

// if you know a class where the resource is
Class.forName(className).getResourceAsStream(resourceName)

// if you know the module containing the resource
ModuleLayer.boot().findModule(moduleName).getResourceAsStream(resourceName)

请参阅下面的工作示例。


Given:

.
├── FrameworkCore
│   └── src
│       └── FrameworkCore
│           ├── com
│           │   └── framework
│           │       └── Main.java
│           └── module-info.java
└── PlaygroundApi
    └── src
        └── PlaygroundApi
            ├── com
            │  └── playground
            │      └── api
            │          └── App.java
            ├── config.yml
            └── module-info.java

Main.java可能

package com.framework;

import java.io.*;
import java.net.URL;
import java.util.Optional;
import java.util.stream.Collectors;

public class Main {
    public static void main( String[] args )
    {
        // load from anywhere in the modulepath
        try {
            URL url = ClassLoader.getSystemResources("config.yml").nextElement();
            InputStream is = url.openStream();
            Main.read(is);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // load from the the module where a given class is
        try {
            InputStream is = Class.forName("com.playground.api.App").getResourceAsStream("/config.yml");
            Main.read(is);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

        // load from a specific module
        Optional<Module> specificModule = ModuleLayer.boot().findModule("PlaygroundApi");
        specificModule.ifPresent(module -> {
            try {
                InputStream is = module.getResourceAsStream("config.yml");
                Main.read(is);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
    }

    private static void read(InputStream is) {
        String s = new BufferedReader(new InputStreamReader(is)).lines().collect(Collectors.joining("\n"));
        System.out.println("config.yml: " + s);
    }
}

你会启动

java --module-path ./FrameworkCore/target/classes:./PlaygroundApi/target/classes \
     --add-modules FrameworkCore,PlaygroundApi \
       com.framework.Main

要克隆此示例:git clone https://github.com/j4n0/SO-46861589.git

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从外部模块访问资源文件 的相关文章

随机推荐

  • “不包含四个或更多重复字符”的正则表达式

    我对正则表达式的经验有限 我一直在阅读有关否定和否定前瞻等的各种教程和帖子 但似乎没有什么与我的情况完全匹配 我正在尝试创建一个属性ASP NET MVC3对于密码复杂性 验证的一部分包括最小数量的重复字符 对于当前项目来说 限制是 3 但
  • 将按钮添加到 ui 导航控制器底部栏

    我可以使用以下代码取消隐藏导航控制器底部栏 self navigationController setToolbarHidden NO 但现在我想更改底部栏的颜色 并向该底部栏添加按钮 任何人都可以帮助我如何做到这一点 是否有任何委托方法
  • 水平滚动整个列表视图

    我有一个自定义列表视图 其中包含 14 个字段 如下所示 字段1 字段2 字段3 字段4 字段5 字段6 字段7 字段8 字段9 字段10 字段11 字段12 字段13 字段14 现在明显的问题是我不可能在屏幕上显示所有字段 所以我想让整个
  • python 3 IDLE 中的“语法错误:语法无效”

    为什么这是语法错误 我该如何解决它 class Queue Queue is basicliy a List def init self self queue add to the top of the list the left side
  • C# UTC 到用户当地时间

    我有一个用户可以发帖的网站 用户可能来自全球各地 因此当他们发帖时 我将发布日期存储为 DateTime UtcNow 我正在使用 JQuery 时间前插件来显示类似于堆栈溢出的发布数据 1 分钟前等 但我不确定如何将系统中存储的日期转换为
  • 如何更改相对布局边框颜色?

    如何更改相对布局边框颜色 这是我下面的代码 我只想显示边框颜色黑色 但显示所有相对布局黑色 我只想显示相对布局白色 只有边框是黑色我该怎么办
  • HTML 表单:完成文本字段后将焦点放在复选框上

    查看此 HTML 表单并注意它在文本字段之间有一个复选框 我尝试在移动设备上使用 Chrome 来填充它 并注意到一个意想不到的问题 如果用户在文本字段中键入内容 然后通过按 Android 键盘中的蓝色 完成 按钮移动到下一个字段 焦点将
  • C++读取csv文件并将值分配给数组

    我正在尝试读取 csv 文件并将值分配给二维数组 但我得到了奇怪的结果和一些垃圾值 虽然第一行是正确的 但第二行和第三行就变得奇怪了 下面是代码 include pch h include
  • 将 MySQL 数据库导入 SQL Server

    我有一个 sql来自 MySQL 转储的文件 其中包含表 定义和要插入这些表中的数据 如何将转储文件中表示的数据库转换为 SQL Server 数据库 Use SQL Server 迁移助手 SSMA 除了 MySQL 之外 它还支持 Or
  • 在 Java 中为变量分配新值

    我是 Java 新手 有一个关于变量的问题 这是一个例子 int hello 6 int goodbye 7 int combined hello goodbye System out println combined hello 10 S
  • 您能解释一下 bash shell 中的数学语法吗?

    for i in 1 99 do if i 2 eq 1 then echo i fi done 我正在学习 bash 并且我正在尝试更好地理解第 3 行 为什么 i 2 必须用括号双层包裹 为什么我不能把 旁边的符号i like i 2
  • 包含存储在向量中的 auto_ptr 的类

    在回答中将具有 std auto ptr 作为其成员变量的类的对象存储在 std vector 中是否安全 我说过包含 auto ptr 的类可以存储在向量中假设该类有一个用户定义的复制构造函数 有一些评论表明情况并非如此 因此这个问题是试
  • 使用内联表单集创建模型和相关模型

    我已将其发布在Django 用户 谷歌网上论坛 also 使用中的示例内联表单集文档 我能够edit属于特定模型的对象 使用 模型 我一直在尝试遵循相同的模式creating使用内联表单集的新对象 但无法 我的头脑足够清醒 可以为此目的提出
  • Android gradle:buildtoolsVersion 与compileSdkVersion

    有什么区别buildtoolsVersion vs compileSdkVersion在 Android 项目的 build gradle 中 编辑 具体来说 我想澄清一下构建工具是什么 compileSdkVersion是您编译所针对的
  • 获取数字范围内的数字列表

    我有一个数据框 其中一列包含一个 或多个 数字范围 我想将其转换为基于给定范围的数字列表 输入示例 35 40 or 35 43 45 47 这应该产生 1 35 36 37 38 39 40 and 1 35 36 37 38 39 40
  • 无法实现 androidx.appcompat.appcompat:1.0.0

    我是 Android 开发的绝对初学者 并尝试构建测试自动化来测试移动应用程序 在设置 IntelliJ 数周后 我仍然面临问题 其中包括以下问题 由于我使用的是 SDK 版本 29 我被告知应该将所有 support 关键字转换为 and
  • C# 的单例模式 [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 我需要存储一堆需要全局访问的变量 我想知道单例模式是否适用 从我看到的例子来看 单例模式只是一个不能被继承的静态类 但我见过的例子对于我的需求来说过于复杂 最简单的单例类是什么 我不能创建
  • android - 让 onTouch 优先于 onClick

    我有一个允许用户在 3 个不同视图之间滑动的活动 每个视图都显示图像列表 这些图像具有调用新活动并使图像全屏显示的 onClick 事件 这一切都正常 但是如果我尝试在 3 个不同的视图之间滑动并且我的手指在图像上滑动 它将触发 onCli
  • JavaFX 3D 对象之间的并集、交集和差异

    有没有办法在 JavaFX 3D 对象之间执行布尔运算 例如并集 交集和差集 例如在 Sphere 实例 Cylinder 实例和 Box 实例之间 从 Shape 类继承的 JavaFX 2D 对象已经具有 union 和 minus 方
  • 从外部模块访问资源文件

    到目前为止 在非模块化 java 之前 您只需将文件放入src main java resources确保它在类路径中 然后加载它 file getClass getClassLoader getResourceAsStream myfil