[shimdandy] 02/21: upstream at 1.2.0

Tony Mancill tmancill at moszumanska.debian.org
Sun Aug 13 15:08:27 UTC 2017


This is an automated email from the git hooks/post-receive script.

tmancill pushed a commit to branch master
in repository shimdandy.

commit 148989372c829047ec4269fc0250b3e37fa34aa0
Author: Tom Marble <tmarble at info9.net>
Date:   Fri Aug 11 09:10:13 2017 -0500

    upstream at 1.2.0
---
 .gitignore                                         |   4 +
 README.md                                          |  82 +++
 api/pom.xml                                        |  14 +
 .../projectodd/shimdandy/ClojureRuntimeShim.java   | 195 +++++++
 impl/pom.xml                                       |  34 ++
 .../shimdandy/impl/ClojureRuntimeShimImpl.java     | 609 +++++++++++++++++++++
 .../shimdandy/impl/ClojureRuntimeShimImplTest.java |  41 ++
 pom.xml                                            |  75 +++
 8 files changed, 1054 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8b29c57
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+target
+*.iml
+*.idea
+*~
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b77b0b4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,82 @@
+# ShimDandy
+
+A Clojure runtime shim, allowing for multiple Clojure runtimes in the
+same JVM.
+
+Clojure has a static runtime (implemented as static methods off of
+clojure.lang.RT), so to run multiple runtimes in the same JVM, they
+have to be loaded in isolated ClassLoader trees. ShimDandy provides a
+mechanism for isolating the runtimes within a non-Clojure application,
+and for calling in to the runtimes from the app.
+
+## Usage
+
+The project provides two artifacts: `shimdandy-api.jar` and
+`shimdandy-impl.jar`. `shimdandy-api` can be on the boot classpath of
+your app, but `shimdandy-impl` should not be on the boot classpath or
+exposed to any ClassLoader initially. Nor should any Clojure jars -
+having a Clojure jar on the classpath will cause the RT from that jar
+(and only that RT) to be loaded, preventing isolation.
+
+You then create a ClassLoader that has access to `shimdandy-impl.jar`,
+`clojure.jar`, and any dependencies you want in the runtime
+(`URLClassLoader` works well for this). That ClassLoader is then
+passed to `ClojureRuntimeShim.newRuntime`, which returns a
+`ClojureRuntimeShim` instance. This instance provides `require` and
+`invoke` methods that can be used to call in to the runtime.
+
+Example:
+
+    URL[] urls = {new URL("file:/path/to/shimdandy-impl.jar"),
+                  new URL("file:/path/to/clojure.jar"),
+                  new URL("file:/path/to/app/src/")};
+    ClassLoader cl = new URLClassLoader(urls, parentClassLoader);
+    ClojureRuntimeShim runtime = ClojureRuntimeShim.newRuntime(cl, "my-app-name");
+
+    runtime.require("my-app.core");
+    Object retval = runtime.invoke("my-app.core/some-fn", arg1, arg2);
+
+When you are done with a shim, you should close it:
+
+    runtime.close();
+
+The latest version is `1.2.0`:
+
+    <dependency>
+      <groupId>org.projectodd.shimdandy</groupId>
+      <artifactId>shimdandy-api</artifactId>
+      <version>1.2.0</version>
+    </dependency>
+
+## Preventing memory leaks
+
+If any code in the shim used an agent or a future, the agent thread
+pool will have been started, and those threads will continue to run
+after you are done with the shim. This will consume a few resources,
+but the bigger concern is the contextClassLoader for those threads
+will hold a reference to the shim's classloader, which will prevent
+any classes loaded in the shim from being unloaded. Those classes will
+eventually cause an OutOfMemoryException from exhausted permgen space
+if you create lots of shims. It's best practice to `close()` the shim
+when you are done with it (see above). This will shutdown the agent
+pool for you.
+
+This same caveat applies to any other threads started from within the
+shim - you need to make sure they are stopped. One particular culprit
+is the `clojure.core.async.impl.timers/timeout-daemon` thread. If you
+use `core.async`, you need to interrupt that thread on shim shutdown
+to interrupt its loop and allow it to exit.
+
+If you are using a `URLClassLoader`, you should also `close()` it when
+you are done with the shim, as some implementations may leak file
+descriptors.
+
+In addition, be sure to use Clojure 1.6.0 or newer to prevent
+[other memory leaks](http://dev.clojure.org/jira/browse/CLJ-1125).
+
+I realize the example here is pretty sparse - please file an issue if
+you have any questions.
+
+Copyright (C) 2013-2015 Tobias Crawley.
+
+Licensed under the Eclipse Public License v1.0
diff --git a/api/pom.xml b/api/pom.xml
new file mode 100644
index 0000000..4b5f4e7
--- /dev/null
+++ b/api/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.projectodd.shimdandy</groupId>
+    <artifactId>shimdandy-parent</artifactId>
+    <version>1.2.0</version>
+  </parent>
+  <groupId>org.projectodd.shimdandy</groupId>
+  <artifactId>shimdandy-api</artifactId>
+  <version>1.2.0</version>
+  <name>shimdandy-api</name>
+  <description>shimdandy API</description>
+</project>
diff --git a/api/src/main/java/org/projectodd/shimdandy/ClojureRuntimeShim.java b/api/src/main/java/org/projectodd/shimdandy/ClojureRuntimeShim.java
new file mode 100644
index 0000000..2cd6794
--- /dev/null
+++ b/api/src/main/java/org/projectodd/shimdandy/ClojureRuntimeShim.java
@@ -0,0 +1,195 @@
+package org.projectodd.shimdandy;
+
+/**
+ * Provides a shim for accessing the Clojure runtime without loading Clojure classes in the
+ * current classLoader.
+ *
+ * @author toby at projectodd.org
+ */
+public abstract class ClojureRuntimeShim {
+    /**
+     * Creates a new runtime shim. The given classLoader must be able to find shimdandy classes and
+     * ClojureRuntimeShimImpl.
+     */
+    public static ClojureRuntimeShim newRuntime(ClassLoader classLoader, String name) {
+        ClojureRuntimeShim runtime;
+        try {
+            runtime = (ClojureRuntimeShim)classLoader
+                    .loadClass("org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl")
+                    .newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to load ClojureRuntimeShimImpl", e);
+        }
+
+        runtime.setClassLoader( classLoader );
+        runtime.setName( name );
+        runtime.init();
+
+        return runtime;
+    }
+
+    public static ClojureRuntimeShim newRuntime(ClassLoader classLoader) {
+        return newRuntime(classLoader, null);
+    }
+
+    public void close() {
+        invoke("clojure.core/shutdown-agents");
+    }
+
+    public abstract void require(String... namespaces);
+
+    public abstract Object invoke(String namespacedFunction);
+
+    public abstract Object invoke(Object fn);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1);
+
+    public abstract Object invoke(Object fn, Object arg1);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
+                                  Object arg15);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
+                                  Object arg15);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
+                                  Object arg15, Object arg16);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
+                                  Object arg15, Object arg16);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
+                                  Object arg15, Object arg16, Object arg17);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
+                                  Object arg15, Object arg16, Object arg17);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
+                                  Object arg15, Object arg16, Object arg17, Object arg18);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
+                                  Object arg15, Object arg16, Object arg17, Object arg18);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
+                                  Object arg15, Object arg16, Object arg17, Object arg18, Object arg19);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
+                                  Object arg15, Object arg16, Object arg17, Object arg18, Object arg19);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
+                                  Object arg15, Object arg16, Object arg17, Object arg18, Object arg19, Object arg20);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
+                                  Object arg15, Object arg16, Object arg17, Object arg18, Object arg19, Object arg20);
+
+    public abstract Object invoke(String namespacedFunction, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
+                                  Object arg15, Object arg16, Object arg17, Object arg18, Object arg19, Object arg20,
+                                  Object... args);
+
+    public abstract Object invoke(Object fn, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                                  Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,
+                                  Object arg15, Object arg16, Object arg17, Object arg18, Object arg19, Object arg20,
+                                  Object... args);
+
+
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setClassLoader(ClassLoader classLoader) {
+        this.classLoader = classLoader;
+    }
+
+    public ClassLoader getClassLoader() {
+        return this.classLoader;
+    }
+
+    public abstract void init();
+
+    protected ClassLoader classLoader;
+    protected String name;
+}
diff --git a/impl/pom.xml b/impl/pom.xml
new file mode 100644
index 0000000..7caa60b
--- /dev/null
+++ b/impl/pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.projectodd.shimdandy</groupId>
+    <artifactId>shimdandy-parent</artifactId>
+    <version>1.2.0</version>
+  </parent>
+  <groupId>org.projectodd.shimdandy</groupId>
+  <artifactId>shimdandy-impl</artifactId>
+  <version>1.2.0</version>
+  <name>shimdandy-impl</name>
+  <description>shimdandy Implementation</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.projectodd.shimdandy</groupId>
+      <artifactId>shimdandy-api</artifactId>
+      <version>${project.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.clojure</groupId>
+      <artifactId>clojure</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.11</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/impl/src/main/java/org/projectodd/shimdandy/impl/ClojureRuntimeShimImpl.java b/impl/src/main/java/org/projectodd/shimdandy/impl/ClojureRuntimeShimImpl.java
new file mode 100644
index 0000000..e3d1a39
--- /dev/null
+++ b/impl/src/main/java/org/projectodd/shimdandy/impl/ClojureRuntimeShimImpl.java
@@ -0,0 +1,609 @@
+package org.projectodd.shimdandy.impl;
+
+import clojure.lang.IFn;
+import clojure.lang.RT;
+import clojure.lang.Symbol;
+import clojure.lang.Var;
+import org.projectodd.shimdandy.ClojureRuntimeShim;
+
+import java.lang.reflect.Field;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ */
+public class ClojureRuntimeShimImpl extends ClojureRuntimeShim {
+    public void init() {
+        ClassLoader origLoader = preInvoke();
+        Exception ex = null;
+        try {
+            Field dvalField = Var.class.getDeclaredField("dvals");
+            dvalField.setAccessible(true);
+            this.dvals = (ThreadLocal)dvalField.get(null);
+            
+            this.require = RT.var("clojure.core", "require");
+            this.resolve = RT.var("clojure.core", "resolve");
+            clojure.lang.Compiler.LOADER.bindRoot(this.classLoader);
+        } catch (IllegalAccessException e) {
+            ex = e;
+        } catch (NoSuchFieldException e) {
+            ex = e;
+        } finally {
+            postInvoke(origLoader);
+        }
+
+        if (ex != null) {
+            throw new RuntimeException("Failed to access Var.dvals", ex);
+        }
+    }
+
+    protected ClassLoader preInvoke() {
+        final ClassLoader originalClassloader = Thread.currentThread().getContextClassLoader();
+        Thread.currentThread().setContextClassLoader(this.classLoader);
+        this.callDepth.get().getAndIncrement();
+
+        return originalClassloader;
+    }
+
+    protected void postInvoke(ClassLoader loader) {
+        if (this.callDepth.get().decrementAndGet() == 0) {
+            this.dvals.remove();
+            this.callDepth.remove();
+        }
+        Thread.currentThread().setContextClassLoader(loader);
+    }
+
+    protected Var var(String namespacedFunction) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            Var var = (Var)this.resolve.invoke(Symbol.create(namespacedFunction));
+            if (var == null) {
+                String[] parts = namespacedFunction.split("/");
+                this.require.invoke(Symbol.create(parts[0]));
+                var = RT.var(parts[0], parts[1]);
+            }
+
+            return var;
+        } catch (Exception e) {
+            throw new RuntimeException( "Failed to load Var " + namespacedFunction, e );
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public void require(String... namespaces) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            for (String ns : namespaces) {
+              this.require.invoke(Symbol.create(ns));
+            }
+        } finally {
+            postInvoke(origLoader);
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction) {
+        return invoke( var( namespacedFunction ) );
+    }
+
+    @Override
+    public Object invoke(Object fn) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke();
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1) {
+        return invoke( var( namespacedFunction ), arg1 );
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2) {
+        return invoke( var( namespacedFunction ), arg1, arg2);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3) {
+        return invoke( var( namespacedFunction ), arg1, arg2, arg3);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2, arg3);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7,
+                      arg8);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7,
+                                    arg8);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7,
+                      arg8, arg9);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7,
+                                    arg8, arg9);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7,
+                      arg8, arg9, arg10);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7,
+                                    arg8, arg9, arg10);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7,
+                      arg8, arg9, arg10, arg11);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7,
+                                    arg8, arg9, arg10, arg11);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7,
+                      arg8, arg9, arg10, arg11, arg12);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7,
+                                    arg8, arg9, arg10, arg11, arg12);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7,
+                      arg8, arg9, arg10, arg11, arg12,
+                      arg13);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7,
+                                    arg8, arg9, arg10, arg11, arg12,
+                                    arg13);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7,
+                      arg8, arg9, arg10, arg11, arg12,
+                      arg13, arg14);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7,
+                                    arg8, arg9, arg10, arg11, arg12,
+                                    arg13, arg14);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14, Object arg15) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7,
+                      arg8, arg9, arg10, arg11, arg12,
+                      arg13, arg14, arg15);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14, Object arg15) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7,
+                                    arg8, arg9, arg10, arg11, arg12,
+                                    arg13, arg14, arg15);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14, Object arg15, Object arg16) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7,
+                      arg8, arg9, arg10, arg11, arg12,
+                      arg13, arg14, arg15, arg16);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14, Object arg15, Object arg16) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7,
+                                    arg8, arg9, arg10, arg11, arg12,
+                                    arg13, arg14, arg15, arg16);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14, Object arg15, Object arg16, Object arg17) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7,
+                      arg8, arg9, arg10, arg11, arg12,
+                      arg13, arg14, arg15, arg16, arg17);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14, Object arg15, Object arg16, Object arg17) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7,
+                                    arg8, arg9, arg10, arg11, arg12,
+                                    arg13, arg14, arg15, arg16, arg17);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14, Object arg15, Object arg16,
+                         Object arg17, Object arg18) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7,
+                      arg8, arg9, arg10, arg11, arg12,
+                      arg13, arg14, arg15, arg16,
+                      arg17, arg18);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14, Object arg15, Object arg16,
+                         Object arg17, Object arg18) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7,
+                                    arg8, arg9, arg10, arg11, arg12,
+                                    arg13, arg14, arg15, arg16,
+                                    arg17, arg18);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14, Object arg15, Object arg16,
+                         Object arg17, Object arg18, Object arg19) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7,
+                      arg8, arg9, arg10, arg11, arg12,
+                      arg13, arg14, arg15, arg16,
+                      arg17, arg18, arg19);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14, Object arg15, Object arg16,
+                         Object arg17, Object arg18, Object arg19) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7,
+                                    arg8, arg9, arg10, arg11, arg12,
+                                    arg13, arg14, arg15, arg16,
+                                    arg17, arg18, arg19);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14, Object arg15, Object arg16,
+                         Object arg17, Object arg18, Object arg19, Object arg20) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7,
+                      arg8, arg9, arg10, arg11, arg12,
+                      arg13, arg14, arg15, arg16,
+                      arg17, arg18, arg19, arg20);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14, Object arg15, Object arg16,
+                         Object arg17, Object arg18, Object arg19, Object arg20) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7,
+                                    arg8, arg9, arg10, arg11, arg12,
+                                    arg13, arg14, arg15, arg16,
+                                    arg17, arg18, arg19, arg20);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    @Override
+    public Object invoke(String namespacedFunction, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14, Object arg15, Object arg16,
+                         Object arg17, Object arg18, Object arg19, Object arg20,
+                         Object... args) {
+        return invoke(var( namespacedFunction ), arg1, arg2,
+                      arg3, arg4, arg5, arg6, arg7,
+                      arg8, arg9, arg10, arg11, arg12,
+                      arg13, arg14, arg15, arg16,
+                      arg17, arg18, arg19, arg20,
+                      args);
+    }
+
+    @Override
+    public Object invoke(Object fn, Object arg1, Object arg2,
+                         Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,
+                         Object arg8, Object arg9, Object arg10, Object arg11, Object arg12,
+                         Object arg13, Object arg14, Object arg15, Object arg16,
+                         Object arg17, Object arg18, Object arg19, Object arg20,
+                         Object... args) {
+        ClassLoader origLoader = preInvoke();
+        try {
+            return ((IFn)fn).invoke(arg1, arg2,
+                                    arg3, arg4, arg5, arg6, arg7,
+                                    arg8, arg9, arg10, arg11, arg12,
+                                    arg13, arg14, arg15, arg16,
+                                    arg17, arg18, arg19, arg20,
+                                    args);
+        } finally {
+            postInvoke( origLoader );
+        }
+    }
+
+    private Var require;
+    private Var resolve;
+    private ThreadLocal dvals;
+    private final ThreadLocal<AtomicLong> callDepth = new ThreadLocal<AtomicLong>() {
+      protected AtomicLong initialValue() {
+          return new AtomicLong(0);
+      }
+    };
+}
diff --git a/impl/src/test/java/org/projectodd/shimdandy/impl/ClojureRuntimeShimImplTest.java b/impl/src/test/java/org/projectodd/shimdandy/impl/ClojureRuntimeShimImplTest.java
new file mode 100644
index 0000000..813a420
--- /dev/null
+++ b/impl/src/test/java/org/projectodd/shimdandy/impl/ClojureRuntimeShimImplTest.java
@@ -0,0 +1,41 @@
+package org.projectodd.shimdandy.impl;
+
+import clojure.lang.Symbol;
+import clojure.lang.Var;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class ClojureRuntimeShimImplTest {
+    @Before
+    public void setup() {
+        shim = new ClojureRuntimeShimImpl();
+        shim.setClassLoader(Symbol.class.getClassLoader());
+        shim.init();
+    }
+
+    @Test
+    public void testVarWhenVarExistsInRTOnly() {
+        Object ns = shim.invoke("clojure.core/create-ns", Symbol.create("foo"));
+        Var intern = shim.var("clojure.core/intern");
+        intern.invoke(ns, Symbol.create("bar"), "baz");
+        Var bar = shim.var("foo/bar");
+        assertNotNull(bar);
+        assertEquals("baz", bar.deref());
+    }
+
+    @Test
+    public void testVarWhenNSExists() {
+        Var trim = shim.var("clojure.string/trim");
+        assertNotNull(trim);
+    }
+
+    @Test
+    public void testInvoke() {
+        assertEquals("ham", shim.invoke("clojure.core/identity", "ham"));
+    }
+
+    private ClojureRuntimeShimImpl shim;
+}
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..4f48685
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.projectodd.shimdandy</groupId>
+  <artifactId>shimdandy-parent</artifactId>
+  <version>1.2.0</version>
+  <packaging>pom</packaging>
+  <description>Shimdandy parent POM</description>
+
+  <name>shimdandy-parent</name>
+  <url>https://github.com/projectodd/shimdandy</url>
+
+  <licenses>
+    <license>
+      <name>Eclipse Public License - v 1.0</name>
+      <url>http://www.eclipse.org/legal/epl-v10.html</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+
+  <parent>
+    <groupId>org.sonatype.oss</groupId>
+    <artifactId>oss-parent</artifactId>
+    <version>7</version>
+  </parent>
+
+  <scm>
+    <connection>scm:git:git at github.com:projectodd/shimdandy.git</connection>
+    <developerConnection>scm:git:git at github.com:projectodd/shimdandy.git</developerConnection>
+    <url>https://github.com/projectodd/shimdandy/</url>
+  </scm>
+
+  <developers>
+    <developer>
+      <id>tcrawey</id>
+      <name>Toby Crawley</name>
+      <email>toby at tcrawley.org</email>
+    </developer>
+  </developers>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <version.clojure>1.7.0-alpha4</version.clojure>
+  </properties>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.clojure</groupId>
+        <artifactId>clojure</artifactId>
+        <version>${version.clojure}</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <modules>
+    <module>api</module>
+    <module>impl</module>
+  </modules>
+
+<distributionManagement>
+  <repository>
+     <id>sonatype-nexus-staging</id>
+     <name>Nexus Staging Repo</name>
+     <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
+  </repository>
+  <snapshotRepository>
+     <id>sonatype-nexus-snapshots</id>
+     <name>Nexus Snapshot Repo</name>
+     <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
+  </snapshotRepository>
+</distributionManagement>
+
+</project>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/shimdandy.git



More information about the pkg-java-commits mailing list