From 14f2449fa9d78b7bde429a4996b20f51b8d0eb47 Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Mon, 8 Mar 2010 06:16:14 +0000 Subject: Support different Java VMs, including Apache Harmony. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@920204 13f79535-47bb-0310-9956-ffa450edef68 --- sca-cpp/trunk/configure.ac | 45 ++++++++++-- sca-cpp/trunk/etc/git-exclude | 1 + sca-cpp/trunk/modules/java/Makefile.am | 13 ++-- sca-cpp/trunk/modules/java/eval.hpp | 32 ++++++--- sca-cpp/trunk/modules/java/jni-test.cpp | 80 ++++++++++++++++++++++ .../java/org/apache/tuscany/ClassLoader.java | 2 +- .../java/org/apache/tuscany/InvocationHandler.java | 7 +- .../java/org/apache/tuscany/IterableUtil.java | 14 +--- 8 files changed, 159 insertions(+), 35 deletions(-) create mode 100644 sca-cpp/trunk/modules/java/jni-test.cpp diff --git a/sca-cpp/trunk/configure.ac b/sca-cpp/trunk/configure.ac index 4e8cac1b8b..7ac5a33b47 100644 --- a/sca-cpp/trunk/configure.ac +++ b/sca-cpp/trunk/configure.ac @@ -318,21 +318,18 @@ AC_MSG_CHECKING([for java]) AC_ARG_WITH([java], [AC_HELP_STRING([--with-java=PATH], [path to installed Java [default=/usr/lib/jvm/default-java]])], [ JAVA_PREFIX="${withval}" JAVA_INCLUDE="${withval}/include" - JAVA_LIB="${withval}/jre/lib/i386" JAVAC="${withval}/bin/javac" JAR="${withval}/bin/jar" AC_MSG_RESULT("${withval}") ], [ JAVA_PREFIX="/usr/lib/jvm/default-java" JAVA_INCLUDE="/usr/lib/jvm/default-java/include" - JAVA_LIB="/usr/lib/jvm/default-java/jre/lib/i386" JAVAC="/usr/lib/jvm/default-java/bin/javac" JAR="/usr/lib/jvm/default-java/bin/jar" AC_MSG_RESULT(/usr/lib/jvm/default-java) ]) AC_SUBST(JAVA_PREFIX) AC_SUBST(JAVA_INCLUDE) -AC_SUBST(JAVA_LIB) AC_SUBST(JAVAC) AC_SUBST(JAR) @@ -350,8 +347,44 @@ AC_ARG_ENABLE(java, [AS_HELP_STRING([--enable-java], [enable Java support [defau esac ], [ AC_MSG_RESULT(no)]) if test "${want_java}" = "true"; then - LIBS="-L${JAVA_LIB} -L${JAVA_LIB}/server ${default_LIBS}" - AC_CHECK_LIB([java], [JNI_CreateJavaVM], [], [AC_MSG_ERROR([couldn't find a suitable libjava, use --with-java=PATH])], [-ljvm -lverify]) + # Detect most common Java VMs + if test -f "${JAVA_PREFIX}/jre/lib/i386/libjava.so"; then + if test -f "${JAVA_PREFIX}/jre/lib/i386/server/libjvm.so"; then + # Server VM + AC_MSG_NOTICE([checking for server Java VM]) + JAVA_CHECK_LIB="-L${JAVA_PREFIX}/jre/lib/i386 -R${JAVA_PREFIX}/jre/lib/i386 -L${JAVA_PREFIX}/jre/lib/i386/server -R${JAVA_PREFIX}/jre/lib/i386/server" + LIBS="${JAVA_CHECK_LIB} ${default_LIBS}" + AC_CHECK_LIB([java], [JNI_CreateJavaVM], [JAVA_LDFLAGS="${JAVA_CHECK_LIB} -ljava"], [], [-ljvm -lverify]) + if test "${JAVA_LDFLAGS}" != ""; then + AC_DEFINE([JAVA_SERVER_VM], 1, [Server Java VM]) + fi + else + if test -f "${JAVA_PREFIX}/jre/lib/i386/j9vm/libjvm.so"; then + # J9 VM + AC_MSG_NOTICE([checking for J9 Java VM]) + JAVA_CHECK_LIB="-L${JAVA_PREFIX}/jre/lib/i386 -R${JAVA_PREFIX}/jre/lib/i386 -L${JAVA_PREFIX}/jre/lib/i386/j9vm -R${JAVA_PREFIX}/jre/lib/i386/j9vm" + LIBS="${JAVA_CHECK_LIB} ${default_LIBS}" + AC_CHECK_LIB([java], [JNI_CreateJavaVM], [JAVA_LDFLAGS="${JAVA_CHECK_LIB} -ljava"], [], [-ljvm -ljsig]) + if test "${JAVA_LDFLAGS}" != ""; then + AC_DEFINE([JAVA_J9_VM], 1, [J9 Java VM]) + fi + fi + fi + else + if test -f "${JAVA_PREFIX}/jre/bin/default/libharmonyvm.so"; then + # Apache Harmony VM + AC_MSG_NOTICE([checking for Apache Harmony Java VM]) + JAVA_CHECK_LIB="-L${JAVA_PREFIX}/jre/bin -R${JAVA_PREFIX}/jre/bin -L${JAVA_PREFIX}/jre/bin/default -R${JAVA_PREFIX}/jre/bin/default" + LIBS="${JAVA_CHECK_LIB} ${default_LIBS}" + AC_CHECK_LIB([harmonyvm], [JNI_CreateJavaVM], [JAVA_LDFLAGS="${JAVA_CHECK_LIB} -lharmonyvm"], [], [-lhythr -licuuc -lch ${JAVA_PREFIX}/jre/bin/default/libicudata.so.34]) + if test "${JAVA_LDFLAGS}" != ""; then + AC_DEFINE([JAVA_HARMONY_VM], 1, [Apache Harmony Java VM]) + fi + fi + fi + if test "${JAVA_LDFLAGS}" = ""; then + AC_MSG_ERROR([couldn't find a suitable Java JNI library, use --with-java=PATH]) + fi AC_MSG_CHECKING([for javac]) if test -x "${JAVAC}"; then AC_MSG_RESULT("${JAVAC}") @@ -368,7 +401,9 @@ if test "${want_java}" = "true"; then AC_DEFINE([WANT_JAVA], 1, [enable Java support]) else AM_CONDITIONAL([WANT_JAVA], false) + JAVA_LDFLAGS="-L${JAVA_PREFIX}/jre/lib -R${JAVA_PREFIX}/jre/lib -ljava" fi +AC_SUBST(JAVA_LDFLAGS) # Configure path to Apache Axis2C includes and lib. AC_MSG_CHECKING([for axis2c]) diff --git a/sca-cpp/trunk/etc/git-exclude b/sca-cpp/trunk/etc/git-exclude index 9b81c5e267..f2d3d08eda 100644 --- a/sca-cpp/trunk/etc/git-exclude +++ b/sca-cpp/trunk/etc/git-exclude @@ -83,6 +83,7 @@ client-test mcache-test curl-test scdl-test +jni-test java-test java-shell script-test diff --git a/sca-cpp/trunk/modules/java/Makefile.am b/sca-cpp/trunk/modules/java/Makefile.am index 5c640ac31b..293b9431b5 100644 --- a/sca-cpp/trunk/modules/java/Makefile.am +++ b/sca-cpp/trunk/modules/java/Makefile.am @@ -32,16 +32,19 @@ java.prefix: $(top_builddir)/config.status lib_LTLIBRARIES = libmod_tuscany_java.la libmod_tuscany_java_la_SOURCES = mod-java.cpp -libmod_tuscany_java_la_LDFLAGS = -lxml2 -lcurl -lmozjs -L${JAVA_LIB} -R${JAVA_LIB} -R${JAVA_LIB}/server -ljava +libmod_tuscany_java_la_LDFLAGS = -lxml2 -lcurl -lmozjs ${JAVA_LDFLAGS} noinst_DATA = libmod_tuscany_java.so libmod_tuscany_java.so: ln -s .libs/libmod_tuscany_java.so libmod_tuscany_java.so +jni_test_SOURCES = jni-test.cpp +jni_test_LDFLAGS = ${JAVA_LDFLAGS} + java_test_SOURCES = java-test.cpp -java_test_LDFLAGS = -L${JAVA_LIB} -R${JAVA_LIB} -R${JAVA_LIB}/server -ljava +java_test_LDFLAGS = ${JAVA_LDFLAGS} java_shell_SOURCES = java-shell.cpp -java_shell_LDFLAGS = -L${JAVA_LIB} -R${JAVA_LIB} -R${JAVA_LIB}/server -ljava +java_shell_LDFLAGS = ${JAVA_LDFLAGS} noinst_JAVA = org/apache/tuscany/*.java test/*.java jardir = ${prefix}/modules/java @@ -55,7 +58,7 @@ CLEANFILES = ${jarfile} org/apache/tuscany/*.class test/*.class client_test_SOURCES = client-test.cpp client_test_LDFLAGS = -lxml2 -lcurl -lmozjs -noinst_PROGRAMS = java-test java-shell client-test -TESTS = java-test server-test +noinst_PROGRAMS = jni-test java-test java-shell client-test +TESTS = jni-test java-test server-test endif diff --git a/sca-cpp/trunk/modules/java/eval.hpp b/sca-cpp/trunk/modules/java/eval.hpp index 741dda52ca..7da1f20a38 100644 --- a/sca-cpp/trunk/modules/java/eval.hpp +++ b/sca-cpp/trunk/modules/java/eval.hpp @@ -33,6 +33,15 @@ namespace tuscany { namespace java { +/** + * Handle differences between various JNI APIs. + */ +#ifdef JAVA_HARMONY_VM +#define JNI_VERSION JNI_VERSION_1_4 +#else +#define JNI_VERSION JNI_VERSION_1_6 +#endif + /** * Represent a Java VM runtime. */ @@ -49,7 +58,7 @@ public: // Create a new JVM JavaVMInitArgs args; - args.version = JNI_VERSION_1_6; + args.version = JNI_VERSION; args.ignoreUnrecognized = JNI_FALSE; JavaVMOption options[3]; args.options = options; @@ -58,7 +67,8 @@ public: // Configure classpath const char* envcp = getenv("CLASSPATH"); const string cp = string("-Djava.class.path=") + (envcp == NULL? "." : envcp); - options[args.nOptions++].optionString = const_cast(c_str(cp)); + options[args.nOptions].optionString = const_cast(c_str(cp)); + options[args.nOptions++].extraInfo = NULL; #ifdef WANT_MAINTAINER_MODE // Enable assertions @@ -68,22 +78,28 @@ public: // Configure Java debugging const char* jpdaopts = getenv("JPDA_OPTS"); if (jpdaopts != NULL) { - options[args.nOptions++].optionString = const_cast(jpdaopts); + options[args.nOptions].optionString = const_cast(jpdaopts); + options[args.nOptions++].extraInfo = NULL; } else { const char* jpdaaddr = getenv("JPDA_ADDRESS"); if (jpdaaddr != NULL) { const string jpda = string("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=") + jpdaaddr; - options[args.nOptions++].optionString = const_cast(c_str(jpda)); + options[args.nOptions].optionString = const_cast(c_str(jpda)); + options[args.nOptions++].extraInfo = NULL; } } // Create the JVM +#ifdef JAVA_HARMONY_VM + JNI_CreateJavaVM(&jvm, &env, &args); +#else JNI_CreateJavaVM(&jvm, (void**)&env, &args); +#endif } else { // Just point to existing JVM - jvm->GetEnv((void**)&env, JNI_VERSION_1_6); + jvm->GetEnv((void**)&env, JNI_VERSION); } // Lookup System classes and methods @@ -94,7 +110,7 @@ public: booleanClass = env->FindClass("java/lang/Boolean"); stringClass = env->FindClass("java/lang/String"); objectArrayClass = env->FindClass("[Ljava/lang/Object;"); - iterableClass = env->FindClass("Ljava/lang/Iterable;"); + iterableClass = env->FindClass("java/lang/Iterable"); classForName = env->GetStaticMethodID(classClass, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"); doubleValueOf = env->GetStaticMethodID(doubleClass, "valueOf", "(D)Ljava/lang/Double;"); doubleValue = env->GetMethodID(doubleClass, "doubleValue", "()D"); @@ -509,10 +525,10 @@ const failable evalClass(const JavaRuntime& jr, const value& expr, const const jmethodID fid = (jmethodID)(long)(double)cadr(func); // Convert args to Java jvalues - const jvalue *args = valuesToJvalues(jr, cddr(func), cdr(expr)); + const jvalue* args = valuesToJvalues(jr, cddr(func), cdr(expr)); // Call the Java function - const jobject result = jr.env->CallObjectMethodA(jc.obj, fid, args); + const jobject result = jr.env->CallObjectMethodA(jc.obj, fid, const_cast(args)); if (result == NULL) return mkfailure(string("Function call failed: ") + car(expr) + " : " + lastException(jr)); diff --git a/sca-cpp/trunk/modules/java/jni-test.cpp b/sca-cpp/trunk/modules/java/jni-test.cpp new file mode 100644 index 0000000000..727af13dc6 --- /dev/null +++ b/sca-cpp/trunk/modules/java/jni-test.cpp @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* $Rev$ $Date$ */ + +/** + * Basic JNI test. + */ + +#include +#include +#include "stream.hpp" +#include "string.hpp" +#include "fstream.hpp" +#include "eval.hpp" + +namespace tuscany { +namespace java { + +#ifdef JAVA_HARMONY_VM +#define JNI_VERSION JNI_VERSION_1_4 +#else +#define JNI_VERSION JNI_VERSION_1_6 +#endif + +bool testJNI() { + gc_scoped_pool pool; + JavaVM* jvm; + JNIEnv* env; + + JavaVMInitArgs args; + args.version = JNI_VERSION; + args.ignoreUnrecognized = JNI_FALSE; + JavaVMOption options[3]; + args.options = options; + args.nOptions = 0; + const char* envcp = getenv("CLASSPATH"); + const string cp = string("-Djava.class.path=") + (envcp == NULL? "." : envcp); + options[args.nOptions].optionString = const_cast(c_str(cp)); + options[args.nOptions++].extraInfo = NULL; +#ifdef JAVA_HARMONY_VM + JNI_CreateJavaVM(&jvm, &env, &args); +#else + JNI_CreateJavaVM(&jvm, (void**)&env, &args); +#endif + + jclass classClass = env->FindClass("java/lang/Class"); + assert(classClass != NULL); + jclass loaderClass = env->FindClass("org/apache/tuscany/ClassLoader"); + assert(loaderClass != NULL); + return true; +} + +} +} + +int main() { + tuscany::cout << "Testing..." << tuscany::endl; + + tuscany::java::testJNI(); + + tuscany::cout << "OK" << tuscany::endl; + return 0; +} diff --git a/sca-cpp/trunk/modules/java/org/apache/tuscany/ClassLoader.java b/sca-cpp/trunk/modules/java/org/apache/tuscany/ClassLoader.java index 7fb6519472..ef7b2316fb 100644 --- a/sca-cpp/trunk/modules/java/org/apache/tuscany/ClassLoader.java +++ b/sca-cpp/trunk/modules/java/org/apache/tuscany/ClassLoader.java @@ -14,7 +14,7 @@ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations - * under the License. + * under the License. */ package org.apache.tuscany; diff --git a/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java b/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java index c5ec6005a1..06466fe9fc 100644 --- a/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java +++ b/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java @@ -14,7 +14,7 @@ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations - * under the License. + * under the License. */ package org.apache.tuscany; @@ -25,7 +25,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** - * Proxy Invocation handler used to represent SCA component references. + * Proxy Invocation handler used to represent SCA component references. */ class InvocationHandler implements java.lang.reflect.InvocationHandler { final long lambda; @@ -33,7 +33,7 @@ class InvocationHandler implements java.lang.reflect.InvocationHandler { InvocationHandler(final long lambda) { this.lambda = lambda; } - + /** * Create a proxy for an interface and the lambda function representing * an SCA component reference. @@ -45,7 +45,6 @@ class InvocationHandler implements java.lang.reflect.InvocationHandler { /** * Proxy invocation of a C++ function. */ - @Override public native Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable; /** diff --git a/sca-cpp/trunk/modules/java/org/apache/tuscany/IterableUtil.java b/sca-cpp/trunk/modules/java/org/apache/tuscany/IterableUtil.java index 85872cba72..6d559f370a 100644 --- a/sca-cpp/trunk/modules/java/org/apache/tuscany/IterableUtil.java +++ b/sca-cpp/trunk/modules/java/org/apache/tuscany/IterableUtil.java @@ -14,7 +14,7 @@ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations - * under the License. + * under the License. */ package org.apache.tuscany; @@ -93,7 +93,6 @@ public class IterableUtil { if(l instanceof Collection) return new ArrayIterable(((Collection)l).toArray(), 1); return new Iterable() { - @Override public Iterator iterator() { final Iterator i = ((Iterable)l).iterator(); i.next(); @@ -148,7 +147,7 @@ public class IterableUtil { @Override public int size() { - throw new UnsupportedOperationException(); + return this.isNil()? 0 : 1 + ((List)this.cdr()).size(); } @Override @@ -190,18 +189,15 @@ public class IterableUtil { return new Iterator() { int i = ArrayIterable.this.start; - @Override public boolean hasNext() { return this.i < ArrayIterable.this.a.length; } @SuppressWarnings("unchecked") - @Override public T next() { return (T)ArrayIterable.this.a[this.i++]; } - @Override public void remove() { throw new UnsupportedOperationException(); } @@ -242,18 +238,15 @@ public class IterableUtil { return new Iterator() { int i = ListIterable.this.start; - @Override public boolean hasNext() { return this.i < ListIterable.this.l.size(); } @SuppressWarnings("unchecked") - @Override public T next() { return (T)ListIterable.this.l.get(this.i++); } - @Override public void remove() { throw new UnsupportedOperationException(); } @@ -296,7 +289,6 @@ public class IterableUtil { boolean carIterator = true; Iterator cdrIterator = PairIterable.this.cdr.iterator(); - @Override public boolean hasNext() { if(this.carIterator) return true; @@ -304,7 +296,6 @@ public class IterableUtil { } @SuppressWarnings("unchecked") - @Override public T next() { if(this.carIterator) { this.carIterator = false; @@ -313,7 +304,6 @@ public class IterableUtil { return (T)this.cdrIterator.next(); } - @Override public void remove() { throw new UnsupportedOperationException(); } -- cgit v1.2.3