Skip to content

Commit b8e87a5

Browse files
committed
Add java/lang/Class::forName
1 parent 1ebc736 commit b8e87a5

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use alloc::vec;
22

33
use java_class_proto::{JavaFieldProto, JavaMethodProto};
4+
use java_constants::MethodAccessFlags;
45
use jvm::{
56
ClassInstanceRef, Jvm, Result,
67
runtime::{JavaLangClass, JavaLangClassLoader, JavaLangString},
@@ -33,6 +34,12 @@ impl Class {
3334
Self::get_resource_as_stream,
3435
Default::default(),
3536
),
37+
JavaMethodProto::new(
38+
"forName",
39+
"(Ljava/lang/String;)Ljava/lang/Class;",
40+
Self::for_name,
41+
MethodAccessFlags::STATIC,
42+
),
3643
],
3744
fields: vec![
3845
JavaFieldProto::new("raw", "[B", Default::default()), // raw rust pointer of Box<dyn Class>
@@ -87,4 +94,14 @@ impl Class {
8794
jvm.invoke_virtual(&class_loader, "getResourceAsStream", "(Ljava/lang/String;)Ljava/io/InputStream;", (name,))
8895
.await
8996
}
97+
98+
async fn for_name(jvm: &Jvm, _context: &mut RuntimeContext, name: ClassInstanceRef<String>) -> Result<ClassInstanceRef<Class>> {
99+
tracing::debug!("java.lang.Class::forName({:?})", &name);
100+
101+
let rust_name = JavaLangString::to_rust_string(jvm, &name).await?;
102+
let qualified_name = rust_name.replace('.', "/");
103+
let class = jvm.get_class(&qualified_name).unwrap().java_class();
104+
105+
Ok(class.into())
106+
}
90107
}

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
use jvm::{Result, runtime::JavaLangClass};
1+
use java_runtime::classes::java::lang::Class;
2+
use jvm::{
3+
ClassInstanceRef, Result,
4+
runtime::{JavaLangClass, JavaLangString},
5+
};
26

37
use test_utils::test_jvm;
48

@@ -39,3 +43,18 @@ async fn test_is_assignable_from() -> Result<()> {
3943

4044
Ok(())
4145
}
46+
47+
#[tokio::test]
48+
async fn test_for_name() -> Result<()> {
49+
let jvm = test_jvm().await?;
50+
51+
let class_name = JavaLangString::from_rust_string(&jvm, "java.lang.String").await?;
52+
let class: ClassInstanceRef<Class> = jvm
53+
.invoke_static("java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", (class_name,))
54+
.await?;
55+
56+
let rust_class = JavaLangClass::to_rust_class(&jvm, &class).await?;
57+
assert_eq!(rust_class.name(), "java/lang/String");
58+
59+
Ok(())
60+
}

0 commit comments

Comments
 (0)