Was asked off-line for a zip-archive for convenience, hence I created a zip archive and put it on Dropbox. Here the link to get the zip-archive: <https://www.dropbox.com/s/fti7camrb5hs7we/02-20180123-getPublicField.zip?dl=0>. Just unzip, go into the <02-20180123-getPublicField> directory and run (on Windows) "1_compile.cmd", then either "5a_module_compile_and_run_TestUse_mtest3_Class03A.cmd" or "5b_classpath_compile_and_run_TestUse_mtest3_Class03A.cmd". Adapting the scripts to Unix should be straight forward.
Being formally an OpenJDK contributor there should be no legal problems. ---rony On 23.01.2018 18:32, Rony G. Flatscher wrote: > 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 >> { >> } >> >> >> --------------------------------------------------------------------------