web-dev-qa-db-ja.com

外部モジュールからリソースファイルにアクセスする

これまでのところ、非モジュール化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のように、できるだけ変更を加えずに動作するでしょうか?

16
cen

Java コマンドを使用して、次のようにアプリケーションを起動している間:-

Java -p target/classes:target/dependency -m framework.core/com.framework.Main 
  • target/classesおよびtarget /を検索する-pのオプション--module-path aternateを使用してモジュールパスを指定していますモジュールの依存関係

  • -mの代わりに--moduleを使用すると、framework.coreという名前の解決する初期モジュールを指定し、メインクラスでモジュールグラフを構築して、 com.framework.Main

さて、ここでの問題は、モジュールframework.corerequiresを読まない、またはplayground.apiモジュールを読み取らないため、モジュールグラフに実際のリソースconfig.yml

@ Alanが推奨 のように、起動時にモジュール解決の出力をリストする良い方法は、--show-module-resolutionオプションを使用することです。


私は単純にsrc/main/resourcesをオープンしようとしましたが、ofcをコンパイルしません

モジュール内のリソースは ルートレベル にあるため、カプセル化されていないであり、開いたりエクスポートしたりする必要はありません。他のモジュール。

あなたの場合は、モジュールplayground.apiがモジュールグラフになり、アプリケーションがリソースにアクセスできることを確認する必要があります。初期モジュールに加えて解決するルートモジュールを指定するには、--add-modulesオプションを使用できます。


したがって、いくつかのデバッグとともに動作する全体的なソリューションは次のようになります。

Java --module-path target/classes:target/dependency 
     --module framework.core/com.framework.Main
     --add-modules playground.api
     --show-module-resolution
6
Naman
// 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)

以下の作業例を参照してください。


与えられた:

.
├── 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

6
Jano