jeudi 11 novembre 2021

java ModuleLayer : ModuleLayer.Controller add methods don't work

I am using Netbeans 12.5 and java 16

In an Java Modular Project I have 2 Modules

Modular-Testing(/*The Project Name*/)
|
|----Consumer(/*Module Name*/)
|    |
     |--classes(/*Folder Name*/)
        |
        |--main(/*package name*/)
           |
           |--CustomModuleTest.java(Main Class)    


     
|--Test_Module_A(/*Module Name*/)
    |
    |--classes(/*Folder Name*/)
        |
        |--package_a(/*package name*/)
           |
           |--ClassA.java  

CustomModuleTest.java

public static void main(String[] args)throws Exception
{
   Path baseDir=Path.of("C:/Users/Home/Documents/NetBeansProjects/Netbeans/Modular-Testing/build/modules/");
 
   //Create the configuration for these two modules with boot-layer configuration as it's parent
   Configuration level1=Configuration.resolve
   (
     ModuleFinder.of(baseDir.resolve("Consumer"),baseDir.resolve("Test_Module_A"))
    ,List.of(ModuleLayer.boot().configuration())
    ,ModuleFinder.of()
    ,List.of("Consumer","Test_Module_A")
   );   

   //create the module layer with only one system class loader and boot layer as parent
   ModuleLayer.Controller layer1=ModuleLayer.defineModulesWithOneLoader
   (
     level1
    ,List.of(ModuleLayer.boot())
    ,ClassLoader.getSystemClassLoader()
   ); 
   
   //this is the main purpose of this test. I want to call ClassA.callMe() via reflection after i have dynamically acheived the permissions for it by first
   //Making Consumer Module read(requires) Test_Module_A
   //Making Test_Module_A open it's package(package_a) to Consumer
   //With this consumer should have full reflective access to Test_Module_A(or that's what i had hoped but it didn't work)

                          //Require(Read)
   //Make Module Consumer--------------->Test_Module_A 
   layer1.addReads
   (
     layer1.layer().findModule("Consumer").get()
    ,layer1.layer().findModule("Test_Module_A").get()
   ); 
                                 //Open package_a
   //Make Module Test_Module_A-------------------->Consumer 
   layer1.addOpens
   (
    layer1.layer().findModule("Test_Module_A").get()
   ,"package_a"
   ,layer1.layer().findModule("Consumer").get()
   ); 
   
   //Do the actual Test
   Class targetClass=layer1.layer().findLoader("Test_Module_A").loadClass("package_a.ClassA");
   Method method=targetClass.getDeclaredMethod("callMe");
   method.trySetAccessible();
   method.invoke(null);  //<---------Crashes Here(It's a static method so no object reference)
}

ClassA does nothing

package package_a;

public class ClassA 
{
  private static void callMe()
  {
   System.out.println("Hooray You Called Me Using ModuleLayers!!!");
  }
}

module-info for both Consumer & Test_Module_A are empty

module Consumer{}
module Test_Module_A{}

the module-info of both these modules are empty because i want to dynamically add Opens/Exports using ModuleLayer.Controller

The class is located with no problems the method is made accessable using trySetAccessible() but as soon as i call invoke i get this error

Exception in thread "main" java.lang.IllegalAccessException: class main.CustomModuleTest (in module Consumer) cannot access class package_a.ClassA (in module Test_Module_A) because module Test_Module_A does not export package_a to module Consumer
    at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:385)
    at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:687)
    at java.base/java.lang.reflect.Method.invoke(Method.java:559)

The test is run from CustomModuleTest.java main method inside Consumer Module the addReads & addOpens method either don't work or i am just using it wrong

Any ideas?





Aucun commentaire:

Enregistrer un commentaire