You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by js...@apache.org on 2010/01/11 09:29:40 UTC

svn commit: r897789 - in /tuscany/sca-cpp/trunk/modules/java: ./ org/ org/apache/ org/apache/tuscany/ test/

Author: jsdelfino
Date: Mon Jan 11 08:29:39 2010
New Revision: 897789

URL: http://svn.apache.org/viewvc?rev=897789&view=rev
Log:
Added utility functions to help call Java code using JNI and wrap Axis2/java in a component.

Added:
    tuscany/sca-cpp/trunk/modules/java/
    tuscany/sca-cpp/trunk/modules/java/Makefile.am
    tuscany/sca-cpp/trunk/modules/java/driver.hpp
    tuscany/sca-cpp/trunk/modules/java/eval.hpp
    tuscany/sca-cpp/trunk/modules/java/io.hpp
    tuscany/sca-cpp/trunk/modules/java/java-shell.cpp
    tuscany/sca-cpp/trunk/modules/java/java-test.cpp
    tuscany/sca-cpp/trunk/modules/java/org/
    tuscany/sca-cpp/trunk/modules/java/org/apache/
    tuscany/sca-cpp/trunk/modules/java/org/apache/tuscany/
    tuscany/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java
    tuscany/sca-cpp/trunk/modules/java/test/
    tuscany/sca-cpp/trunk/modules/java/test/Adder.java
    tuscany/sca-cpp/trunk/modules/java/test/AdderImpl.java
    tuscany/sca-cpp/trunk/modules/java/test/CalcImpl.java

Added: tuscany/sca-cpp/trunk/modules/java/Makefile.am
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/java/Makefile.am?rev=897789&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/java/Makefile.am (added)
+++ tuscany/sca-cpp/trunk/modules/java/Makefile.am Mon Jan 11 08:29:39 2010
@@ -0,0 +1,39 @@
+#  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.
+
+datadir=$(prefix)/modules/java
+JAVAROOT = $(top_builddir)/modules/java
+
+if WANT_JAVA
+
+noinst_PROGRAMS = java-test java-shell
+
+INCLUDES = -I${JAVA_INCLUDE}
+
+java_test_SOURCES = java-test.cpp
+java_test_LDADD =  -L${JAVA_LIB} -ljava
+java_test_LDFLAGS = -rpath ${JAVA_LIB} -rpath ${JAVA_LIB}/server
+
+java_shell_SOURCES = java-shell.cpp
+java_shell_LDADD = -L${JAVA_LIB} -ljava
+java_shell_LDFLAGS = -rpath ${JAVA_LIB} -rpath ${JAVA_LIB}/server
+
+noinst_JAVA = org/apache/tuscany/*.java test/*.java
+
+TESTS = java-test
+
+endif
\ No newline at end of file

Added: tuscany/sca-cpp/trunk/modules/java/driver.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/java/driver.hpp?rev=897789&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/java/driver.hpp (added)
+++ tuscany/sca-cpp/trunk/modules/java/driver.hpp Mon Jan 11 08:29:39 2010
@@ -0,0 +1,60 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_java_driver_hpp
+#define tuscany_java_driver_hpp
+
+/**
+ * Java evaluator main driver loop.
+ */
+
+#include "string.hpp"
+#include "stream.hpp"
+#include "monad.hpp"
+#include "../scheme/driver.hpp"
+#include "eval.hpp"
+
+namespace tuscany {
+namespace java {
+
+const value evalDriverLoop(const JavaRuntime& jr, const JavaClass jc, istream& in, ostream& out) {
+    scheme::promptForInput(scheme::evalInputPrompt, out);
+    value input = scheme::readValue(in);
+    if (isNil(input))
+        return input;
+    const failable<value> output = evalClass(jr, input, jc);
+    scheme::announceOutput(scheme::evalOutputPrompt, out);
+    scheme::userPrint(content(output), out);
+    return evalDriverLoop(jr, jc, in, out);
+}
+
+const bool evalDriverRun(const char* name, istream& in, ostream& out) {
+    scheme::setupDisplay(out);
+    const failable<JavaClass> jc = readClass(javaRuntime, name);
+    if (!hasContent(jc))
+        return true;
+    evalDriverLoop(javaRuntime, content(jc), in, out);
+    return true;
+}
+
+}
+}
+#endif /* tuscany_java_driver_hpp */

Added: tuscany/sca-cpp/trunk/modules/java/eval.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/java/eval.hpp?rev=897789&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/java/eval.hpp (added)
+++ tuscany/sca-cpp/trunk/modules/java/eval.hpp Mon Jan 11 08:29:39 2010
@@ -0,0 +1,398 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_java_eval_hpp
+#define tuscany_java_eval_hpp
+
+/**
+ * Java component implementation evaluation logic.
+ */
+#include <jni.h>
+
+#include "list.hpp"
+#include "value.hpp"
+#include "io.hpp"
+
+namespace tuscany {
+namespace java {
+
+/**
+ * Initialize a JVM.
+ */
+jobject JNICALL nativeInvoke(JNIEnv *env, jobject self, jobject proxy, jobject method, jobjectArray args);
+
+class JavaRuntime {
+public:
+    JavaRuntime() {
+
+        // Create a JVM
+        JavaVMInitArgs args;
+        args.version = JNI_VERSION_1_6;
+        args.ignoreUnrecognized = JNI_FALSE;
+        JavaVMOption options[1];
+        options[0].optionString = const_cast<char*>("-Djava.class.path=.");
+        args.options = options;
+        args.nOptions = 1;
+        JNI_CreateJavaVM(&jvm, (void**)&env, &args);
+
+        // Capture JVM standard IO
+        setupIO();
+
+        // Lookup the system classes and methods we need
+        classClass = env->FindClass("java/lang/Class");
+        methodClass = env->FindClass("java/lang/reflect/Method");
+        objectClass = env->FindClass("java/lang/Object");
+        doubleClass = env->FindClass("java/lang/Double");
+        booleanClass = env->FindClass("java/lang/Boolean");
+        stringClass = env->FindClass("java/lang/String");
+        objectArrayClass = env->FindClass("[Ljava/lang/Object;");
+        doubleValueOf = env->GetStaticMethodID(doubleClass, "valueOf", "(D)Ljava/lang/Double;");
+        doubleValue = env->GetMethodID(doubleClass, "doubleValue", "()D");
+        booleanValueOf = env->GetStaticMethodID(booleanClass, "valueOf", "(Z)Ljava/lang/Boolean;");
+        booleanValue = env->GetMethodID(booleanClass, "booleanValue", "()Z");
+        declaredMethods = env->GetMethodID(classClass, "getDeclaredMethods", "()[Ljava/lang/reflect/Method;");
+        methodName = env->GetMethodID(methodClass, "getName", "()Ljava/lang/String;");
+
+        // Register our native invocation handler native
+        invokerClass = env->FindClass("org/apache/tuscany/InvocationHandler");
+        invokerValueOf = env->GetStaticMethodID(invokerClass, "valueOf", "(Ljava/lang/Class;J)Ljava/lang/Object;");
+        invokerLambda = env->GetFieldID(invokerClass, "lambda", "J");
+        JNINativeMethod nm;
+        nm.name = const_cast<char*>("invoke");
+        nm.signature = const_cast<char*>("(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
+        nm.fnPtr = (void*)nativeInvoke;
+        env->RegisterNatives(invokerClass, &nm, 1);
+    }
+
+    ~JavaRuntime() {
+        if (jvm == NULL)
+            return;
+        jvm->DestroyJavaVM();
+    }
+
+    JavaVM* jvm;
+    JNIEnv* env;
+
+    jclass classClass;
+    jclass methodClass;
+    jclass objectClass;
+    jclass doubleClass;
+    jclass booleanClass;
+    jclass stringClass;
+    jclass objectArrayClass;
+    jmethodID doubleValueOf;
+    jmethodID doubleValue;
+    jmethodID booleanValueOf;
+    jmethodID booleanValue;
+    jmethodID declaredMethods;
+    jmethodID methodName;
+
+    jclass invokerClass;
+    jmethodID invokerValueOf;
+    jfieldID invokerLambda;
+
+} javaRuntime;
+
+/**
+ * Return the last exception that occurred in a JVM.
+ */
+string lastException(const JavaRuntime& jr) {
+    if (!jr.env->ExceptionCheck())
+        return "No Exception";
+    jr.env->ExceptionDescribe();
+    jr.env->ExceptionClear();
+    return "UnknownException";
+}
+
+/**
+ * Declare conversion functions.
+ */
+const jobject valueToJobject(const JavaRuntime& jr, const value& v);
+const value jobjectToValue(const JavaRuntime& jr, const jobject o);
+const jobjectArray valuesToJarray(const JavaRuntime& jr, const list<value>& v);
+const list<value> jarrayToValues(const JavaRuntime& jr, const jobjectArray o);
+
+/**
+ * Convert a Java class name to a JNI class name.
+ */
+const bool jniClassNameHelper(char* to, const char* from) {
+    if (*from == '\0') {
+        *to = '\0';
+        return true;
+    }
+    *to = *from == '.'? '/' : *from;
+    return jniClassNameHelper(to + 1, from + 1);
+}
+
+const string jniClassName(const string& from) {
+    char buf[length(from) + 1];
+    jniClassNameHelper(buf, c_str(from));
+    return string(buf);
+}
+
+/**
+ * Create a new Java object representing a lambda expression.
+ */
+class javaLambda {
+public:
+    javaLambda(const JavaRuntime& jr, const value& iface, const lambda<value(const list<value>&)>& func) : jr(jr), iface(iface), func(func) {
+    }
+
+    const JavaRuntime& jr;
+    const value iface;
+    const lambda<value(const list<value>&)> func;
+};
+
+/**
+ * Invocation handler invoke method, dispatches to the lambda function wrapped
+ * in the invocation handler.
+ */
+jobject JNICALL nativeInvoke(JNIEnv* env, jobject self, unused jobject proxy, jobject method, jobjectArray args) {
+
+    // Retrieve the lambda function from the invocation handler
+    jclass clazz = env->GetObjectClass(self);
+    jfieldID f = env->GetFieldID(clazz, "lambda", "J");
+    const javaLambda& jl = *(javaLambda*)(long)env->GetLongField(self, f);
+
+    // Retrieve the function name
+    const jstring s = (jstring)env->CallObjectMethod(method, jl.jr.methodName);
+    const char* c = env->GetStringUTFChars(s, NULL);
+    const value func(c);
+    env->ReleaseStringUTFChars(s, c);
+
+    // Build the expression to evaluate
+    const list<value> expr = cons<value>(func, jarrayToValues(jl.jr, args));
+
+    // Invoke the lambda function
+    value result = jl.func(expr);
+
+    // Convert result to a jobject
+    return valueToJobject(jl.jr, result);
+}
+
+const jobject mkJavaLambda(const JavaRuntime& jr, const lambda<value(const list<value>&)>& l) {
+
+    // The lambda function is given the opportunity to give us a
+    // Java interface name that it implements, and which will be
+    // used as the type of the Java proxy representing it. If the
+    // lambda function doesn't specify an interface, then the
+    // proxy implements javax.script.Invocable.
+    const value iface = l(mklist<value>("interface"));
+    const gc_ptr<javaLambda> jl = new (gc_new<javaLambda>()) javaLambda(jr, iface, l);
+
+    jclass jc = jr.env->FindClass(c_str(jniClassName(string(iface))));
+    const jobject obj = jr.env->CallStaticObjectMethod(jr.invokerClass, jr.invokerValueOf, jc, (long)(javaLambda*)jl);
+    return obj;
+}
+
+/**
+ * Convert a list of values to a Java jobjectArray.
+ */
+const jobjectArray valuesToJarrayHelper(const JavaRuntime& jr, jobjectArray a, const list<value>& v, const int i) {
+    if (isNil(v))
+        return a;
+    jr.env->SetObjectArrayElement(a, i, valueToJobject(jr, car(v)));
+    return valuesToJarrayHelper(jr, a, cdr(v), i + 1);
+}
+
+const jobjectArray valuesToJarray(const JavaRuntime& jr, const list<value>& v) {
+    jobjectArray a = jr.env->NewObjectArray(length(v), jr.objectClass, NULL);
+    return valuesToJarrayHelper(jr, a, v, 0);
+}
+
+/**
+ * Convert a value to a Java jobject.
+ */
+const jobject valueToJobject(const JavaRuntime& jr, const value& v) {
+    switch (type(v)) {
+    case value::List:
+        return valuesToJarray(jr, v);
+    case value::Lambda:
+        return mkJavaLambda(jr, v);
+    case value::Symbol:
+        return jr.env->NewStringUTF(c_str(string("'") + v));
+    case value::String:
+        return jr.env->NewStringUTF(c_str(v));
+    case value::Number:
+        return jr.env->CallStaticObjectMethod(jr.doubleClass, jr.doubleValueOf, (double)v);
+    case value::Bool:
+        return jr.env->CallStaticObjectMethod(jr.booleanClass, jr.booleanValueOf, (double)v);
+    default:
+        return NULL;
+    }
+}
+
+/**
+ * Convert a list of values to an array of jvalues.
+ */
+const jvalue* valuesToJvaluesHelper(const JavaRuntime& jr, jvalue* a, const list<value>& v) {
+    if (isNil(v))
+        return a;
+    a->l = valueToJobject(jr, car(v));
+    return valuesToJvaluesHelper(jr, a + 1, cdr(v));
+}
+
+const jvalue* valuesToJvalues(const JavaRuntime& jr, const list<value>& v) {
+    const int n = length(v);
+    jvalue* a = new (gc_anew<jvalue>(n)) jvalue[n];
+    valuesToJvaluesHelper(jr, a, v);
+    return a;
+}
+
+/**
+ * Convert a Java jobjectArray to a list of values.
+ */
+const list<value> jarrayToValuesHelper(const JavaRuntime& jr, jobjectArray a, const int i, const int size) {
+    if (i == size)
+        return list<value>();
+    return cons(jobjectToValue(jr, jr.env->GetObjectArrayElement(a, i)), jarrayToValuesHelper(jr, a, i + 1, size));
+}
+
+const list<value> jarrayToValues(const JavaRuntime& jr, jobjectArray o) {
+    return jarrayToValuesHelper(jr, o, 0, jr.env->GetArrayLength(o));
+}
+
+/**
+ * Lambda function used to represent a Java callable object.
+ */
+struct javaCallable {
+    const JavaRuntime& jr;
+    const jobject obj;
+
+    javaCallable(const JavaRuntime& jr, const jobject obj) : jr(jr), obj(obj) {
+    }
+
+    const value operator()(const list<value>& args) const {
+        jobjectArray jargs = valuesToJarray(jr, args);
+        jobject result = jargs; //CallObject(func, jargs);
+        return jobjectToValue(jr, result);
+    }
+};
+
+/**
+ * Convert a Java jobject to a value.
+ */
+const value jobjectToValue(const JavaRuntime& jr, const jobject o) {
+    if (o == NULL)
+        return value();
+    const jclass clazz = jr.env->GetObjectClass(o);
+    if ((jr.env->IsSameObject(clazz, jr.stringClass))) {
+        const char* s = jr.env->GetStringUTFChars((jstring)o, NULL);
+        if (*s == '\'') {
+            const value v(s + 1);
+            jr.env->ReleaseStringUTFChars((jstring)o, s);
+            return v;
+        }
+        const value v = string(s);
+        jr.env->ReleaseStringUTFChars((jstring)o, s);
+        return v;
+    }
+    if (jr.env->IsSameObject(clazz, jr.booleanClass))
+        return value((bool)jr.env->CallBooleanMethod(o, jr.booleanValue));
+    if (jr.env->IsSameObject(clazz, jr.doubleClass))
+        return value((double)jr.env->CallDoubleMethod(o, jr.doubleValue));
+    if ((jr.env->IsSameObject(clazz, jr.objectArrayClass)))
+        return jarrayToValues(jr, (jobjectArray)o);
+    return lambda<value(const list<value>&)>(javaCallable(jr, o));
+}
+
+/**
+ * Returns a balanced tree of a class' methods.
+ */
+const value methodToValue(const JavaRuntime& jr, const jobject m) {
+    const jobject s = jr.env->CallObjectMethod(m, jr.methodName);
+    const char* c = jr.env->GetStringUTFChars((jstring)s, NULL);
+    const string& name = string(c);
+    jr.env->ReleaseStringUTFChars((jstring)s, c);
+    const jmethodID mid = jr.env->FromReflectedMethod(m);
+    return mklist<value>(c_str(name), (double)(long)mid);
+}
+
+const list<value> methodsToValues(const JavaRuntime& jr, const jobjectArray m, const int i) {
+    if (i == 0)
+        return list<value>();
+    return cons<value>(methodToValue(jr, jr.env->GetObjectArrayElement(m, i - 1)), methodsToValues(jr, m, i - 1));
+}
+
+const list<value> methodsToValues(const JavaRuntime& jr, const jclass clazz) {
+    const jobjectArray m = (jobjectArray)jr.env->CallObjectMethod(clazz, jr.declaredMethods);
+    return methodsToValues(jr, m, jr.env->GetArrayLength(m));
+}
+
+/**
+ * Represents a Java Class.
+ */
+class JavaClass {
+public:
+    JavaClass() : clazz(NULL), obj(NULL) {
+    }
+
+    JavaClass(const jclass clazz, const jobject obj, const list<value> m) : clazz(clazz), obj(obj), m(m) {
+    }
+
+    const jclass clazz;
+    const jobject obj;
+    const list<value> m;
+};
+
+/**
+ * Read a class.
+ */
+const failable<JavaClass> readClass(const JavaRuntime& jr, const string& name) {
+    const string jname = jniClassName(name);
+    const jclass clazz = jr.env->FindClass(c_str(jname));
+    if (clazz == NULL)
+        return mkfailure<JavaClass>(string("Couldn't load class: ") + name + " : " + lastException(jr));
+    const jmethodID constr = jr.env->GetMethodID(clazz, "<init>", "()V");
+    if (constr == NULL)
+        return mkfailure<JavaClass>(string("Couldn't find constructor: ") + name + " : " + lastException(jr));
+    const jobject obj = jr.env->NewObject(clazz, constr);
+    if (obj == NULL)
+        return mkfailure<JavaClass>(string("Couldn't construct object: ") + name + " : " + lastException(jr));
+    return JavaClass(clazz, obj, methodsToValues(jr, clazz));
+}
+
+/**
+ * Evaluate an expression against a Java class.
+ */
+const failable<value> evalClass(const JavaRuntime& jr, const value& expr, const JavaClass jc) {
+
+    // Lookup the Java function named as the expression operand
+    const list<value> func = assoc<value>(car<value>(expr), jc.m);
+    if (isNil(func))
+        return mkfailure<value>(string("Couldn't find function: ") + car<value>(expr) + " : " + lastException(jr));
+    const jmethodID fid = (jmethodID)(long)(double)cadr(func);
+
+    // Convert args to Java jvalues
+    const jvalue *args = valuesToJvalues(jr, cdr<value>(expr));
+
+    // Call the Java function
+    const jobject result = jr.env->CallObjectMethodA(jc.obj, fid, args);
+    if (result == NULL)
+        return mkfailure<value>(string("Function call failed: ") + car<value>(expr) + " : " + lastException(jr));
+
+    // Convert Java result to a value
+    return jobjectToValue(jr, result);
+}
+
+}
+}
+#endif /* tuscany_java_eval_hpp */

Added: tuscany/sca-cpp/trunk/modules/java/io.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/java/io.hpp?rev=897789&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/java/io.hpp (added)
+++ tuscany/sca-cpp/trunk/modules/java/io.hpp Mon Jan 11 08:29:39 2010
@@ -0,0 +1,43 @@
+/*
+ * 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$ */
+
+#ifndef tuscany_java_io_hpp
+#define tuscany_java_io_hpp
+
+/**
+ * Java IO functions.
+ */
+#include "stream.hpp"
+#include "../scheme/io.hpp"
+
+namespace tuscany {
+namespace java {
+
+/**
+ * Setup the display and log hooks.
+ */
+bool setupIO() {
+    return true;
+}
+
+}
+}
+#endif /* tuscany_python_pyio_hpp */

Added: tuscany/sca-cpp/trunk/modules/java/java-shell.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/java/java-shell.cpp?rev=897789&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/java/java-shell.cpp (added)
+++ tuscany/sca-cpp/trunk/modules/java/java-shell.cpp Mon Jan 11 08:29:39 2010
@@ -0,0 +1,40 @@
+/*
+ * 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$ */
+
+/**
+ * Java evaluator shell, used for interactive testing of Java classes.
+ */
+
+#include <assert.h>
+#include "gc.hpp"
+#include "stream.hpp"
+#include "string.hpp"
+#include "driver.hpp"
+
+int main(const int argc, char** argv) {
+    tuscany::gc_scoped_pool pool;
+    if (argc != 2) {
+        tuscany::cerr << "Usage: java-shell <class name>" << tuscany::endl;
+        return 1;
+    }
+    tuscany::java::evalDriverRun(argv[1], tuscany::cin, tuscany::cout);
+    return 0;
+}

Added: tuscany/sca-cpp/trunk/modules/java/java-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/java/java-test.cpp?rev=897789&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/java/java-test.cpp (added)
+++ tuscany/sca-cpp/trunk/modules/java/java-test.cpp Mon Jan 11 08:29:39 2010
@@ -0,0 +1,87 @@
+/*
+ * 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$ */
+
+/**
+ * Test Java evaluator.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "driver.hpp"
+
+namespace tuscany {
+namespace java {
+
+bool testEvalExpr() {
+    gc_scoped_pool pool;
+    {
+        const failable<JavaClass> obj = readClass(javaRuntime, "test.CalcImpl");
+        assert(hasContent(obj));
+        const value exp = mklist<value>("mult", 2, 3);
+        const failable<value> r = evalClass(javaRuntime, exp, content(obj));
+        assert(hasContent(r));
+        assert(content(r) == value(6));
+    }
+    {
+        const failable<JavaClass> obj = readClass(javaRuntime, "test.AdderImpl");
+        assert(hasContent(obj));
+        const value exp = mklist<value>("add", 2, 3);
+        const failable<value> r = evalClass(javaRuntime, exp, content(obj));
+        assert(hasContent(r));
+        assert(content(r) == value(5));
+    }
+    return true;
+}
+
+const value add(const list<value>& args) {
+    if (car(args) == "interface")
+        return "test.Adder";
+
+    assert(car(args) == "add");
+    const double x = cadr(args);
+    const double y = caddr(args);
+    return x + y;
+}
+
+bool testEvalLambda() {
+    gc_scoped_pool pool;
+    const failable<JavaClass> obj = readClass(javaRuntime, "test.CalcImpl");
+    assert(hasContent(obj));
+    const value tcel = mklist<value>("add", 3, 4, lambda<value(const list<value>&)>(add));
+    const failable<value> r = evalClass(javaRuntime, tcel, content(obj));
+    assert(hasContent(r));
+    assert(content(r) == value(7));
+    return true;
+}
+
+}
+}
+
+int main() {
+    tuscany::cout << "Testing..." << tuscany::endl;
+
+    //tuscany::java::testEvalExpr();
+    tuscany::java::testEvalLambda();
+
+    tuscany::cout << "OK" << tuscany::endl;
+    return 0;
+}

Added: tuscany/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java?rev=897789&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java (added)
+++ tuscany/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java Mon Jan 11 08:29:39 2010
@@ -0,0 +1,39 @@
+/*
+ * 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.    
+ */
+
+package org.apache.tuscany;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+public class InvocationHandler implements java.lang.reflect.InvocationHandler {
+    final long lambda;
+
+    InvocationHandler(final long lambda) {
+        this.lambda = lambda;
+    }
+    
+    public static Object valueOf(final Class<?> clazz, final long lambda) {
+        return Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, new InvocationHandler(lambda));
+    }
+
+    @Override
+    public native Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable;
+
+}

Added: tuscany/sca-cpp/trunk/modules/java/test/Adder.java
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/java/test/Adder.java?rev=897789&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/java/test/Adder.java (added)
+++ tuscany/sca-cpp/trunk/modules/java/test/Adder.java Mon Jan 11 08:29:39 2010
@@ -0,0 +1,26 @@
+/*
+ * 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.    
+ */
+
+package test;
+
+public interface Adder {
+
+    Double add(Double x, Double y);
+
+}

Added: tuscany/sca-cpp/trunk/modules/java/test/AdderImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/java/test/AdderImpl.java?rev=897789&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/java/test/AdderImpl.java (added)
+++ tuscany/sca-cpp/trunk/modules/java/test/AdderImpl.java Mon Jan 11 08:29:39 2010
@@ -0,0 +1,28 @@
+/*
+ * 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.    
+ */
+
+package test;
+
+public class AdderImpl {
+
+    public Double add(Double x, Double y) {
+        return x + y;
+    }
+
+}

Added: tuscany/sca-cpp/trunk/modules/java/test/CalcImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/java/test/CalcImpl.java?rev=897789&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/java/test/CalcImpl.java (added)
+++ tuscany/sca-cpp/trunk/modules/java/test/CalcImpl.java Mon Jan 11 08:29:39 2010
@@ -0,0 +1,32 @@
+/*
+ * 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.    
+ */
+
+package test;
+
+public class CalcImpl {
+    
+    public Double add(Double x, Double y, Adder adder) {
+        return adder.add(x, y);
+    }
+    
+    public Double mult(Double x, Double y) {
+        return x * y;
+    }
+    
+}