Skip to content

Commit 99fac77

Browse files
committed
[J17] Add intermodule class loading example description
1 parent a0573b8 commit 99fac77

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
## Java 17. Manual Loading (loading and loadable)
2+
---
3+
**Task:** load any application class using a custom class loader (`CustomClassLoader`) from another module (the modules are NOT linked through `module-info.java`).
4+
5+
### Solution
6+
---
7+
Modules (declared via `module-info.java`):
8+
- `manual.fewmodules.separately.nodeps.loading`:
9+
- [`Main`](loading/src/ru/ispras/j17/manual/fewmodules/separately/withdeps/loading/Main.java) - a class containing the `main` method, where an instance of the `CustomClassLoader` class is created, the `Cat` class is loaded using it, creating an instance of the class `Cat` and calling the `Cat::talk` method;
10+
- [`CustomClassLoader`](loading/src/ru/ispras/j17/manual/fewmodules/separately/withdeps/loading/CustomClassLoader.java) - a class that is an implementation of a custom class loader;
11+
- `manual.fewmodules.separately.nodeps.loadable`:
12+
- [`Cat`](loadable/src/ru/ispras/j17/manual/fewmodules/separately/withdeps/loadable/Cat.java) - loadable class with the `talk` method, which prints the string *"Meow"* to `stdout`.
13+
14+
### Run
15+
---
16+
Using `modulepath`:
17+
18+
```shell
19+
java17 -p loading-1.0.jar -m manual.fewmodules.separately.nodeps.loading
20+
```
21+
22+
Output:
23+
24+
```shell
25+
[loading] Main Class Module is module manual.fewmodules.separately.nodeps.loading
26+
[loading] Main Class ClassLoader is jdk.internal.loader.ClassLoaders$AppClassLoader@4554617c
27+
ClassLoader for [loadable] module is jdk.internal.loader.Loader@4a574795
28+
[loadable] Main Class ClassLoader is jdk.internal.loader.Loader@4a574795
29+
[loadable] Cat Class ClassLoader is jdk.internal.loader.Loader@4a574795
30+
[loadable] Main Class Module is module manual.fewmodules.separately.nodeps.loadable
31+
[loadable] Cat Class Module is module manual.fewmodules.separately.nodeps.loadable
32+
Meow
33+
```
34+
35+
### Explanation
36+
---
37+
![Java 17. Manual Loading (loading and loadable).jpg](../../../../../img/Java%2017.%20Manual%20Loading%20(loading%20and%20loadable).jpg)
38+
39+
The class modules are as we wanted, but the `Cat` class loader turned out to be not `CustomClassLoader` as we expected, but some `Loader`. The fact is that in the `defineModuleWithOneLoader` method, a new `Loader` loader is created (the same one that I mentioned in the **Java 8: Auto Loading** example), the parent of which becomes the passed `CustomClassLoader`.
40+
41+
```java
42+
private static ModuleLayer createLayer(Path modulePath, String moduleName) {
43+
/* ... */
44+
return bootLayer.defineModulesWithOneLoader(config, new CustomClassLoader());
45+
}
46+
```
47+
48+
Indeed, in [documentation](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/ModuleLayer.html#defineModulesWithOneLoader(java.lang.module.Configuration,java.util.List,java.lang.ClassLoader):~:text=of%20parent%20layers%20in%20search%20order-,parentLoader,-%2D%20The%20parent%20class%20loader%20for%20the) so and it is written:
49+
50+
```java
51+
public ModuleLayer defineModulesWithOneLoader(Configuration cf, ClassLoader parentLoader)
52+
```
53+
54+
> `parentLoader` - The parent class loader for the class loader created by this method; may be `null` for the
55+
> bootstrap class loader.
56+
57+
Thus, we do not have the opportunity to somehow pass our own class loader to the layer; we can only indicate the parent for the newly created one. Moreover, according to the same documentation, class loading will be delegated to the parent only if `Loader` does not find the package in which the class is located, here you can come up with different hacks based on this delegation model.
58+
59+
### Notes
60+
---
61+
- You can rewrite the code a little and add a hack that will force `Loader` to delegate class loading to a custom class loader: [Java 17. Manual Loading (loading and loadable) - hack](https://github.com/temikfart/java-classloading/tree/main/java-17/manual/few-modules/separately/no-deps-hack)

0 commit comments

Comments
 (0)