So the scenario is
ME -> M1 -> M2 -> M3
with "->" meaning <dependencies><module name="X"/>... in the left side module's module.xml and no 'export="true"' attribute. So ME can only see M1's classes, M1 can only see M2, M2 can only see M3.
If M2 uses the single param java.util.ServiceLoader.load() variant and doesn't do anything to change the TCCL, this setup will not work. In 7.0.2 when M2 is executing the TCCL will have visibility to the classes in ME and M1 (if ME doesn't change the TCCL from what the AS passes in) or to the classes in M1 and M2 (if ME changes the TCCL to M1's classloader.) Either way, M3 classes are not visible.
Options:
1) If ME, M1, M2, M3 are really a unit, package ME.jar, M1.jar, M2.jar, M3.jar in a single module.
2) In ME's module.xml's dependencies section, add
<module name="M1"/>
<module name=M2"/>
<module name="M3"/>
The TCCL passed in by AS 7.0.2.+ will be able to see all relevant classes.
3) In M2's module.xml have <module name="M3" export="true"/> and in M1's module.xml have <module name="M2" export="true"/>
Again, the TCCL passed in by the AS will be able to see all relevant classes. If some other module depends on M1, the M2 and M3 classes will be visible to that module as well. Which may be a good thing or a bad thing. If it's bad, solution 2) is better.
4) If M1, M2, M3 are really a unit, package M1.jar, M2.jar, M3.jar in a single module.
5) In M1's module.xml's dependencies section, add
<module name=M2"/>
<module name="M3"/>
Then in ME, change the TCCL to M1's classloader before calling into M1. When M1 calls into M2, the TCCL will be one that can see M3's classes.
6) In M2's module.xml have <module name="M3" export="true"/>. M3's classes will now be visible to M1. Then in ME, change the TCCL to M1's classloader before calling into M1. When M1 calls into M2, the TCCL will be one that can see M3's classes. If some other module depends on M2, the M3 classes will be visible to that module as well. Which may be a good thing or a bad thing.
7) Package M2.jar and M3.jar in a single module, M2+. Then in ME, change the TCCL to M1's classloader before calling into M1. When M1 calls into M2+, the TCCL will be one that can see M3.jar's classes. If some other module depends on M2+, the M3.jar classes will be visible to that module as well. Which may be a good thing or a bad thing.
Dan Sirbu wrote:
In a genric way, once in a Module, the Module should have visibility on all other Modules that were added as dependecies in the ModuleExtension, to cover more complex stuff.
This can be done in a variety of ways, as described above. What can't be done is having a module's dependencies exposed without the consent of the module. A module's dependencies are treated as internal details unless the export="true" attribute is added.