Oh, forgot the scripts to compile and run (these are under Windows): Assuming that the sources of "mod_A", "mod_B" and m"od_C" are located in "src", the compilation result should be placed into "out" here the compile script:
rd out /s /q && md out @echo compiling module mod_A dir src\mod_A\*java /s /b > mod_A_source_files.txt type mod_A_source_files.txt javac -d out\mod_A @mod_A_source_files.txt @echo compiling module mod_B dir src\mod_B\*java /s /b > mod_B_source_files.txt type mod_B_source_files.txt javac --module-path out -d out\mod_B @mod_B_source_files.txt @echo compiling module mod_C dir src\mod_C\*java /s /b > mod_C_source_files.txt type mod_C_source_files.txt javac --module-path out -d out\mod_C @mod_C_source_files.txt Assuming that "TestUse_mtest3_Class03A.java" is located in the directory that contains the "out" subdirectory: del TestUse_mtest3_Class03A.class javac -cp "." --module-path out --add-modules mod_A,mod_B,mod_C TestUse_mtest3_Class03A.java java -cp "." --module-path out --add-modules mod_A,mod_B,mod_C TestUse_mtest3_Class03A ---rony On 23.01.2018 15:52, Rony G. Flatscher wrote: > Given three modules (sources at the end) where > > * "mod_A" exports its package "mtest1", to everyone > * "mod_B" requires "mod_A" and exports its package "mtest2" to "mod_C" > * "mod_C" requires "mod_B" and exports its package "mtest3" to everyone > > "mod_B"'s class "mtest2.Class02A" defines two public fields, one static > ("pubStaticFromClass02A") > and one an instance ("pubFromClass02") one. > > Compiling the modules and then using them in the following Java program (via > the CLASSPATH) works, > here the source: > > TestUse_mtest3_Class03A.java > > public class TestUse_mtest3_Class03A > { > public static void main (String args[]) { > mtest3.Class03A o=new mtest3.Class03A(); > System.out.println("o.pubStaticFromClass02A : > "+o.pubStaticFromClass02A ); > System.out.println("o.pubFromClass02A : > "+o.pubFromClass02A ); > System.out.println("o: "+o+", o.getMyClassName(): > "+o.getMyClassName()); > } > } > > Compiling the above program and running it yields: > > o.pubStaticFromClass02A : static-mtest2.Class02A > o.pubFromClass02A : instance-mtest2.Class02A > o: mtest3.Class03A@5afa04c, o.getMyClassName(): via: > this=[mtest3.Class03A@5afa04c], > getMyClassName()=[class-mtest1.Class01A] > > Here is a 1:1 transcription from the above Java program to Rexx which uses > Java reflection to > achieve the same: > > test.rex > > o=.bsf~new("mtest3.Class03A") -- create Java object > say "o~pubStaticFromClass01A:" o~pubStaticFromClass02A > say "o~pubFromClass01A :" o~pubFromClass02A > say "o:" o "o~getMyClassName:" o~getMyClassName > > ::requires BSF.CLS -- direct interpreter to load Java bridge > > Running the Rexx program yields the following reflection error: > > // // -> -> RexxReflectJava9.processField(): EXCEPTION in GET-operation: > tmpField="pubStaticFromClass02A" exception: > "java.lang.IllegalAccessException: class > org.rexxla.bsf.engines.rexx.RexxReflectJava9 cannot access class > mtest2.Class02A (in module > mod_B) because module mod_B does not export mtest2 to unnamed module > @51c8530f" > > The reflection code currently > > * gets the type from the Java object ("mtest3.Class03A") and tests whether > the package "mtest3" is > exported (it is), > * looks for all declaredFields and finds none, so it gets the superclass > "mtest2.Class02A", > * looks for all declaredFields and locates the Field named > "pubStaticFromClass02A" and invokes the > Field's get method, supplying the Java object (an instance of class > mtest3.Class03A) which > causes an IlleagalAccessException. > > Although it is true that "mod_B" is not exported to the unnamed module it is > still the case that > "mod_C" is exported (and class "mtest3.Class03A" can be accessed), such that > all public members in > its superclasses should be accessible via reflection, even in the case that a > public member resides > in a module that is not exported to the reflector from the unnamed module? > > The reflective code would be able to assess that the supplied object is from > an exported type and > hence allow the get access in this case for reflected members in its > superclasses, like it seems the > Java compiler allows for. > > ---rony > > Here are the contents of the module directories in source: > > > --------------------------------------------------------------------------- > > mod_A/module-info.java > > module mod_A { exports mtest1; } > > mod_A/mtest1/Class01A.java > > package mtest1; > > abstract public class Class01A > { > protected static String myClassName = "class-mtest1.Class01A"; > } > > > --------------------------------------------------------------------------- > > mod_B/module-info.java > > module mod_B { > requires mod_A; > exports mtest2 to mod_C; > } > > mod_B/mtest2/Class02A.java > > package mtest2; > > public class Class02A extends mtest1.Class01A > { > public static String > pubStaticFromClass02A="static-mtest2.Class02A"; > public String pubFromClass02A > ="instance-mtest2.Class02A"; > > public String getMyClassName() > { > return "via: this=["+this+"], > getMyClassName()=["+myClassName+"]"; > } > } > > > --------------------------------------------------------------------------- > > mod_C/module-info.java > > module mod_B { > requires mod_A; > exports mtest2 to mod_C; > } > > mod_C/mtest3/Class03A.java > > package mtest3; > > public class Class03A extends mtest2.Class02A > { > } > > -------------------------------------------------------------------------- > >