Skip to content

Commit 3288f74

Browse files
committed
Support for slf4j-jdk-platform-logging with GraalVM (build time initialization)
Will do build time initialization of avaje simple logger classes with graalvm native image, and thus support the use of slf4j-jdk-platform-logging. This is required due to graalvm native-image wanting to initialise jdk logging at build time (which is a bit viral and means the logger implementation needs to support build time initialisation as well).
1 parent fa30f70 commit 3288f74

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

avaje-simple-logger/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@
4444
<artifactId>avaje-config</artifactId>
4545
<version>4.2</version>
4646
</dependency>
47+
<dependency>
48+
<groupId>org.graalvm.nativeimage</groupId>
49+
<artifactId>svm</artifactId>
50+
<version>25.0.1</version>
51+
<scope>provided</scope>
52+
</dependency>
4753

4854
<dependency>
4955
<groupId>io.avaje</groupId>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package io.avaje.simplelogger.graalvm;
2+
3+
import org.graalvm.nativeimage.hosted.Feature;
4+
import org.graalvm.nativeimage.hosted.RuntimeClassInitialization;
5+
6+
/**
7+
* GraalVM Native Image build Feature that initialises Simple Logger classes at Build time.
8+
* <p>
9+
* Use this when using slf4j-jdk-platform-logging to redirect System.Logger to slf4j. This
10+
* is needed as GraalVM by default initialised JDK logging at build time. Adding this
11+
* feature supports redirecting System.Logger to avaje simple logger by also initialising
12+
* the avaje simple logger classes at build time.
13+
* </p>
14+
*/
15+
public class BuildInitialization implements Feature {
16+
17+
@Override
18+
public void beforeAnalysis(BeforeAnalysisAccess access) {
19+
20+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.simplelogger.encoder.FilterBuilder$PatternFilter"));
21+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.simplelogger.encoder.FilterBuilder$ReflectiveInvocation"));
22+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.simplelogger.encoder.FilterBuilder$SpringFilter"));
23+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.simplelogger.encoder.FilterBuilder$Generated"));
24+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.simplelogger.encoder.FilterBuilder$Group"));
25+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.simplelogger.encoder.FilterBuilder$JDKInternals"));
26+
27+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.simplelogger.encoder.StackElementFilter"));
28+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.simplelogger.encoder.AbbreviatorByLength"));
29+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.simplelogger.encoder.AbbreviatorCaching"));
30+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.simplelogger.encoder.StackHasher"));
31+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.simplelogger.encoder.ThrowableConverter"));
32+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.simplelogger.encoder.JsonEncoder"));
33+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.simplelogger.encoder.JsonWriter"));
34+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.simplelogger.encoder.SimpleLogger"));
35+
36+
37+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.json.stream.core.JsonNames"));
38+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.json.stream.core.CoreJsonStream"));
39+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.json.stream.core.HybridBufferRecycler$XorShiftThreadProbe"));
40+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.json.stream.core.HybridBufferRecycler"));
41+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.json.stream.core.HybridBufferRecycler$StripedLockFreePool"));
42+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("io.avaje.json.stream.core.Recyclers$ThreadLocalPool"));
43+
44+
// check for optional SLF4JPlatformLogger
45+
Class<?> slfPlatform = access.findClassByName("org.slf4j.jdk.platform.logging.SLF4JPlatformLogger");
46+
if (slfPlatform != null) {
47+
RuntimeClassInitialization.initializeAtBuildTime(slfPlatform);
48+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("org.slf4j.jdk.platform.logging.SLF4JPlatformLoggerFactory"));
49+
RuntimeClassInitialization.initializeAtBuildTime(access.findClassByName("org.slf4j.jdk.platform.logging.SLF4JSystemLoggerFinder"));
50+
}
51+
}
52+
53+
}

avaje-simple-logger/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
requires transitive io.avaje.simplelogger;
99
requires transitive io.avaje.config;
1010
requires io.avaje.applog;
11+
requires static org.graalvm.nativeimage;
1112

1213
provides io.avaje.config.ConfigExtension with DynamicLogLevels;
1314
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Args=--no-fallback \
2+
--features=io.avaje.simplelogger.graalvm.BuildInitialization

0 commit comments

Comments
 (0)