Skip to content

Commit 18c09bd

Browse files
committed
[J17] Add intermodule class loading example
1 parent 57cecfc commit 18c09bd

File tree

9 files changed

+174
-0
lines changed

9 files changed

+174
-0
lines changed

.idea/runConfigurations/java_17_manual_few_modules_together_dependent___run_.xml

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
plugins {
2+
id 'java-library'
3+
}
4+
5+
group = 'com.habr.j17.manual.fewmodules.together.dependency'
6+
version = '1.0'
7+
8+
layout.buildDirectory = getParent().layout.buildDirectory
9+
10+
compileJava {
11+
java {
12+
toolchain {
13+
languageVersion = JavaLanguageVersion.of(17)
14+
}
15+
}
16+
}
17+
18+
sourceSets {
19+
main.java.srcDirs = ['src']
20+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.habr.j17.manual.fewmodules.together.dependency;
2+
3+
public class Cat {
4+
public void talk() {
5+
System.out.println("Meow");
6+
}
7+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module manual.fewmodules.together.dependency {
2+
exports com.habr.j17.manual.fewmodules.together.dependency;
3+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
plugins {
2+
id 'java'
3+
id 'application'
4+
}
5+
6+
group = 'com.habr.j17.manual.fewmodules.together.dependent'
7+
version = '1.0'
8+
9+
layout.buildDirectory = getParent().layout.buildDirectory
10+
11+
compileJava {
12+
java {
13+
toolchain {
14+
languageVersion = JavaLanguageVersion.of(17)
15+
}
16+
}
17+
}
18+
19+
application {
20+
mainClassName = 'com.habr.j17.manual.fewmodules.together.dependent.Main'
21+
}
22+
23+
dependencies {
24+
implementation project(':java-17:manual:few-modules:together:dependency')
25+
}
26+
27+
sourceSets {
28+
main.java.srcDirs = ['src']
29+
}
30+
31+
jar {
32+
manifest {
33+
attributes(
34+
"Main-Class": application.mainClass
35+
)
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.habr.j17.manual.fewmodules.together.dependent;
2+
3+
import java.io.ByteArrayOutputStream;
4+
import java.io.File;
5+
import java.io.IOException;
6+
import java.io.InputStream;
7+
8+
public class CustomClassLoader extends ClassLoader {
9+
@Override
10+
public Class<?> loadClass(String name) throws ClassNotFoundException {
11+
synchronized (getClassLoadingLock(name)) {
12+
Class<?> c = findLoadedClass(name);
13+
if (c != null)
14+
return c;
15+
16+
String APP_GROUP = "com.habr";
17+
if (name.startsWith(APP_GROUP)) {
18+
System.out.println("CCL: Loading " + name);
19+
c = loadClassFromFile(name);
20+
21+
if (c != null)
22+
return c;
23+
}
24+
25+
System.out.println("CCL: Delegating " + name);
26+
return super.loadClass(name);
27+
}
28+
}
29+
30+
private Class<?> loadClassFromFile(String name) {
31+
String classFile = name.replace('.', File.separatorChar) + ".class";
32+
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(classFile)) {
33+
if (inputStream == null)
34+
throw new RuntimeException();
35+
36+
byte[] buffer;
37+
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
38+
39+
int nextValue;
40+
while ((nextValue = inputStream.read()) != -1) {
41+
byteStream.write(nextValue);
42+
}
43+
44+
buffer = byteStream.toByteArray();
45+
return defineClass(name, buffer, 0, buffer.length);
46+
} catch (RuntimeException | IOException e) {
47+
throw new RuntimeException("Failed to read from input stream", e);
48+
}
49+
}
50+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.habr.j17.manual.fewmodules.together.dependent;
2+
3+
import java.lang.reflect.InvocationTargetException;
4+
import java.lang.reflect.Method;
5+
6+
public class Main {
7+
public static void main(String[] args) {
8+
ClassLoader customClassLoader = new CustomClassLoader();
9+
try {
10+
Class<?> catClass = customClassLoader.loadClass(
11+
"com.habr.j17.manual.fewmodules.together.dependency.Cat");
12+
Object cat = catClass.getDeclaredConstructor().newInstance();
13+
14+
System.out.println("System ClassLoader is " + ClassLoader.getSystemClassLoader());
15+
System.out.println("Cat Class ClassLoader is " + catClass.getClassLoader());
16+
17+
System.out.println("Main Class Module is " + Main.class.getModule());
18+
System.out.println("Cat Class Module is " + catClass.getModule());
19+
20+
Method talkMethod = catClass.getMethod("talk");
21+
talkMethod.invoke(cat);
22+
} catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | InstantiationException |
23+
IllegalAccessException e) {
24+
throw new RuntimeException(e);
25+
}
26+
}
27+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module manual.fewmodules.together.dependent {
2+
requires manual.fewmodules.together.dependency;
3+
}

settings.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,8 @@ include 'java-8:auto'
66
include 'java-17:manual:one-module:java8style'
77
include 'java-17:manual:one-module:java17style'
88

9+
include 'java-17:manual:few-modules:together:dependency'
10+
include 'java-17:manual:few-modules:together:dependent'
11+
912
include 'java-17:auto:one-module:java8style'
1013
include 'java-17:auto:one-module:java17style'

0 commit comments

Comments
 (0)