Skip to content

Commit 3d915ed

Browse files
committed
Delegate null-parent class loading to bootstrap
1 parent 423d1bd commit 3d915ed

3 files changed

Lines changed: 16 additions & 7 deletions

File tree

java_runtime/src/classes/java/lang/class_loader.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ impl ClassLoader {
183183
jvm.invoke_virtual(&parent, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", (name.clone(),))
184184
.await?
185185
} else {
186-
None.into()
186+
jvm.load_bootstrap_class(&name_str).await?.into()
187187
};
188188

189189
if !class.is_null() {

java_runtime/tests/classes/java/lang/test_class.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,16 @@ async fn test_cldc_class_queries_and_new_instance() -> Result<()> {
246246
}
247247

248248
#[tokio::test]
249-
async fn test_base_class_loader_find_class_throws() -> Result<()> {
249+
async fn test_base_class_loader_delegates_to_bootstrap_and_find_class_throws() -> Result<()> {
250250
let jvm = test_jvm().await?;
251251
let loader = jvm.new_class("java/lang/ClassLoader", "(Ljava/lang/ClassLoader;)V", (None,)).await?;
252+
253+
let name = JavaLangString::from_rust_string(&jvm, "java/util/Random").await?;
254+
let class: ClassInstanceRef<Class> = jvm
255+
.invoke_virtual(&loader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", (name,))
256+
.await?;
257+
assert!(!class.is_null());
258+
252259
let name = JavaLangString::from_rust_string(&jvm, "missing.Type").await?;
253260

254261
let result: Result<ClassInstanceRef<Class>> = jvm

jvm/src/jvm.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,13 @@ impl Jvm {
573573
self.resolve_class_internal(class_name, None).await
574574
}
575575

576+
pub async fn load_bootstrap_class(&self, class_name: &str) -> Result<Option<Box<dyn ClassInstance>>> {
577+
let class = BootstrapClassLoaderWrapper::new(&*self.inner.bootstrap_class_loader)
578+
.load_class(self, class_name)
579+
.await?;
580+
Ok(class.map(|class| class.java_class()))
581+
}
582+
576583
#[async_recursion::async_recursion]
577584
async fn resolve_class_internal(&self, class_name: &str, class_loader_wrapper: Option<&dyn ClassLoaderWrapper>) -> Result<Class> {
578585
tracing::trace!("Resolving class {class_name}");
@@ -722,11 +729,6 @@ impl Jvm {
722729
pub async fn exception(&self, r#type: &str, message: &str) -> JavaError {
723730
tracing::info!("throwing java exception: {} {message}", r#type);
724731

725-
if !self.has_class(r#type) {
726-
self.resolve_class_internal(r#type, Some(&BootstrapClassLoaderWrapper::new(&*self.inner.bootstrap_class_loader)))
727-
.await
728-
.unwrap();
729-
}
730732
let message_str = JavaLangString::from_rust_string(self, message).await.unwrap();
731733
let instance = self.new_class(r#type, "(Ljava/lang/String;)V", (message_str,)).await.unwrap();
732734

0 commit comments

Comments
 (0)