-
Notifications
You must be signed in to change notification settings - Fork 7
Java Versions and Toolchains
EverNifeCore compiles modern Java source and ships Java 8 bytecode for the modules that must run on old Minecraft servers - all from a single JDK 25 toolchain, with no compiler pin anywhere. This page explains how that works and where the exceptions are.
The rules live in the root build.gradle; the version numbers live in the version catalog
(gradle/libs.versions.toml). See Building from Source for the build
commands.
Launch Gradle with JDK 25 and it compiles and runs everything, tests included. The root build applies a single toolchain to every subproject:
java {
toolchain.languageVersion = JavaLanguageVersion.of(25)
}There is no separate compiler pin anywhere in the build. Gradle, the production compile, the test compile and the test execution all run on that one Java 25 toolchain. Older setups pinned JDK 17 for the dual-target compile; that pin is gone (see "Jabel" below).
Every configuration is also tagged TargetJvmVersion = 25, which lets the Java-8-bytecode modules
still resolve JVM-11+ dependencies on the compile classpath.
Four modules must run on a Java 8 JVM (a 1.7.10 server can be that old) yet are written in modern Java. They are the dual-target set:
:api-contracts :common :libby :minecraft
For these, the root build applies:
compileJava {
sourceCompatibility = 25 // modern *syntax* (an IDE/javac hint; Jabel lifts the source check)
options.release = 8 // Java 8 *bytecode* and Java 8 *API* floor
}Two things are pinned here, and they are different:
-
options.release = 8caps both the emitted bytecode (runs on a Java 8 JVM) and the API floor (no Java 9+ library API can slip into code that has to run on an old server). - Jabel lifts javac's source-level check so the Java 25 compiler accepts modern syntax while still emitting Java 8 bytecode.
Jabel is the FinalCraft fork br.com.finalcraft:jabel (the same one EveryDatabase and EveryConfig
use), applied as an annotation processor on the dual-target modules. It lets you write var, switch
expressions, and text blocks and have them downgraded to Java 8 bytecode.
The upstream
bsideupJabel could not hook a javac newer than 17 - that was the only reason the old JDK 17 pin existed. The FinalCraft fork works on JDK 25, so the pin is gone.
Not available in the dual-target modules: record and sealed. Those have no Java 8 bytecode
form Jabel can produce, so they are off-limits in common, minecraft, api-contracts, and
libby. (They are fine in hytale - see below.)
The four version-compatibility modules use a different rule - plain source/targetCompatibility = 1.8, no Jabel, no options.release:
:minecraft:modules:v1_7_10 :minecraft:modules:v1_12_2
:minecraft:modules:v1_16_5 :minecraft:modules:VersionedPlugins
This is deliberate and must not be "fixed" to options.release = 8. These modules reach for
sun.misc.Unsafe (through UnsafeUtil, and ImpIFCFlagRegistry on top of it) to rewrite a final
field in WorldGuard's flag registry. options.release deliberately hides the JDK's internal
packages, so switching to it fails to compile. The old source/target pair is what keeps sun.misc
reachable.
The trade-off: these four modules get no API floor. Only code review stops a Java 9+ API from reaching a 1.7.10 server. They are plain Java 8 syntax, so no Jabel and no modern-syntax features.
For what these modules actually do (WorldGuard compatibility, not NMS), see Version Compatibility.
hytale is deliberately not in the dual-target set. It is plain Java 25 - the Java 25 toolchain,
no Jabel, no bytecode cap. Records, sealed types, and modern library APIs are all fine there,
because Hytale targets a modern runtime. See Hytale Platform.
| Module(s) | Bytecode | Compiler | Modern syntax |
record/sealed
|
API floor |
|---|---|---|---|---|---|
common, minecraft, api-contracts, libby
|
Java 8 | JDK 25 + Jabel + release=8
|
yes (var, switch expr, text blocks) |
no | Java 8 |
minecraft:modules:* |
Java 8 | JDK 25, source/target=1.8
|
no | no | none (review only) |
hytale |
Java 25 | JDK 25 | yes | yes | Java 25 |
Other build facts worth knowing:
-
Lombok (
1.18.46) is declared once at the root for every subproject. -
Test code is never capped. In every module the tests compile and run on the full Java 25 API,
even where
mainis capped to Java 8 - so tests can use records, modern collections, etc. -
FCScheduleruses virtual threads on Java 21+ (via EveryLibs'VirtualThreadedScheduledExecutor), falling back to a fixed thread pool bounded to the CPU core count on older JVMs. See Scheduler and Threading.
-
Building from Source - JDK setup,
gradlewcommands, private deps. -
Platform Abstraction - why
api-contractsandcommonare dual-target. - Hytale Platform - the plain-Java-25 module.
-
Version Compatibility - the
sun.misc.Unsafemodules in context.
EverNifeCore · Home · made by Petrus Pradella
Getting Started
Commands & Text
Player Data & Storage
- PlayerData & PDSections
- Accounts
- Storage Backends
- Inline Backends for Plugins
- Legacy Data Migration
- Cooldowns
Config & Minecraft Systems
- Configuration
- Scheduler & Threading
- Items & NBT
- GUI Framework
- Integrations
- Economy
- Version Compatibility
Architecture & Reference