# Class Loading and Boot Image **Location**: `crates/core/src/class_loader.rs`, `crates/core/src/bimage.rs` ## Boot Image (Bimage) A 7z archive containing precompiled Java standard library classes. ### Structure ```rust pub struct Bimage { image: ArchiveReader, // 7z archive reader modules: Vec, // Available modules packages: HashMap, // Package -> Module mapping pub total_access_time: Duration, // Performance tracking } ``` - **Default Location**: `./lib/modules` - **Format**: 7z compressed archive - **Structure**: `/classes/.class` - **Default Module**: `java.base` (used when no module is specified) ## Class Loading Flow The `ClassLoader` manages class resolution with a two-tier fallback mechanism: ### Process 1. **Check Cache**: Look in `DashMap<(String, LoaderId), Arc>` for already-loaded classes 2. **Try Bimage**: Attempt to load from boot image via `bimage.get_class(module, class_fqn)` 3. **Fallback to Disk**: If not in bimage, load from filesystem at `{CLASSPATH}/{class_name}.class` 4. **Parse & Cache**: Parse ClassFile using deku, create RuntimeClass, store in cache ### Key Method ```rust pub fn load_class(&mut self, what: &str, loader: LoaderId) -> Result, VmError> { let bytes = self.bimage .and_then(|b| b.get_class("", what).ok()) .or_else(|_| Self::load_class_from_disk(what)) .map_err(|_| VmError::LoaderError(...))?; let (_, cf) = ClassFile::from_bytes(bytes.as_ref())?; let runtime = self.runtime_class(cf); // Store with loader ID for multi-loader support self.classes.insert((class_fqn, loader), Arc::new(runtime)); } ``` ## Classpath Handling ### Resolution Priority 1. **Bimage (boot image)** - Primary source for standard library 2. **Command-line argument (arg[1])** - User-provided classpath 3. **Default `./data` directory** - Fallback location ### Implementation ```rust fn load_class_from_disk(what: &str) -> Result, String> { let class_path = std::env::args() .nth(1) .unwrap_or("./data".to_string()) .replace("\\", "/"); let path = format!("{class_path}/{what}.class"); // Load file from disk } ``` ## Bootstrap Process **Location**: `crates/core/src/vm.rs` - `boot_strap()` method ### Steps 1. **Create VM**: `ClassLoader::with_bimage()` - initializes with boot image 2. **Load Core Classes**: Preloads essential VM classes 3. **Create Primitive Classes**: Synthetic class objects for primitive types 4. **Initialize Classes**: Run static initializers (``) ### Core Classes Loaded ```rust let classes = vec![ "java/lang/String", "java/lang/System", "java/lang/Class", "java/lang/Object", "java/lang/Thread", "java/lang/ThreadGroup", "java/lang/Module", "java/lang/reflect/Method", // ... ]; ``` ## RuntimeClass Runtime representation of a loaded class: ### Cached Data - **Superclass Chain**: `super_classes: Vec>` - **Interface Hierarchy**: `super_interfaces: Vec>` - **Component Type**: For array classes, reference to element type - **Initialization State**: Thread-safe `InitState` enum ### Initialization States ```rust pub enum InitState { NotInitialized, Initializing(ThreadId), // Track which thread is initializing Initialized, } ``` ### Method/Field Resolution - `find_method()` - Searches class then walks up superclass chain - `find_field()` - Same recursive behavior for fields - `is_assignable_into()` - Checks type compatibility with array covariance ## Multi-Loader Support Classes are keyed by `(class_name, LoaderId)` tuple to support: - Different class loaders loading same-named classes - Isolation between class loader namespaces - Proper class identity checks