反射とワークにテストコードとパッチのJava 9モジュール

イッチー:

両方が同じJava 9モジュールであり、反射を用いて相互にアクセスできるように、どのように私は、テスト実行時に私の生産コードに私のテストを追加できますか?

私はこれまで試してみました:

  • (実際にはJavaの9モジュール性を削除module-info.java)→それは完全に働いたが、私が探しているものではありません。
  • 専用のモジュールに私のテストを移動します(したがって、パッケージ)→それは完全に働いたが、私が探しているものではありません。(私は私のコードの近くに私のユニット・テストをしたいです。)
  • 使用--patch-module事実上、別のフォルダを追加するには(1には、使用して、指定された--module-pathそれは、「正常な」コードで働い→)ではなく、反射して、それがで指定されたクラスを見つけることができません--module-path
    • 使用して私のテストと本番コードの両方を指定して--patch-module、それが唯一の私が最初に指定したフォルダ内のクラスを検索します→。
    • 明示的に追加--add-opens mymodule/mypackge=mymoduleまたは...=ALL-UNNAMED反射のためにそれを開くために→どんな効果があると見ていません。

だから、私の完全なテストラインは次のようになります。

java \
  --patch-module com.stackoverflow.examplemodule=ModuleInfoTest:ModuleInfoExample \
  --module-path ModuleInfoExample \
  --add-opens com.stackoverflow.examplemodule/com.stackoverflow.examplepackage=com.stackoverflow.examplemodule \
  --add-opens com.stackoverflow.examplemodule/com.stackoverflow.examplepackage=ALL-UNNAMED \
  --module com.stackoverflow.examplemodule/com.stackoverflow.examplepackage.Main

私は、次のサブディレクトリとファイルを含むディレクトリにいます:

  • ModuleInfoExample /モジュールinfo.class
  • ModuleInfoExample / COM / stackoverflowの/ examplepackage / Main.class
  • ModuleInfoTest / COM / stackoverflowの/ examplepackage / AnyClass.class

私が使用しています:

openjdk version "13.0.2" 2020-01-14
OpenJDK Runtime Environment (build 13.0.2+8)
OpenJDK 64-Bit Server VM (build 13.0.2+8, mixed mode, sharing)



私が承認答えから学んだように、私の問題は本当に「なかったアクセス、私はそれを言葉で表現として、他のクラス」。しかし、より多くのような見つける(クラスパス/のModulePathをスキャンすることによって)、それらを。しかし、この部分は、すでにされ、この他のStackOverflowの質問に答えました

Scratte:

Javaの13 javaコマンドこれらは、あなたが使用しようとした2つのオプションがあります。

--add-opens module/package=target-module(,target-module)*
--patch-module module=file(;file)*

だが:

  • --add-opensそれは他のモジュールに一つのモジュールを開きますので、あなたを助けていません。あなたはモジュールを1つだけ持っています。
  • --patch-moduleあなたはモジュールにパッチを適用するディレクトリ(またはjarファイル)を指定する必要があります。私はそこだと気づい;ていない:あなたが使用しよう。あなたのモジュールが持つにある同じディレクトリからパッチファイルには、Javaを言ってきたように私には思えます:ModuleInfoExample

あなただけのファイルを追加する必要がありModuleInfoTest/、あなたのモジュールに。私はあなたの質問から構造を作成し、それを実行しました:

コンパイル:

javac -d target/ModuleInfoExample src/ModuleInfoExample/*.java src/ModuleInfoExample/com/stackoverflow/examplepackage/*.java
javac -cp target/ModuleInfoExample -d target/ModuleInfoTest src/ModuleInfoTest/com/stackoverflow/examplepackage/*.java

モジュールからメインを実行していない - 何も追加されたクラスを:

java --module-path target/ModuleInfoExample --module com.stackoverflow.examplemodule/com.stackoverflow.examplepackage.Main

prints:
Hello world - I'm private

モジュールから実行AnyClass - 無添加のクラス - 例外が予想されます

java --module-path target/ModuleInfoExample --module com.stackoverflow.examplemodule/com.stackoverflow.examplepackage.AnyClass

Error: Could not find or load main class com.stackoverflow.examplepackage.AnyClass in module com.stackoverflow.examplemodule

モジュールからAnyClassを実行 - パッケージにAnyClassを追加します:

java --module-path target/ModuleInfoExample --patch-module com.stackoverflow.examplemodule=target/ModuleInfoTest --module com.stackoverflow.examplemodule/com.stackoverflow.examplepackage.AnyClass

prints:
Inside AnyClass - calling Main: Hello world - I'm private

  field.get() = I'm private
  field.get() = I'm not private anymore

合計の構造:

>tree /f
..snip..
C:.
+---src
¦   +---ModuleInfoExample
¦   ¦   ¦   module-info.java
¦   ¦   ¦
¦   ¦   +---com
¦   ¦       +---stackoverflow
¦   ¦           +---examplepackage
¦   ¦                   Main.java
¦   ¦
¦   +---ModuleInfoTest
¦       +---com
¦           +---stackoverflow
¦               +---examplepackage
¦                       AnyClass.java
¦
+---target
    +---ModuleInfoExample
    ¦   ¦   module-info.class
    ¦   ¦
    ¦   +---com
    ¦       +---stackoverflow
    ¦           +---examplepackage
    ¦                   Main.class
    ¦
    +---ModuleInfoTest
        +---com
            +---stackoverflow
                +---examplepackage
                        AnyClass.class

SRC \ ModuleInfoExample \ module-info.java:

module com.stackoverflow.examplemodule {
//  exports com.stackoverflow.examplepackage; // no need to export. Nothing is using this
}

SRC \ ModuleInfoExample \ COM \ stackoverflowの\ examplepackage \ Main.java:

package com.stackoverflow.examplepackage;

public class Main {
  private String privateString = "I'm private";

  public static void main(String[] args) {
    new Main().hello();
  }
  public void hello(){
    System.out.println("Hello world - " + privateString);
  }
}

SRC \ ModuleInfoTest \ COM \ stackoverflowの\ examplepackage \ AnyClass.java:

package com.stackoverflow.examplepackage;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public class AnyClass {
  public static void main(String[] args) {
    testhello();
    System.out.println();
    breakhello();
  }

  public static void testhello(){
    System.out.print("Inside AnyClass - calling Main: ");
    Main test = new Main();
    test.hello();
  }

  public static void breakhello(){
    try {
      // Not necessary - same package, but..
      Class<?> mainClass = Class.forName("com.stackoverflow.examplepackage.Main");
      Constructor<?> constructor = mainClass.getConstructor();
      Object main = constructor.newInstance();

      // Getting, printing and changing the field..
      Field field = mainClass.getDeclaredField("privateString");
      field.setAccessible(true);
      System.out.println("  field.get() = " + field.get(main));
      field.set(main,"I'm not private anymore");
      System.out.println("  field.get() = " + field.get(main));

    } catch (Exception e) {  // Sorry, all in one big bucket
       System.out.println("Error: " + e);
    }
  }
}

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=6461&siteId=1