-
Notifications
You must be signed in to change notification settings - Fork 0
VM Classloader
JVM classloader implementation with plugin delegation.
JNode's VM classloader system bridges the JVM's class loading requirements with JNode's plugin-based architecture. The core abstraction is VmClassLoader (org.jnode.vm.classmgr.VmClassLoader), an abstract base class that extends VmSystemObject and defines the contract for loading classes into the VM. Unlike standard Java where ClassLoader is the primary interface, JNode's VmClassLoader is designed around the needs of a native OS: class definition from ByteBuffer/byte[], resource loading, statics management, JIT compiler integration, and architecture-aware IMT compilation.
The classloader hierarchy serves two distinct purposes. The first is the Java classloader delegation chain — the standard parent-first lookup pattern — which JNode implements via VmSystemClassLoader.loadClass() delegating to a ClassLoaderWrapper. The second is plugin-based class isolation — each plugin gets its own PluginClassLoaderImpl, which can only see classes from its own JAR and its declared prerequisites. These two systems are bridged by VmJavaClassLoader, which wraps a Java ClassLoader and converts Class<?> objects to VmType<?> instances.
| Class / File | Role |
|---|---|
core/src/core/org/jnode/vm/classmgr/VmClassLoader.java |
Abstract base class for all VM classloaders |
core/src/core/org/jnode/vm/VmAbstractClassLoader.java |
Common defineClass logic, array class loading, security checks |
core/src/core/org/jnode/vm/VmSystemClassLoader.java |
Default system classloader; loads from URLs, systemRtJar, or ResourceLoaders |
core/src/core/org/jnode/vm/VmJavaClassLoader.java |
Wraps a Java ClassLoader, converts Class<?> to VmType<?>
|
core/src/core/org/jnode/plugin/model/PluginClassLoaderImpl.java |
Per-plugin classloader: loads from plugin JAR, delegates to prerequisites |
core/src/core/org/jnode/plugin/model/PluginsClassLoader.java |
Aggregator that searches all non-system plugin classloaders |
BootClassLoader (VM built-in — no Java representation)
└── VmSystemClassLoader (default system classloader, ~ClassLoader.getSystemClassLoader())
├── VmJavaClassLoader [wraps arbitrary ClassLoaders]
└── ClassLoaderWrapper [bridges VmClassLoader to java.lang.ClassLoader]
The VmSystemClassLoader.loadClass(name, resolve) method implements the standard delegation:
- Check parent
ClassLoaderfirst (viaparent.loadClass(name)) - Check if class is already loaded via
findLoadedClass(name) - Load from the boot class path:
- If
systemRtJaris set: look up in the JAR map, then in registeredResourceLoaders - Otherwise: open a resource stream from
classesURLand read.classbytes
- If
- Call
ClassDecoder.defineClass()to parse bytecode into aVmType - If
resolveis true, callvmClass.link()to prepare the class
The key design choice is that VmSystemClassLoader enforces that only it can define java.lang.* and org.jnode.vm.* classes (via the isSystemClassLoader() check in VmAbstractClassLoader.defineClass()).
Array classes (byte[], MyClass[], etc.) are handled specially in VmAbstractClassLoader.loadArrayClass(). For reference arrays, the component type is loaded recursively, then VmType.getArrayClass() constructs the array class. Primitive arrays use predefined singletons from VmType.getPrimitiveArrayClass().
Plugin classloaders (PluginClassLoaderImpl) work alongside the VM classloader system:
- Each plugin has a
PluginClassLoaderImplthat loads from its JAR -
findPluginClass()checks prerequisite plugin classloaders first (dependency chain) - Falls back to
findLoadedClass(), then fragment JARs, then the plugin's own JAR - On successful class load, the plugin is started automatically
- A
PluginsClassLoaderaggregates all non-system plugin classloaders as a fallback
VmAbstractClassLoader.defineClass() synchronizes on the classloader instance and:
- Checks if the class is already loaded (returns the cached instance)
- Calls
LoadCompileService.defineClass()to parse bytecode and create theVmType - Verifies the class belongs to a package the classloader is allowed to define
- Adds the class to the loaded classes map
VmClassLoader provides methods for JIT compiler support:
-
getArchitecture()— returnsVmArchitecturefor ISA-specific compilation -
compileIMT(IMTBuilder)— generates architecture-specific interface method table code -
disassemble(VmMethod, ...)— dumps compiled method bytecode for debugging -
getSelectorMap()— maps method signatures to unique selectors -
getSharedStatics()/getIsolatedStatics()— access static field storage
-
Bootstrap class gating —
VmSystemClassLoadersetsfailOnNewLoadduring boot image initialization to catch unexpected dynamic class loading. OnceprepareAfterBootstrap()is called, normal class loading resumes. -
Security restriction on class definition —
VmAbstractClassLoader.defineClass()throwsSecurityExceptionif a non-system classloader attempts to defineorg.jnode.vm.*orjava.lang.*classes. This prevents plugins from injecting classes into protected namespaces. -
Array class cache — Array classes are cached on the component
VmTypeviaVmType.getArrayClass(). The same array class instance is returned for repeatedObject[]lookups. -
Parent-first is advisory — The
parent.skipParentLoader(name)check inVmSystemClassLoaderallows certain classes to bypass the parent loader. This is used to redirect core classes back to the VM's built-in mechanisms. -
Plugin classloader delegation —
PluginClassLoaderImpl.findPluginClass()tries prerequisite loaders BEFORE checkingfindLoadedClass(). This means dependency classes are always loaded from their owning plugin, not from a parent that may have cached a different version. -
ClassInfo wait/notify —
VmSystemClassLoader.ClassInfouseswait()/notifyAll()for concurrent class loading. Multiple threads requesting the same class block until the first thread completes the load.
- Type-System-Internals — VmType hierarchy, class loading pipeline
- Plugin-System — Plugin architecture, classloader hierarchy
- Class-Library-Integration — Integration with GNU Classpath/OpenJDK
- Build---BootImageBuilder-Internals — Boot image class pre-loading
- JIT-Compilers — Compilation and IMT generation via classloaders
- TIB — Type Information Block constructed during class preparation
- Virtual-Methods-Dispatch — Method dispatch requiring classloader support