From f45b95e1b556943fc5cbb81de0a367f9e88d1c21 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 19 Feb 2013 16:48:33 -0700 Subject: [PATCH] progress towards Android classpath support It now builds and links, but fails at runtime because register_libcore_icu_ICU can't find the file it wants. We'll probably need to replace register_libcore_icu_ICU with a better-behaved version. --- makefile | 19 +++++- src/classpath-android.cpp | 133 +++++++++++++++++++++++++++++++++++++- src/jnienv.cpp | 2 +- 3 files changed, 148 insertions(+), 6 deletions(-) diff --git a/makefile b/makefile index 1d9ade13f4..a50fc6cb53 100755 --- a/makefile +++ b/makefile @@ -166,7 +166,16 @@ ifneq ($(android),) -fpermissive \ -fno-exceptions \ -DHAVE_SYS_UIO_H \ - -D_FILE_OFFSET_BITS=64 + -D_FILE_OFFSET_BITS=64 \ + -g3 + classpath-lflags := $(android)/icu4c/lib/libicuuc.a \ + $(android)/icu4c/lib/libicui18n.a \ + $(android)/icu4c/lib/libicudata.a \ + $(android)/fdlibm/libfdm.a \ + $(android)/expat/.libs/libexpat.a \ + $(android)/openssl-1.0.1e/libssl.a \ + $(android)/openssl-1.0.1e/libcrypto.a \ + -lstdc++ luni-cpps := $(shell find $(luni-native) -name '*.cpp') classpath-objects = \ $(call cpp-objects,$(luni-cpps),$(luni-native),$(build)) @@ -279,7 +288,7 @@ common-lflags = -lm -lz $(classpath-lflags) build-lflags = -lz -lpthread -ldl -lflags = $(common-lflags) -lpthread -ldl +lflags = $(common-lflags) $(classpath-lflags) -lpthread -ldl soname-flag = -Wl,-soname -Wl,$(so-prefix)jvm$(so-suffix) version-script-flag = -Wl,--version-script=openjdk.ld @@ -1217,7 +1226,10 @@ ifneq ($(classpath),avian) classpath-sources := $(classpath-sources) \ $(classpath-src)/sun/reflect/ConstantPool.java \ $(classpath-src)/java/lang/ReflectiveOperationException.java \ - $(classpath-src)/sun/misc/Cleaner.java + $(classpath-src)/java/net/ProtocolFamily.java \ + $(classpath-src)/java/net/StandardProtocolFamily.java \ + $(classpath-src)/sun/misc/Cleaner.java \ + $(classpath-src)/sun/misc/Unsafe.java endif else classpath-sources := $(shell find $(classpath-src) -name '*.java') @@ -1413,6 +1425,7 @@ $(build)/android.dep: $(luni-javas) $(dalvik-javas) $(xml-javas) find $(build)/android-src -name '*.java' > $(build)/android.txt $(javac) -Xmaxerrs 1000 -d $(build)/android -sourcepath $(luni-java) \ @$(build)/android.txt + rm $(build)/android/sun/misc/Unsafe* cp -r $(build)/android/* $(classpath-build) @touch $(@) diff --git a/src/classpath-android.cpp b/src/classpath-android.cpp index 3fe5996aec..d50be47057 100644 --- a/src/classpath-android.cpp +++ b/src/classpath-android.cpp @@ -8,6 +8,12 @@ There is NO WARRANTY for this software. See license.txt for details. */ +struct JavaVM; + +extern "C" int JNI_OnLoad(JavaVM*, void*); + +#define _POSIX_C_SOURCE 200112L +#undef _GNU_SOURCE #include "machine.h" #include "classpath-common.h" #include "process.h" @@ -130,9 +136,9 @@ class MyClasspath : public Classpath { } virtual void - boot(Thread*) + boot(Thread* t) { - // ignore + JNI_OnLoad(reinterpret_cast< ::JavaVM*>(t->m), 0); } virtual const char* @@ -170,3 +176,126 @@ makeClasspath(System*, Allocator* allocator, const char*, const char*) } } // namespace vm + +extern "C" int +jniRegisterNativeMethods(JNIEnv* e, const char* className, + const JNINativeMethod* methods, int methodCount) +{ + jclass c = e->vtable->FindClass(e, className); + + if (c) { + e->vtable->RegisterNatives(e, c, methods, methodCount); + } + + return 0; +} + +extern "C" void +jniLogException(JNIEnv*, int, const char*, jthrowable) +{ + // ignore +} + +extern "C" int +jniThrowException(JNIEnv* e, const char* className, const char* message) +{ + jclass c = e->vtable->FindClass(e, className); + + if (c) { + e->vtable->ThrowNew(e, c, message); + } + + return 0; +} + +extern "C" int +jniThrowExceptionFmt(JNIEnv* e, const char* className, const char* format, + va_list args) +{ + const unsigned size = 4096; + char buffer[size]; + ::vsnprintf(buffer, size, format, args); + return jniThrowException(e, className, buffer); +} + +extern "C" int +jniThrowNullPointerException(JNIEnv* e, const char* message) +{ + return jniThrowException(e, "java/lang/NullPointerException", message); +} + +extern "C" int +jniThrowRuntimeException(JNIEnv* e, const char* message) +{ + return jniThrowException(e, "java/lang/RuntimeException", message); +} + +extern "C" int +jniThrowIOException(JNIEnv* e, const char* message) +{ + return jniThrowException(e, "java/lang/IOException", message); +} + +extern "C" const char* +jniStrError(int error, char* buffer, size_t length) +{ + if (static_cast(strerror_r(error, buffer, length)) == 0) { + return buffer; + } else { + return 0; + } +} + +extern "C" int +__android_log_print(int priority, const char* tag, const char* format, ...) +{ + va_list a; + const unsigned size = 4096; + char buffer[size]; + + va_start(a, format); + ::vsnprintf(buffer, size, format, a); + va_end(a); + + return fprintf(stderr, "%d %s %s\n", priority, tag, buffer); +} + +extern "C" int +jniGetFDFromFileDescriptor(JNIEnv* e, jobject descriptor) +{ + return e->vtable->GetIntField + (e, descriptor, e->vtable->GetFieldID + (e, e->vtable->FindClass + (e, "java/io/FileDescriptor"), "descriptor", "I")); +} + +extern "C" void +jniSetFileDescriptorOfFD(JNIEnv* e, jobject descriptor, int value) +{ + e->vtable->SetIntField + (e, descriptor, e->vtable->GetFieldID + (e, e->vtable->FindClass + (e, "java/io/FileDescriptor"), "descriptor", "I"), value); +} + +extern "C" jobject +jniCreateFileDescriptor(JNIEnv* e, int fd) +{ + jobject descriptor = e->vtable->NewObject + (e, e->vtable->FindClass(e, "java/io/FileDescriptor"), + e->vtable->GetMethodID + (e, e->vtable->FindClass(e, "java/io/FileDescriptor"), "", "()V")); + + jniSetFileDescriptorOfFD(e, descriptor, fd); + + return descriptor; +} + +extern "C" struct _JNIEnv; + +int +register_org_apache_harmony_dalvik_NativeTestTarget(_JNIEnv*) +{ + // ignore + return 0; +} diff --git a/src/jnienv.cpp b/src/jnienv.cpp index 37d3a65f13..12fd3d9fbc 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -104,7 +104,7 @@ GetEnv(Machine* m, Thread** t, jint version) { *t = static_cast(m->localThread->get()); if (*t) { - if (version <= JNI_VERSION_1_4) { + if (version <= JNI_VERSION_1_6) { return JNI_OK; } else { return JNI_EVERSION;