summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/modules/java
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-01-17 09:02:39 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-01-17 09:02:39 +0000
commite34c4a9109bbbb28d7ecef7cccccdc537008f8a5 (patch)
treef1d946b5401763a306068cc7bbfad4ac7d489d8e /sca-cpp/trunk/modules/java
parentb00fe2747627bc95ac8d1d548e0621930a1775a2 (diff)
Integrated Java component support as an HTTPD module. Added test case and store scenario skeleton.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@900072 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-cpp/trunk/modules/java')
-rw-r--r--sca-cpp/trunk/modules/java/client-test.cpp46
-rw-r--r--sca-cpp/trunk/modules/java/domain-test.composite42
-rw-r--r--sca-cpp/trunk/modules/java/eval.hpp132
-rwxr-xr-xsca-cpp/trunk/modules/java/java-conf26
-rw-r--r--sca-cpp/trunk/modules/java/java-test.cpp3
-rw-r--r--sca-cpp/trunk/modules/java/mod-java.cpp54
-rw-r--r--sca-cpp/trunk/modules/java/mod-java.hpp78
-rw-r--r--sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java4
-rw-r--r--sca-cpp/trunk/modules/java/org/apache/tuscany/Service.java38
-rw-r--r--sca-cpp/trunk/modules/java/test/Client.java38
-rw-r--r--sca-cpp/trunk/modules/java/test/ClientImpl.java52
-rw-r--r--sca-cpp/trunk/modules/java/test/Server.java38
-rw-r--r--sca-cpp/trunk/modules/java/test/ServerImpl.java59
13 files changed, 557 insertions, 53 deletions
diff --git a/sca-cpp/trunk/modules/java/client-test.cpp b/sca-cpp/trunk/modules/java/client-test.cpp
new file mode 100644
index 0000000000..d4a4d65ab4
--- /dev/null
+++ b/sca-cpp/trunk/modules/java/client-test.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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 HTTP client functions.
+ */
+
+#include "stream.hpp"
+#include "string.hpp"
+#include "../server/client-test.hpp"
+
+namespace tuscany {
+namespace server {
+
+string testURI = "http://localhost:8090/java";
+
+}
+}
+
+int main() {
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ tuscany::server::testServer();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sca-cpp/trunk/modules/java/domain-test.composite b/sca-cpp/trunk/modules/java/domain-test.composite
new file mode 100644
index 0000000000..e35945f314
--- /dev/null
+++ b/sca-cpp/trunk/modules/java/domain-test.composite
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200903"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://domain/test"
+ name="domain-test">
+
+ <component name="java-test">
+ <implementation.java class="test.ServerImpl"/>
+ <service name="test">
+ <t:binding.http uri="java"/>
+ </service>
+ </component>
+
+ <component name="client-test">
+ <implementation.java class="test.ClientImpl"/>
+ <service name="client">
+ <t:binding.http uri="client"/>
+ </service>
+ <reference name="ref" target="java-test">
+ <t:binding.http/>
+ </reference>
+ </component>
+
+</composite>
diff --git a/sca-cpp/trunk/modules/java/eval.hpp b/sca-cpp/trunk/modules/java/eval.hpp
index b51a57337e..7641c5de79 100644
--- a/sca-cpp/trunk/modules/java/eval.hpp
+++ b/sca-cpp/trunk/modules/java/eval.hpp
@@ -43,20 +43,40 @@ 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);
+ // Get existing JVM
+ jsize nvms = 0;
+ JNI_GetCreatedJavaVMs(&jvm, 1, &nvms);
+ if (nvms == 0) {
+
+ // Create a new 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);
+
+ // Register our native invocation handler function
+ invokerClass = env->FindClass("org/apache/tuscany/InvocationHandler");
+ 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);
+
+ } else {
+
+ // Just hook to existing JVM
+ jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
+ invokerClass = env->FindClass("org/apache/tuscany/InvocationHandler");
+ }
// Capture JVM standard IO
setupIO();
- // Lookup the system classes and methods we need
+ // Lookup the classes and methods we need
classClass = env->FindClass("java/lang/Class");
methodClass = env->FindClass("java/lang/reflect/Method");
objectClass = env->FindClass("java/lang/Object");
@@ -70,22 +90,9 @@ public:
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");
+ parameterTypes = env->GetMethodID(methodClass, "getParameterTypes", "()[Ljava/lang/Class;");
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;
@@ -104,6 +111,7 @@ public:
jmethodID booleanValue;
jmethodID declaredMethods;
jmethodID methodName;
+ jmethodID parameterTypes;
jclass invokerClass;
jmethodID invokerValueOf;
@@ -125,7 +133,7 @@ string lastException(const JavaRuntime& jr) {
/**
* Declare conversion functions.
*/
-const jobject valueToJobject(const JavaRuntime& jr, const value& v);
+const jobject valueToJobject(const JavaRuntime& jr, const value& jtype, 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);
@@ -156,6 +164,22 @@ public:
javaLambda(const JavaRuntime& jr, const value& iface, const lambda<value(const list<value>&)>& func) : jr(jr), iface(iface), func(func) {
}
+ const value operator()(const list<value>& expr) const {
+ const value& op(car(expr));
+ if (op == "toString") {
+ ostringstream os;
+ os << this;
+ return value(string("org.apache.tuscany.InvocationHandler@") + (c_str(str(os)) + 2));
+ }
+ if (op == "hashCode") {
+ return value((double)(long)this);
+ }
+ if (op == "equals") {
+ return value(cadr(expr) == this);
+ }
+ return func(expr);
+ }
+
const JavaRuntime& jr;
const value iface;
const lambda<value(const list<value>&)> func;
@@ -182,23 +206,18 @@ jobject JNICALL nativeInvoke(JNIEnv* env, jobject self, unused jobject proxy, jo
const list<value> expr = cons<value>(func, jarrayToValues(jl.jr, args));
// Invoke the lambda function
- value result = jl.func(expr);
+ value result = jl(expr);
// Convert result to a jobject
- return valueToJobject(jl.jr, result);
+ return valueToJobject(jl.jr, value(), 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"));
+/**
+ * Convert a lambda function to Java proxy.
+ */
+const jobject mkJavaLambda(const JavaRuntime& jr, unused const value& iface, const lambda<value(const list<value>&)>& l) {
const gc_ptr<javaLambda> jl = new (gc_new<javaLambda>()) javaLambda(jr, iface, l);
-
- jclass jc = jr.env->FindClass(c_str(jniClassName(string(iface))));
+ jclass jc = (jclass)(long)(double)iface;
const jobject obj = jr.env->CallStaticObjectMethod(jr.invokerClass, jr.invokerValueOf, jc, (long)(javaLambda*)jl);
return obj;
}
@@ -209,7 +228,7 @@ const jobject mkJavaLambda(const JavaRuntime& jr, const lambda<value(const list<
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)));
+ jr.env->SetObjectArrayElement(a, i, valueToJobject(jr, value(), car(v)));
return valuesToJarrayHelper(jr, a, cdr(v), i + 1);
}
@@ -221,12 +240,12 @@ const jobjectArray valuesToJarray(const JavaRuntime& jr, const list<value>& v) {
/**
* Convert a value to a Java jobject.
*/
-const jobject valueToJobject(const JavaRuntime& jr, const value& v) {
+const jobject valueToJobject(const JavaRuntime& jr, const value& jtype, const value& v) {
switch (type(v)) {
case value::List:
return valuesToJarray(jr, v);
case value::Lambda:
- return mkJavaLambda(jr, v);
+ return mkJavaLambda(jr, jtype, v);
case value::Symbol:
return jr.env->NewStringUTF(c_str(string("'") + v));
case value::String:
@@ -243,17 +262,17 @@ const jobject valueToJobject(const JavaRuntime& jr, const value& v) {
/**
* Convert a list of values to an array of jvalues.
*/
-const jvalue* valuesToJvaluesHelper(const JavaRuntime& jr, jvalue* a, const list<value>& v) {
+const jvalue* valuesToJvaluesHelper(const JavaRuntime& jr, jvalue* a, const list<value>& types, const list<value>& v) {
if (isNil(v))
return a;
- a->l = valueToJobject(jr, car(v));
- return valuesToJvaluesHelper(jr, a + 1, cdr(v));
+ a->l = valueToJobject(jr, car(types), car(v));
+ return valuesToJvaluesHelper(jr, a + 1, cdr(types), cdr(v));
}
-const jvalue* valuesToJvalues(const JavaRuntime& jr, const list<value>& v) {
+const jvalue* valuesToJvalues(const JavaRuntime& jr, const list<value>& types, const list<value>& v) {
const int n = length(v);
jvalue* a = new (gc_anew<jvalue>(n)) jvalue[n];
- valuesToJvaluesHelper(jr, a, v);
+ valuesToJvaluesHelper(jr, a, types, v);
return a;
}
@@ -267,6 +286,8 @@ const list<value> jarrayToValuesHelper(const JavaRuntime& jr, jobjectArray a, co
}
const list<value> jarrayToValues(const JavaRuntime& jr, jobjectArray o) {
+ if (o == NULL)
+ return list<value>();
return jarrayToValuesHelper(jr, o, 0, jr.env->GetArrayLength(o));
}
@@ -315,15 +336,30 @@ const value jobjectToValue(const JavaRuntime& jr, const jobject o) {
}
/**
- * Returns a balanced tree of a class' methods.
+ * Returns a balanced tree of the methods of a class.
*/
+const value parameterTypeToValue(const jobject t) {
+ return value((double)(long)t);
+}
+
+const list<value> parameterTypesToValues(const JavaRuntime& jr, const jobjectArray t, const int i) {
+ if (i == 0)
+ return list<value>();
+ return cons<value>(parameterTypeToValue(jr.env->GetObjectArrayElement(t, i - 1)), parameterTypesToValues(jr, t, i - 1));
+}
+
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 jobjectArray t = (jobjectArray)jr.env->CallObjectMethod(m, jr.parameterTypes);
+ const list<value> types = reverse(parameterTypesToValues(jr, t, jr.env->GetArrayLength(t)));
+
+ return cons<value>(c_str(name), cons<value>((double)(long)mid, types));
}
const list<value> methodsToValues(const JavaRuntime& jr, const jobjectArray m, const int i) {
@@ -382,7 +418,7 @@ const failable<value> 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, cdr<value>(expr));
+ const jvalue *args = valuesToJvalues(jr, cddr(func), cdr<value>(expr));
// Call the Java function
const jobject result = jr.env->CallObjectMethodA(jc.obj, fid, args);
diff --git a/sca-cpp/trunk/modules/java/java-conf b/sca-cpp/trunk/modules/java/java-conf
new file mode 100755
index 0000000000..d81a14a6c1
--- /dev/null
+++ b/sca-cpp/trunk/modules/java/java-conf
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# 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.
+
+# Generate a Java server conf
+here=`readlink -f $0`; here=`dirname $here`
+root=`readlink -f $1`
+
+cat >>$root/conf/httpd.conf <<EOF
+LoadModule mod_tuscany_eval $here/.libs/libmod_tuscany_java.so
+EOF
diff --git a/sca-cpp/trunk/modules/java/java-test.cpp b/sca-cpp/trunk/modules/java/java-test.cpp
index e50cfe5671..7ece2dfc68 100644
--- a/sca-cpp/trunk/modules/java/java-test.cpp
+++ b/sca-cpp/trunk/modules/java/java-test.cpp
@@ -53,9 +53,6 @@ bool testEvalExpr() {
}
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);
diff --git a/sca-cpp/trunk/modules/java/mod-java.cpp b/sca-cpp/trunk/modules/java/mod-java.cpp
new file mode 100644
index 0000000000..a5dc48679d
--- /dev/null
+++ b/sca-cpp/trunk/modules/java/mod-java.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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$ */
+
+/**
+ * HTTPD module used to eval Java component implementations.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "../server/mod-cpp.hpp"
+#include "../server/mod-eval.hpp"
+#include "mod-java.hpp"
+
+namespace tuscany {
+namespace server {
+namespace modeval {
+
+/**
+ * Evaluate a Java component implementation and convert it to an applicable
+ * lambda function.
+ */
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) {
+ const string itype(elementName(impl));
+ if (contains(itype, ".java"))
+ return modjava::evalImplementation(path, impl, px);
+ if (contains(itype, ".cpp"))
+ return modcpp::evalImplementation(path, impl, px);
+ return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype);
+}
+
+}
+}
+}
diff --git a/sca-cpp/trunk/modules/java/mod-java.hpp b/sca-cpp/trunk/modules/java/mod-java.hpp
new file mode 100644
index 0000000000..933550b7c3
--- /dev/null
+++ b/sca-cpp/trunk/modules/java/mod-java.hpp
@@ -0,0 +1,78 @@
+/*
+ * 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_modjava_hpp
+#define tuscany_modjava_hpp
+
+/**
+ * Evaluation functions used by mod-eval to evaluate Java
+ * component implementations.
+ */
+
+#include "string.hpp"
+#include "stream.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+#include "eval.hpp"
+#include "../http/httpd.hpp"
+
+namespace tuscany {
+namespace server {
+namespace modjava {
+
+/**
+ * Apply a Java component implementation function.
+ */
+struct applyImplementation {
+ java::JavaClass impl;
+ const list<value> px;
+ applyImplementation(const java::JavaClass& impl, const list<value>& px) : impl(impl), px(px) {
+ }
+ const value operator()(const list<value>& params) const {
+ const value expr = append<value>(params, px);
+ debug(expr, "modeval::java::applyImplementation::input");
+ const failable<value> val = java::evalClass(java::javaRuntime, expr, impl);
+ debug(val, "modeval::java::applyImplementation::result");
+ if (!hasContent(val))
+ return mklist<value>(value(), reason(val));
+ return mklist<value>(content(val));
+ }
+};
+
+/**
+ * Evaluate a Java component implementation and convert it to an applicable
+ * lambda function.
+ */
+const failable<lambda<value(const list<value>&)> > evalImplementation(unused const string& path, const value& impl, const list<value>& px) {
+ const string cn(attributeValue("class", impl));
+ const failable<java::JavaClass> jc = java::readClass(java::javaRuntime, cn);
+ if (!hasContent(jc))
+ return mkfailure<lambda<value(const list<value>&)> >(reason(jc));
+ return lambda<value(const list<value>&)>(applyImplementation(content(jc), px));
+}
+
+}
+}
+}
+
+#endif /* tuscany_modjava_hpp */
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 423fe6248d..1c159a99d5 100644
--- a/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java
+++ b/sca-cpp/trunk/modules/java/org/apache/tuscany/InvocationHandler.java
@@ -29,8 +29,8 @@ public class InvocationHandler implements java.lang.reflect.InvocationHandler {
this.lambda = lambda;
}
- public static Object valueOf(final Class<?> clazz, final long lambda) {
- return Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, new InvocationHandler(lambda));
+ public static Object valueOf(final Class<?> iface, final long lambda) {
+ return Proxy.newProxyInstance(iface.getClassLoader(), new Class[]{iface}, new InvocationHandler(lambda));
}
@Override
diff --git a/sca-cpp/trunk/modules/java/org/apache/tuscany/Service.java b/sca-cpp/trunk/modules/java/org/apache/tuscany/Service.java
new file mode 100644
index 0000000000..c8152463b4
--- /dev/null
+++ b/sca-cpp/trunk/modules/java/org/apache/tuscany/Service.java
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+public interface Service {
+
+ String post(Object[] item);
+
+ Object[] get(String id);
+
+ Object[] getall();
+
+ boolean put(String id, Object[] item);
+
+ boolean delete(String id);
+
+ boolean deleteall();
+
+ <T> T apply(Object... params);
+
+}
diff --git a/sca-cpp/trunk/modules/java/test/Client.java b/sca-cpp/trunk/modules/java/test/Client.java
new file mode 100644
index 0000000000..447b408cd4
--- /dev/null
+++ b/sca-cpp/trunk/modules/java/test/Client.java
@@ -0,0 +1,38 @@
+/*
+ * 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 Client {
+
+ String echo(String x);
+
+ Object[] getall();
+
+ Object[] get(String id);
+
+ String post(Object[] item);
+
+ Boolean put(String id, Object[] entry);
+
+ Boolean deleteall();
+
+ Boolean delete(String id);
+
+}
diff --git a/sca-cpp/trunk/modules/java/test/ClientImpl.java b/sca-cpp/trunk/modules/java/test/ClientImpl.java
new file mode 100644
index 0000000000..3d3063b608
--- /dev/null
+++ b/sca-cpp/trunk/modules/java/test/ClientImpl.java
@@ -0,0 +1,52 @@
+/*
+ * 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 ClientImpl {
+
+ public String echo(String x, Server server) {
+ return server.echo(x);
+ }
+
+ public Object[] getall(Server server) {
+ return server.getall();
+ }
+
+ public Object[] get(String id, Server server) {
+ return server.get(id);
+ }
+
+ public String post(Object[] item, Server server) {
+ return server.post(item);
+ }
+
+ public Boolean put(String id, Object[] item, Server server) {
+ return server.put(id, item);
+ }
+
+ public Boolean deleteall(Server server) {
+ return server.deleteall();
+ }
+
+ public Boolean delete(String id, Server server) {
+ return server.delete(id);
+ }
+
+}
diff --git a/sca-cpp/trunk/modules/java/test/Server.java b/sca-cpp/trunk/modules/java/test/Server.java
new file mode 100644
index 0000000000..a165988550
--- /dev/null
+++ b/sca-cpp/trunk/modules/java/test/Server.java
@@ -0,0 +1,38 @@
+/*
+ * 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 Server {
+
+ String echo(String x);
+
+ Object[] getall();
+
+ Object[] get(String id);
+
+ String post(Object[] item);
+
+ Boolean put(String id, Object[] entry);
+
+ Boolean deleteall();
+
+ Boolean delete(String id);
+
+}
diff --git a/sca-cpp/trunk/modules/java/test/ServerImpl.java b/sca-cpp/trunk/modules/java/test/ServerImpl.java
new file mode 100644
index 0000000000..f82a8a24b5
--- /dev/null
+++ b/sca-cpp/trunk/modules/java/test/ServerImpl.java
@@ -0,0 +1,59 @@
+/*
+ * 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 ServerImpl {
+
+ Object[] list(Object... o) {
+ return o;
+ }
+
+ public String echo(String x) {
+ return x;
+ }
+
+ public Object[] getall() {
+ return list("Sample Feed", "123456789",
+ list("Item", "111", list(list("'javaClass", "services.Item"), list("'name", "Apple"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 2.99))),
+ list("Item", "222", list(list("'javaClass", "services.Item"), list("'name", "Orange"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 3.55))),
+ list("Item", "333", list(list("'javaClass", "services.Item"), list("name", "Pear"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 1.55))));
+ }
+
+ public Object[] get(String id) {
+ Object[] entry = list(list("'javaClass", "services.Item"), list("'name", "Apple"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 2.99));
+ return list("Item", id, entry);
+ }
+
+ public String post(Object[] item) {
+ return "123456789";
+ }
+
+ public Boolean put(String id, Object[] entry) {
+ return true;
+ }
+
+ public Boolean deleteall() {
+ return true;
+ }
+
+ public Boolean delete(String id) {
+ return true;
+ }
+}