+struct CYJava :
+ CYRoot
+{
+ CYJavaGlobal<jobject> loader_;
+ jmethodID ClassLoader$loadClass;
+
+ CYJava() {
+ }
+
+ bool Setup(JNIEnv *env) {
+ if (loader_)
+ return false;
+
+ CYJavaEnv jni(env);
+ CYPool pool;
+
+ auto ClassLoader$(jni.FindClass("java/lang/ClassLoader"));
+ ClassLoader$loadClass = jni.GetMethodID(ClassLoader$, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
+
+ auto ClassLoader$getSystemClassLoader(jni.GetStaticMethodID(ClassLoader$, "getSystemClassLoader", "()Ljava/lang/ClassLoader;"));
+ auto parent(jni.CallStaticObjectMethod<jobject>(ClassLoader$, ClassLoader$getSystemClassLoader));
+
+ auto path(CYCastJavaString(jni, pool.strcat("file://", CYPoolLibraryPath(pool), "/libcycript.jar", NULL)));
+
+ auto PathClassLoader$(jni.FindClass$("dalvik/system/PathClassLoader"));
+ if (PathClassLoader$) {
+ auto PathClassLoader$$init$(jni.GetMethodID(PathClassLoader$, "<init>", "(Ljava/lang/String;Ljava/lang/ClassLoader;)V"));
+ loader_ = jni.NewObject(PathClassLoader$, PathClassLoader$$init$, path.get(), parent.get());
+ } else {
+ auto URL$(jni.FindClass("java/net/URL"));
+ auto URL$$init$(jni.GetMethodID(URL$, "<init>", "(Ljava/lang/String;)V"));
+
+ auto URLClassLoader$(jni.FindClass("java/net/URLClassLoader"));
+ auto URLClassLoader$$init$(jni.GetMethodID(URLClassLoader$, "<init>", "([Ljava/net/URL;Ljava/lang/ClassLoader;)V"));
+
+ auto url(jni.NewObject(URL$, URL$$init$, path.get()));
+ auto urls(jni.NewObjectArray(1, URL$, url));
+ // XXX: .cast().get() <- this is required :/
+ loader_ = jni.NewObject(URLClassLoader$, URLClassLoader$$init$, urls.cast<jobject>().get(), parent.get());
+ }
+
+ return true;
+ }
+
+ CYJavaLocal<jclass> LoadClass(const char *name) {
+ _assert(loader_);
+ CYJavaEnv jni(loader_);
+ return jni.CallObjectMethod<jclass>(loader_, ClassLoader$loadClass, CYCastJavaString(jni, name).get());
+ }
+};
+