@@ -131,29 +131,47 @@ impl URLClassLoader {
131131 let urls: Vec < ClassInstanceRef < URL > > = jvm. load_array ( & urls, 0 , jvm. array_length ( & urls) . await ? as _ ) . await ?;
132132
133133 for url in urls {
134- let file = jvm. invoke_virtual ( & url, "java/net/URL" , "getFile" , "()Ljava/lang/String;" , ( ) ) . await ?;
134+ let file: ClassInstanceRef < String > = jvm. invoke_virtual ( & url, "java/net/URL" , "getFile" , "()Ljava/lang/String;" , ( ) ) . await ?;
135+ let path = jvm
136+ . invoke_static (
137+ "org/rustjava/net/URLPath" ,
138+ "decode" ,
139+ "(Ljava/lang/String;)Ljava/lang/String;" ,
140+ ( file. clone ( ) , ) ,
141+ )
142+ . await ?;
135143 let file = JavaLangString :: to_rust_string ( jvm, & file) . await ?;
144+ let path = JavaLangString :: to_rust_string ( jvm, & path) . await ?;
136145
137- let metadata = runtime. metadata ( & file ) . await ;
138- if file . ends_with ( '/' ) || file . is_empty ( ) || metadata. as_ref ( ) . is_ok_and ( |metadata| metadata. r#type == FileType :: Directory ) {
146+ let metadata = runtime. metadata ( & path ) . await ;
147+ if path . ends_with ( '/' ) || path . is_empty ( ) || metadata. as_ref ( ) . is_ok_and ( |metadata| metadata. r#type == FileType :: Directory ) {
139148 // directory
140- let final_path = if file . is_empty ( ) {
149+ let final_path = if path . is_empty ( ) {
141150 name_str. clone ( )
142- } else if file . ends_with ( '/' ) {
143- format ! ( "{file }{name_str}" )
151+ } else if path . ends_with ( '/' ) {
152+ format ! ( "{path }{name_str}" )
144153 } else {
145- format ! ( "{file }/{name_str}" )
154+ format ! ( "{path }/{name_str}" )
146155 } ;
147156
148157 if runtime. metadata ( & final_path) . await . is_ok ( ) {
158+ let final_path = JavaLangString :: from_rust_string ( jvm, & final_path) . await ?;
159+ let final_path: ClassInstanceRef < String > = jvm
160+ . invoke_static (
161+ "org/rustjava/net/URLPath" ,
162+ "encode" ,
163+ "(Ljava/lang/String;)Ljava/lang/String;" ,
164+ ( final_path, ) ,
165+ )
166+ . await ?;
149167 let new_url = jvm
150168 . new_class (
151169 "java/net/URL" ,
152170 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V" ,
153171 (
154172 JavaLangString :: from_rust_string ( jvm, "file" ) . await ?,
155173 JavaLangString :: from_rust_string ( jvm, "" ) . await ?,
156- JavaLangString :: from_rust_string ( jvm , & final_path) . await ? ,
174+ final_path,
157175 ) ,
158176 )
159177 . await ?;
@@ -165,8 +183,12 @@ impl URLClassLoader {
165183 } else {
166184 // treat as jar
167185 let name_str = name_str. trim_start_matches ( '/' ) ;
168-
169- let jar_url_str = format ! ( "jar:file:{file}!/{name_str}" ) ; // TODO url might not be file
186+ let entry = JavaLangString :: from_rust_string ( jvm, name_str) . await ?;
187+ let entry = jvm
188+ . invoke_static ( "org/rustjava/net/URLPath" , "encode" , "(Ljava/lang/String;)Ljava/lang/String;" , ( entry, ) )
189+ . await ?;
190+ let entry = JavaLangString :: to_rust_string ( jvm, & entry) . await ?;
191+ let jar_url_str = format ! ( "jar:file:{file}!/{entry}" ) ; // TODO url might not be file
170192 let jar_url = JavaLangString :: from_rust_string ( jvm, & jar_url_str) . await ?;
171193 let jar_url = jvm. new_class ( "java/net/URL" , "(Ljava/lang/String;)V" , ( jar_url, ) ) . await ?;
172194 let connection: ClassInstanceRef < JarURLConnection > = jvm
0 commit comments