From: Waldemar Kozaczuk <jwkozac...@gmail.com>
Committer: Avi Kivity <a...@scylladb.com>
Branch: master

Provide alternative java.so to start jvm without classloader and log manager isolation in order to run JRE compact profiles.

In order to run a JVM app using compact profile 1, 2 or 3 JRE the Java bootstrap code under runjava cannot depend on java.beans.* that is not part of any of the compact profiles. More specifically runjava depends on cglib and asm java libraries that manipulate bytecode and rely on java.beans*.

Therefore the changes that are part of this commit essentially allow to bootstrap a JVM app in one of two modes: - old one which provides classloader and JUL log manager isolation between potential multiple apps and runjava code and apps that possibly targets multi-apps on single JVM in OSv and requires full JRE - new one which does NOT provide any classloader and JUL log manager isolation and targets single main method apps on JVM in OSv and allows using compact profile 1, 2 or 3

    Following changes are part of this commit:

* Added io.osv.isolated and io.osv.nonisolated packages under java/runjava and refactored ContextIsolator to create Jvm, NonIsolatedJvm, RunNonIsolatedJvmApp, IsolatedJvm, RunIsolatedJvmApp classes

* Changed java.cc and makefile to support producing two executable - old java.so that can run multiple JVM apps in isolated fashion (class loader, log manager, etc) and new java_non_isolated.so that can run single JVM app without any isolation of the former one

* Changed java/jvm/java.cc to print which java class it uses to bootstrap - isolated or nonisolated one; fixed Makefile to properly handle building of java_non_isolated.so

    * Added java_non_isolated.so to modules/java-tests/usr.manifest

* Added java_non_isolated test to test.py; modified testing.py to detect failure to start *.so

* Added unit tests to test running non-isolated JVM app to tests-isolates

Fixes #497

Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com>
Message-Id: <1471017677-4249-1-git-send-email-jwkozac...@gmail.com>
Signed-off-by: Avi Kivity <a...@scylladb.com>

---
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -136,7 +136,8 @@ very-quiet = $(if $V, $1, @$1)
 ifeq ($(arch),aarch64)
 java-targets :=
 else
-java-targets := $(out)/java/jvm/java.so $(out)/java/jni/balloon.so $(out)/java/jni/elf-loader.so $(out)/java/jni/networking.so \ +java-targets := $(out)/java/jvm/java.so $(out)/java/jvm/java_non_isolated.so \ + $(out)/java/jni/balloon.so $(out)/java/jni/elf-loader.so $(out)/java/jni/networking.so \ $(out)/java/jni/stty.so $(out)/java/jni/tracepoint.so $(out)/java/jni/power.so $(out)/java/jni/monitor.so
 endif

@@ -376,6 +377,10 @@ $(out)/%.o: %.c | generated-headers
        $(makedir)
        $(call quiet, $(CC) $(CFLAGS) -c -o $@ $<, CC $*.c)

+$(out)/java/jvm/java_non_isolated.o: java/jvm/java.cc | generated-headers
+       $(makedir)
+ $(call quiet, $(CXX) $(CXXFLAGS) -DRUN_JAVA_NON_ISOLATED -o $@ -c java/jvm/java.cc, CXX $<)
+
 $(out)/%.o: %.S
        $(makedir)
        $(call quiet, $(CXX) $(CXXFLAGS) $(ASFLAGS) -c -o $@ $<, AS $*.s)
diff --git a/java/jvm/java.cc b/java/jvm/java.cc
--- a/java/jvm/java.cc
+++ b/java/jvm/java.cc
@@ -30,7 +30,11 @@ extern size_t jvm_heap_size;
 // parameters.

 #define JVM_PATH        "/usr/lib/jvm/jre/lib/amd64/server/libjvm.so"
-#define RUNJAVA "io/osv/RunJava" // separated by slashes, not dots
+#if defined(RUN_JAVA_NON_ISOLATED)
+#define RUNJAVA "io/osv/nonisolated/RunNonIsolatedJvmApp" // separated by slashes, not dots
+#else
+#define RUNJAVA "io/osv/isolated/RunIsolatedJvmApp" // separated by slashes, not dots
+#endif

 JavaVMOption mkoption(const char* s)
 {
@@ -96,6 +100,8 @@ static void on_vm_stop(JNIEnv *env, jclass clz) {

 static int java_main(int argc, char **argv)
 {
+    std::cout << "java.so: Starting JVM app using: " << RUNJAVA << "\n";
+
     auto prog = elf::get_program();
     // The JVM library remains loaded as long as jvm_so is in scope.
     auto jvm_so = prog->get_library(JVM_PATH);
@@ -108,8 +114,11 @@ static int java_main(int argc, char **argv)

     std::vector<JavaVMOption> options;
     options.push_back(mkoption("-Djava.class.path=/dev/null"));
- options.push_back(mkoption("-Djava.system.class.loader=io.osv.OsvSystemClassLoader"));
+#if !defined(RUN_JAVA_NON_ISOLATED)
+ std::cout << "java.so: Setting Java system classloader and logging manager to the isolated ones" << "\n"; + options.push_back(mkoption("-Djava.system.class.loader=io.osv.isolated.OsvSystemClassLoader")); options.push_back(mkoption("-Djava.util.logging.manager=io.osv.jul.IsolatingLogManager"));
+#endif
     options.push_back(mkoption("-Dosv.version=" + osv::version()));

     {
diff --git a/java/runjava/src/main/java/io/osv/AppThreadTerminatedWithUncaughtException.java b/java/runjava/src/main/java/io/osv/AppThreadTerminatedWithUncaughtException.java --- a/java/runjava/src/main/java/io/osv/AppThreadTerminatedWithUncaughtException.java +++ b/java/runjava/src/main/java/io/osv/AppThreadTerminatedWithUncaughtException.java
@@ -0,0 +1,13 @@
+package io.osv;
+
+/*
+ * Copyright (C) 2016 Waldemar Kozaczuk
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+public class AppThreadTerminatedWithUncaughtException extends Exception {
+    public AppThreadTerminatedWithUncaughtException(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/runjava/src/main/java/io/osv/Jvm.java b/java/runjava/src/main/java/io/osv/Jvm.java
--- a/java/runjava/src/main/java/io/osv/Jvm.java
+++ b/java/runjava/src/main/java/io/osv/Jvm.java
@@ -1,13 +1,8 @@
 package io.osv;

-import io.osv.jul.IsolatingLogManager;
-import net.sf.cglib.proxy.Dispatcher;
-import net.sf.cglib.proxy.Enhancer;
-
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FilePermission;
-import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.MalformedURLException;
@@ -20,138 +15,19 @@
 import java.util.Properties;
 import java.util.jar.JarFile;
 import java.util.jar.Manifest;
-import java.util.logging.LogManager;
 import java.util.zip.ZipException;

 /*
+ * Copyright (C) 2016 Waldemar Kozaczuk
  * Copyright (C) 2014 Cloudius Systems, Ltd.
  *
  * This work is open source software, licensed under the terms of the
  * BSD license as described in the LICENSE file in the top-level directory.
  */
-public class ContextIsolator {
-    private static final ContextIsolator instance = new ContextIsolator();
-
-    static {
-        verifyLogManagerIsInstalled();
-    }
-
-    private final Context masterContext;
-    private final Properties commonSystemProperties;
-
-    private static void verifyLogManagerIsInstalled() {
-        LogManager manager = LogManager.getLogManager();
-        if (!(manager instanceof IsolatingLogManager)) {
- throw new AssertionError("For isolation to work logging manager must be " - + IsolatingLogManager.class.getName() + " but is: " + manager.getClass().getName());
-        }
-    }
-
- private final InheritableThreadLocal<Context> currentContext = new InheritableThreadLocal<Context>() {
-        @Override
-        protected Context initialValue() {
-            return masterContext;
-        }
-    };
-
-    private final ClassLoader parentClassLoaderForIsolates;
-
-    public static ContextIsolator getInstance() {
-        return instance;
-    }
-
-    public ContextIsolator() {
- ClassLoader originalSystemClassLoader = getOsvClassLoader().getParent();
-        commonSystemProperties = copyOf(System.getProperties());
- masterContext = new Context(originalSystemClassLoader, copyOf(commonSystemProperties));
-
-        parentClassLoaderForIsolates = originalSystemClassLoader;
-
-        installSystemPropertiesProxy();
-    }
-
-    private Properties copyOf(Properties properties) {
-        Properties result = new Properties();
-        result.putAll(properties);
-        return result;
-    }
-
-    private static void installSystemPropertiesProxy() {
-        Enhancer enhancer = new Enhancer();
-        enhancer.setSuperclass(Properties.class);
-        enhancer.setCallback(new Dispatcher() {
-            @Override
-            public Object loadObject() throws Exception {
-                return instance.getContext().getProperties();
-            }
-        });
-        Properties contextAwareProperties = (Properties) enhancer.create();
-
-        try {
-            Field props = System.class.getDeclaredField("props");
-            props.setAccessible(true);
-            props.set(System.class, contextAwareProperties);
-        } catch (NoSuchFieldException | IllegalAccessException e) {
-            throw new AssertionError("Unable to override System.props", e);
-        }
-    }
-
-    public Context getContext() {
-        return currentContext.get();
-    }
-
- private Context run(ClassLoader classLoader, final String classpath, final String mainClass,
-                        final String[] args, final Properties properties) {
-        Properties contextProperties = new Properties();
-        contextProperties.putAll(commonSystemProperties);
-        contextProperties.putAll(properties);
-
- final Context context = new Context(classLoader, contextProperties);
+public abstract class Jvm<T> {
+    public abstract void runSync(String... args) throws Throwable;

-        Thread thread = new Thread() {
-            @Override
-            public void run() {
-                currentContext.set(context);
-                context.setProperty("java.class.path", classpath);
-
-                try {
-                    runMain(loadClass(mainClass), args);
-                } catch (InterruptedException e) {
-                    Thread.currentThread().interrupt();
-                } catch (MainClassNotFoundException e) {
-                    context.setException(e);
-                } catch (Throwable e) {
- getUncaughtExceptionHandler().uncaughtException(this, e);
-                }
-            }
-        };
-
-        context.setMainThread(thread);
- thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
-            @Override
-            public void uncaughtException(Thread t, Throwable e) {
-                context.setException(e);
-            }
-        });
-        thread.setContextClassLoader(classLoader);
-        thread.start();
-        return context;
-    }
-
-    public void runSync(String... args) throws Throwable {
-        Context context = run(args);
-
-        while (true) {
-            try {
-                context.join();
-                return;
-            } catch (InterruptedException e) {
-                context.interrupt();
-            }
-        }
-    }
-
-    public Context run(String... args) throws Throwable {
+    public T run(String... args) throws Throwable {
         Properties properties = new Properties();

         ArrayList<String> classpath = new ArrayList<>();
@@ -189,7 +65,7 @@ public Context run(String... args) throws Throwable {
throw new IllegalArgumentException("No jar or class specified to run.");
     }

- private Context runJar(String jarName, String[] args, ArrayList<String> classpath, Properties properties) throws Throwable { + private T runJar(String jarName, String[] args, ArrayList<String> classpath, Properties properties) throws Throwable {
         File jarFile = new File(jarName);
         try {
             JarFile jar = new JarFile(jarFile);
@@ -208,26 +84,31 @@ private Context runJar(String jarName, String[] args, ArrayList<String> classpat
         }
     }

- private Context runClass(String mainClass, String[] args, Iterable<String> classpath, Properties properties) throws MalformedURLException { - ClassLoader appClassLoader = getClassLoader(classpath, parentClassLoaderForIsolates); + private T runClass(String mainClass, String[] args, Iterable<String> classpath, Properties properties) throws MalformedURLException { + ClassLoader appClassLoader = createAppClassLoader(classpath, getParentClassLoader()); return run(appClassLoader, joinClassPath(classpath), mainClass, args, properties);
     }

- private static ClassLoader getClassLoader(Iterable<String> classpath, ClassLoader parent) throws MalformedURLException { + protected abstract T run(ClassLoader classLoader, final String classpath, final String mainClass,
+                final String[] args, final Properties properties);
+
+    protected abstract ClassLoader getParentClassLoader();
+
+ private ClassLoader createAppClassLoader(Iterable<String> classpath, ClassLoader parent) throws MalformedURLException {
         List<URL> urls = toUrls(classpath);
         URL[] urlArray = urls.toArray(new URL[urls.size()]);
         return new AppClassLoader(urlArray, parent);
     }

- private static List<URL> toUrls(Iterable<String> classpath) throws MalformedURLException { + private List<URL> toUrls(Iterable<String> classpath) throws MalformedURLException {
         ArrayList<URL> urls = new ArrayList<>();
         for (String path : classpath) {
             urls.add(toUrl(path));
         }
         return urls;
     }

- private static void runMain(Class<?> klass, String[] args) throws Throwable { + protected void runMain(Class<?> klass, String[] args) throws Throwable {
         Method main = klass.getMethod("main", String[].class);
         try {
             main.invoke(null, new Object[]{args});
@@ -236,18 +117,15 @@ private static void runMain(Class<?> klass, String[] args) throws Throwable {
         }
     }

-    private static OsvSystemClassLoader getOsvClassLoader() {
-        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
-        if (!(systemClassLoader instanceof OsvSystemClassLoader)) {
- throw new AssertionError("System class loader should be an instance of "
-                    + OsvSystemClassLoader.class.getName() + " but is "
-                    + systemClassLoader.getClass().getName());
+ protected Class<?> loadClass(String name) throws MainClassNotFoundException {
+        try {
+ return Thread.currentThread().getContextClassLoader().loadClass(name);
+        } catch (ClassNotFoundException ex) {
+            throw new MainClassNotFoundException(name);
         }
-
-        return (OsvSystemClassLoader) systemClassLoader;
     }

-    private static String joinClassPath(Iterable<String> classpath) {
+    private String joinClassPath(Iterable<String> classpath) {
         StringBuilder sb = new StringBuilder();
         boolean first = true;
         for (String path : classpath) {
@@ -260,29 +138,21 @@ private static String joinClassPath(Iterable<String> classpath) {
         return sb.toString();
     }

-    private static URL toUrl(String path) throws MalformedURLException {
+    private URL toUrl(String path) throws MalformedURLException {
         return new URL("file:///" + path + (isDirectory(path) ? "/" : ""));
     }

-    private static boolean isDirectory(String path) {
+    private boolean isDirectory(String path) {
         return new File(path).isDirectory();
     }

- private static Class<?> loadClass(String name) throws MainClassNotFoundException {
-        try {
- return Thread.currentThread().getContextClassLoader().loadClass(name);
-        } catch (ClassNotFoundException ex) {
-            throw new MainClassNotFoundException(name);
-        }
-    }
-
     // Expand classpath, as given in the "-classpath" option, to a list of
     // jars or directories. As in the traditional "java" command-line
     // launcher, components of the class path are separated by ":", and
     // we also support the traditional (but awkward) Java wildcard syntax,
     // where "dir/*" adds to the classpath all jar files in the given
     // directory.
-    private static Iterable<String> expandClassPath(String classpath) {
+    private Iterable<String> expandClassPath(String classpath) {
         ArrayList<String> ret = new ArrayList<>();
         for (String component : classpath.split(":")) {
             if (component.endsWith("/*")) {
@@ -307,10 +177,6 @@ private static boolean isDirectory(String path) {
         return ret;
     }

-    public Object receive() throws InterruptedException {
-        return getContext().takeMessage();
-    }
-
     private static class AppClassLoader extends URLClassLoader {
         public AppClassLoader(URL[] urlArray, ClassLoader parent) {
             super(urlArray, parent);
@@ -324,5 +190,4 @@ protected PermissionCollection getPermissions(CodeSource codesource) {
             return permissions;
         }
     }
-
 }
diff --git a/java/runjava/src/main/java/io/osv/RunJava.java b/java/runjava/src/main/java/io/osv/RunJava.java
--- a/java/runjava/src/main/java/io/osv/RunJava.java
+++ b/java/runjava/src/main/java/io/osv/RunJava.java
@@ -1,48 +0,0 @@
-package io.osv;
-
-/*
- * Copyright (C) 2013-2014 Cloudius Systems, Ltd.
- *
- * This work is open source software, licensed under the terms of the
- * BSD license as described in the LICENSE file in the top-level directory.
- */
-
-public class RunJava {
-       private static native void onVMStop();
-
-       static {
-               Runtime.getRuntime().addShutdownHook(new Thread() {
-                       public void run() {
-                               onVMStop();
-                       }
-               });
-       }
-
-    public static void main(String[] args) {
-        if (args.length > 0 && args[0].equals("-version")) {
-            System.err.println("java version \"" +
-                    System.getProperty("java.version") + "\"");
-            System.err.println(System.getProperty("java.runtime.name") +
-                    " (" + System.getProperty("java.runtime.version") +
-                    ")");
-            System.err.println(System.getProperty("java.vm.name") +
-                    " (build " + System.getProperty("java.vm.version") +
-                    ", " + System.getProperty("java.vm.info") + ")");
-            return;
-        }
-
-        try {
-            ContextIsolator.getInstance().runSync(args);
-        } catch (IllegalArgumentException ex) {
-            System.err.println("RunJava: " + ex.getMessage());
-        } catch (ContextFailedException ex) {
-            if (ex.getCause() instanceof MainClassNotFoundException) {
- System.err.println("Error: Could not find or load main class " + ((MainClassNotFoundException) ex.getCause()).getClassName());
-            } else {
-                ex.printStackTrace();
-            }
-        } catch (Throwable ex) {
-            ex.printStackTrace();
-        }
-    }
-}
diff --git a/java/runjava/src/main/java/io/osv/RunJvmAppHelper.java b/java/runjava/src/main/java/io/osv/RunJvmAppHelper.java
--- a/java/runjava/src/main/java/io/osv/RunJvmAppHelper.java
+++ b/java/runjava/src/main/java/io/osv/RunJvmAppHelper.java
@@ -0,0 +1,44 @@
+package io.osv;
+
+/*
+ * Copyright (C) 2016 Waldemar Kozaczuk
+ * Copyright (C) 2013-2016 Cloudius Systems, Ltd.
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+public class RunJvmAppHelper {
+
+   public interface JvmFactory {
+       Jvm getJvm();
+   }
+
+   static public void runSync(JvmFactory jvmFactory, String[] args) {
+
+       if (args.length > 0 && args[0].equals("-version")) {
+           System.err.println("java version \"" +
+                   System.getProperty("java.version") + "\"");
+           System.err.println(System.getProperty("java.runtime.name") +
+                   " (" + System.getProperty("java.runtime.version") +
+                   ")");
+           System.err.println(System.getProperty("java.vm.name") +
+                   " (build " + System.getProperty("java.vm.version") +
+                   ", " + System.getProperty("java.vm.info") + ")");
+           return;
+       }
+
+       try {
+           jvmFactory.getJvm().runSync(args);
+       } catch (IllegalArgumentException ex) {
+           System.err.println("RunJava: " + ex.getMessage());
+       } catch (AppThreadTerminatedWithUncaughtException ex) {
+           if (ex.getCause() instanceof MainClassNotFoundException) {
+ System.err.println("Error: Could not find or load main class " + ((MainClassNotFoundException) ex.getCause()).getClassName());
+           } else {
+               ex.printStackTrace();
+           }
+       } catch (Throwable ex) {
+           ex.printStackTrace();
+       }
+   }
+}
diff --git a/java/runjava/src/main/java/io/osv/isolated/Context.java b/java/runjava/src/main/java/io/osv/isolated/Context.java
--- a/java/runjava/src/main/java/io/osv/isolated/Context.java
+++ b/java/runjava/src/main/java/io/osv/isolated/Context.java
@@ -1,4 +1,4 @@
-package io.osv;
+package io.osv.isolated;

 import io.osv.jul.LogManagerWrapper;
 import io.osv.util.LazilyInitialized;
diff --git a/java/runjava/src/main/java/io/osv/isolated/ContextFailedException.java b/java/runjava/src/main/java/io/osv/isolated/ContextFailedException.java
--- a/java/runjava/src/main/java/io/osv/isolated/ContextFailedException.java
+++ b/java/runjava/src/main/java/io/osv/isolated/ContextFailedException.java
@@ -1,12 +1,14 @@
-package io.osv;
+package io.osv.isolated;
+
+import io.osv.AppThreadTerminatedWithUncaughtException;

 /*
  * Copyright (C) 2014 Cloudius Systems, Ltd.
  *
  * This work is open source software, licensed under the terms of the
  * BSD license as described in the LICENSE file in the top-level directory.
  */
-public class ContextFailedException extends Exception {
+public class ContextFailedException extends AppThreadTerminatedWithUncaughtException {
     public ContextFailedException(Throwable cause) {
         super(cause);
     }
diff --git a/java/runjava/src/main/java/io/osv/isolated/IsolatedJvm.java b/java/runjava/src/main/java/io/osv/isolated/IsolatedJvm.java
--- a/java/runjava/src/main/java/io/osv/isolated/IsolatedJvm.java
+++ b/java/runjava/src/main/java/io/osv/isolated/IsolatedJvm.java
@@ -0,0 +1,160 @@
+package io.osv.isolated;
+
+import io.osv.MainClassNotFoundException;
+import io.osv.Jvm;
+import io.osv.jul.IsolatingLogManager;
+import net.sf.cglib.proxy.Dispatcher;
+import net.sf.cglib.proxy.Enhancer;
+
+import java.lang.reflect.Field;
+import java.util.Properties;
+import java.util.logging.LogManager;
+
+/*
+ * Copyright (C) 2016 Waldemar Kozaczuk
+ * Copyright (C) 2014 Cloudius Systems, Ltd.
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+public class IsolatedJvm extends Jvm<Context> {
+    private static final IsolatedJvm instance = new IsolatedJvm();
+
+    static {
+        verifyLogManagerIsInstalled();
+    }
+
+    private final Context masterContext;
+    private final Properties commonSystemProperties;
+
+    private static void verifyLogManagerIsInstalled() {
+        LogManager manager = LogManager.getLogManager();
+        if (!(manager instanceof IsolatingLogManager)) {
+ throw new AssertionError("For isolation to work logging manager must be " + + IsolatingLogManager.class.getName() + " but is: " + manager.getClass().getName());
+        }
+    }
+
+ private final InheritableThreadLocal<Context> currentContext = new InheritableThreadLocal<Context>() {
+        @Override
+        protected Context initialValue() {
+            return masterContext;
+        }
+    };
+
+    private final ClassLoader parentClassLoaderForIsolates;
+
+    public static IsolatedJvm getInstance() {
+        return instance;
+    }
+
+    private IsolatedJvm() {
+ ClassLoader originalSystemClassLoader = getOsvClassLoader().getParent();
+        commonSystemProperties = copyOf(System.getProperties());
+ masterContext = new Context(originalSystemClassLoader, copyOf(commonSystemProperties));
+
+        parentClassLoaderForIsolates = originalSystemClassLoader;
+
+        installSystemPropertiesProxy();
+    }
+
+    private Properties copyOf(Properties properties) {
+        Properties result = new Properties();
+        result.putAll(properties);
+        return result;
+    }
+
+    private void installSystemPropertiesProxy() {
+        Enhancer enhancer = new Enhancer();
+        enhancer.setSuperclass(Properties.class);
+        enhancer.setCallback(new Dispatcher() {
+            @Override
+            public Object loadObject() throws Exception {
+                return instance.getContext().getProperties();
+            }
+        });
+        Properties contextAwareProperties = (Properties) enhancer.create();
+
+        try {
+            Field props = System.class.getDeclaredField("props");
+            props.setAccessible(true);
+            props.set(System.class, contextAwareProperties);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            throw new AssertionError("Unable to override System.props", e);
+        }
+    }
+
+    public Context getContext() {
+        return currentContext.get();
+    }
+
+ protected Context run(ClassLoader classLoader, final String classpath, final String mainClass,
+                        final String[] args, final Properties properties) {
+        Properties contextProperties = new Properties();
+        contextProperties.putAll(commonSystemProperties);
+        contextProperties.putAll(properties);
+
+ final Context context = new Context(classLoader, contextProperties);
+
+        Thread thread = new Thread() {
+            @Override
+            public void run() {
+                currentContext.set(context);
+                context.setProperty("java.class.path", classpath);
+
+                try {
+                    runMain(loadClass(mainClass), args);
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                } catch (MainClassNotFoundException e) {
+                    context.setException(e);
+                } catch (Throwable e) {
+ getUncaughtExceptionHandler().uncaughtException(this, e);
+                }
+            }
+        };
+
+        context.setMainThread(thread);
+ thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+            @Override
+            public void uncaughtException(Thread t, Throwable e) {
+                context.setException(e);
+            }
+        });
+        thread.setContextClassLoader(classLoader);
+        thread.start();
+        return context;
+    }
+
+    protected ClassLoader getParentClassLoader() {
+        return parentClassLoaderForIsolates;
+    }
+
+    public void runSync(String... args) throws Throwable {
+        Context context = run(args);
+
+        while (true) {
+            try {
+                context.join();
+                return;
+            } catch (InterruptedException e) {
+                context.interrupt();
+            }
+        }
+    }
+
+    private OsvSystemClassLoader getOsvClassLoader() {
+        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
+        if (!(systemClassLoader instanceof OsvSystemClassLoader)) {
+ throw new AssertionError("System class loader should be an instance of "
+                    + OsvSystemClassLoader.class.getName() + " but is "
+                    + systemClassLoader.getClass().getName());
+        }
+
+        return (OsvSystemClassLoader) systemClassLoader;
+    }
+
+    public Object receive() throws InterruptedException {
+        return getContext().takeMessage();
+    }
+}
diff --git a/java/runjava/src/main/java/io/osv/isolated/MultiJarLoader.java b/java/runjava/src/main/java/io/osv/isolated/MultiJarLoader.java
--- a/java/runjava/src/main/java/io/osv/isolated/MultiJarLoader.java
+++ b/java/runjava/src/main/java/io/osv/isolated/MultiJarLoader.java
@@ -1,4 +1,4 @@
-package io.osv;
+package io.osv.isolated;

 import java.io.BufferedReader;
 import java.io.File;
@@ -110,7 +110,7 @@ public RunOnThread(String args) {
         @Override
         public void run() {
             try {
-                ContextIsolator.getInstance().runSync(args.split("\\s+"));
+                IsolatedJvm.getInstance().runSync(args.split("\\s+"));
             } catch (Throwable e) {
System.err.println("Exception was caught while running " + args
                         + " exception: " + e);
diff --git a/java/runjava/src/main/java/io/osv/isolated/OsvSystemClassLoader.java b/java/runjava/src/main/java/io/osv/isolated/OsvSystemClassLoader.java
--- a/java/runjava/src/main/java/io/osv/isolated/OsvSystemClassLoader.java
+++ b/java/runjava/src/main/java/io/osv/isolated/OsvSystemClassLoader.java
@@ -1,4 +1,4 @@
-package io.osv;
+package io.osv.isolated;

 /*
  * Copyright (C) 2013 Cloudius Systems, Ltd.
@@ -54,7 +54,7 @@ private Method getProtectedMethod(String name, Class<?>... parameters) throws No
     }

     private Context getContext() {
-        return ContextIsolator.getInstance().getContext();
+        return IsolatedJvm.getInstance().getContext();
     }

     private ClassLoader getDelegate() {
diff --git a/java/runjava/src/main/java/io/osv/isolated/RunIsolatedJvmApp.java b/java/runjava/src/main/java/io/osv/isolated/RunIsolatedJvmApp.java
--- a/java/runjava/src/main/java/io/osv/isolated/RunIsolatedJvmApp.java
+++ b/java/runjava/src/main/java/io/osv/isolated/RunIsolatedJvmApp.java
@@ -0,0 +1,33 @@
+package io.osv.isolated;
+
+/*
+ * Copyright (C) 2016 Waldemar Kozaczuk
+ * Copyright (C) 2013-2014 Cloudius Systems, Ltd.
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+import io.osv.Jvm;
+
+import static io.osv.RunJvmAppHelper.runSync;
+import static io.osv.RunJvmAppHelper.JvmFactory;
+
+public class RunIsolatedJvmApp {
+       private static native void onVMStop();
+
+       static {
+               Runtime.getRuntime().addShutdownHook(new Thread() {
+                       public void run() {
+                               onVMStop();
+                       }
+               });
+       }
+
+    public static void main(String[] args) {
+        runSync(new JvmFactory() {
+            public Jvm getJvm() {
+                return IsolatedJvm.getInstance();
+            }
+        },args);
+    }
+}
diff --git a/java/runjava/src/main/java/io/osv/jul/IsolatingLogManager.java b/java/runjava/src/main/java/io/osv/jul/IsolatingLogManager.java
--- a/java/runjava/src/main/java/io/osv/jul/IsolatingLogManager.java
+++ b/java/runjava/src/main/java/io/osv/jul/IsolatingLogManager.java
@@ -1,7 +1,7 @@
 package io.osv.jul;

-import io.osv.Context;
-import io.osv.ContextIsolator;
+import io.osv.isolated.Context;
+import io.osv.isolated.IsolatedJvm;

 import java.beans.PropertyChangeListener;
 import java.io.IOException;
@@ -19,7 +19,7 @@
 @SuppressWarnings("UnusedDeclaration")
 public class IsolatingLogManager extends LogManager {
     private LogManager getDelegate() {
-        Context context = ContextIsolator.getInstance().getContext();
+        Context context = IsolatedJvm.getInstance().getContext();
         return context.getLogManagerWrapper().getManager();
     }

diff --git a/java/runjava/src/main/java/io/osv/jul/LogManagerWrapper.java b/java/runjava/src/main/java/io/osv/jul/LogManagerWrapper.java
--- a/java/runjava/src/main/java/io/osv/jul/LogManagerWrapper.java
+++ b/java/runjava/src/main/java/io/osv/jul/LogManagerWrapper.java
@@ -1,6 +1,6 @@
 package io.osv.jul;

-import io.osv.Context;
+import io.osv.isolated.Context;
 import io.osv.util.LazilyInitialized;
 import net.sf.cglib.proxy.Enhancer;
 import net.sf.cglib.proxy.MethodInterceptor;
diff --git a/java/runjava/src/main/java/io/osv/nonisolated/NonIsolatedJvm.java b/java/runjava/src/main/java/io/osv/nonisolated/NonIsolatedJvm.java
--- a/java/runjava/src/main/java/io/osv/nonisolated/NonIsolatedJvm.java
+++ b/java/runjava/src/main/java/io/osv/nonisolated/NonIsolatedJvm.java
@@ -0,0 +1,86 @@
+package io.osv.nonisolated;
+
+import io.osv.AppThreadTerminatedWithUncaughtException;
+import io.osv.Jvm;
+import io.osv.MainClassNotFoundException;
+
+import java.util.Properties;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+/*
+ * Copyright (C) 2016 Waldemar Kozaczuk
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+public class NonIsolatedJvm extends Jvm<Thread> {
+
+    private static final NonIsolatedJvm instance = new NonIsolatedJvm();
+
+ private AtomicReference<Throwable> thrownException = new AtomicReference<>();
+
+    public static NonIsolatedJvm getInstance() {
+        return instance;
+    }
+
+    private NonIsolatedJvm() {}
+
+    @Override
+ protected Thread run(ClassLoader classLoader, final String classpath, final String mainClass, final String[] args, final Properties properties) {
+        thrownException.set(null);
+        Thread thread = new Thread() {
+            @Override
+            public void run() {
+            System.setProperty("java.class.path", classpath);
+
+            for(Map.Entry<?,?> property : properties.entrySet())
+ System.setProperty(property.getKey().toString(),property.getValue().toString()); //TODO Check for null
+
+            try {
+                runMain(loadClass(mainClass), args);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+            } catch (MainClassNotFoundException e) {
+                thrownException.set(e);
+            } catch (Throwable e) {
+                getUncaughtExceptionHandler().uncaughtException(this, e);
+            }
+            }
+        };
+
+ thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+            @Override
+            public void uncaughtException(Thread t, Throwable e) {
+                thrownException.set(e);
+            }
+        });
+        thread.setContextClassLoader(classLoader);
+        thread.start();
+        return thread;
+    }
+
+    public void runSync(String... args) throws Throwable {
+        Thread thread = run(args);
+
+        while (true) {
+            try {
+                thread.join();
+                final Throwable exception = thrownException.get();
+                if (null != exception) {
+ throw new AppThreadTerminatedWithUncaughtException(exception);
+                }
+                return;
+            } catch (InterruptedException e) {
+                thread.interrupt();
+            }
+        }
+    }
+
+    @Override
+    protected ClassLoader getParentClassLoader() {
+        return Thread.currentThread().getContextClassLoader();
+    }
+
+ public Throwable getThrownExceptionIfAny() { return thrownException.get(); }
+}
diff --git a/java/runjava/src/main/java/io/osv/nonisolated/RunNonIsolatedJvmApp.java b/java/runjava/src/main/java/io/osv/nonisolated/RunNonIsolatedJvmApp.java --- a/java/runjava/src/main/java/io/osv/nonisolated/RunNonIsolatedJvmApp.java +++ b/java/runjava/src/main/java/io/osv/nonisolated/RunNonIsolatedJvmApp.java
@@ -0,0 +1,33 @@
+package io.osv.nonisolated;
+
+/*
+ * Copyright (C) 2016 Waldemar Kozaczuk
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+
+import io.osv.Jvm;
+
+import static io.osv.RunJvmAppHelper.runSync;
+import static io.osv.RunJvmAppHelper.JvmFactory;
+
+public class RunNonIsolatedJvmApp {
+       private static native void onVMStop();
+
+       static {
+               Runtime.getRuntime().addShutdownHook(new Thread() {
+                       public void run() {
+                               onVMStop();
+                       }
+               });
+       }
+
+    public static void main(String[] args) {
+        runSync(new JvmFactory() {
+            public Jvm getJvm() {
+                return NonIsolatedJvm.getInstance();
+            }
+        },args);
+    }
+}
diff --git a/java/tests-isolates/src/main/java/tests/LoggingProcess.java b/java/tests-isolates/src/main/java/tests/LoggingProcess.java
--- a/java/tests-isolates/src/main/java/tests/LoggingProcess.java
+++ b/java/tests-isolates/src/main/java/tests/LoggingProcess.java
@@ -1,6 +1,6 @@
 package tests;

-import io.osv.ContextIsolator;
+import io.osv.isolated.IsolatedJvm;

 import java.util.concurrent.CyclicBarrier;
 import java.util.logging.FileHandler;
@@ -16,7 +16,7 @@
  */
 public class LoggingProcess {
     public static void main(String[] args) throws Throwable {
- CyclicBarrier barrier = (CyclicBarrier) ContextIsolator.getInstance().receive(); + CyclicBarrier barrier = (CyclicBarrier) IsolatedJvm.getInstance().receive();

         String logFileName = args[0];
         String loggerName = args[1];
diff --git a/java/tests-isolates/src/main/java/tests/NonIsolatedLoggingProcess.java b/java/tests-isolates/src/main/java/tests/NonIsolatedLoggingProcess.java
--- a/java/tests-isolates/src/main/java/tests/NonIsolatedLoggingProcess.java
+++ b/java/tests-isolates/src/main/java/tests/NonIsolatedLoggingProcess.java
@@ -0,0 +1,32 @@
+package tests;
+
+import java.util.logging.FileHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.logging.SimpleFormatter;
+
+/*
+ * Copyright (C) 2016 Waldemar Kozaczuk
+ * Copyright (C) 2014 Cloudius Systems, Ltd.
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+public class NonIsolatedLoggingProcess {
+    public static void main(String[] args) throws Throwable {
+        String logFileName = args[0];
+        String loggerName = args[1];
+        Level level = Level.parse(args[2]);
+        String message = args[3];
+
+        FileHandler handler = new FileHandler(logFileName);
+        handler.setFormatter(new SimpleFormatter());
+        Logger logger = Logger.getLogger(loggerName);
+        logger.addHandler(handler);
+
+        logger.setLevel(level);
+
+        logger.info(message);
+        logger.warning(message);
+    }
+}
diff --git a/java/tests-isolates/src/main/java/tests/PropertyReader.java b/java/tests-isolates/src/main/java/tests/PropertyReader.java
--- a/java/tests-isolates/src/main/java/tests/PropertyReader.java
+++ b/java/tests-isolates/src/main/java/tests/PropertyReader.java
@@ -1,6 +1,6 @@
 package tests;

-import io.osv.ContextIsolator;
+import io.osv.isolated.IsolatedJvm;

 import java.util.concurrent.CyclicBarrier;

@@ -17,7 +17,7 @@ public static void main(String[] args) throws Exception {
         String property = args[0];
         String expectedValue = args[1];

- CyclicBarrier barrier = (CyclicBarrier) ContextIsolator.getInstance().receive(); + CyclicBarrier barrier = (CyclicBarrier) IsolatedJvm.getInstance().receive();
         barrier.await();

         assertEquals(expectedValue, System.getProperty(property));
diff --git a/java/tests-isolates/src/main/java/tests/PropertySetter.java b/java/tests-isolates/src/main/java/tests/PropertySetter.java
--- a/java/tests-isolates/src/main/java/tests/PropertySetter.java
+++ b/java/tests-isolates/src/main/java/tests/PropertySetter.java
@@ -1,6 +1,6 @@
 package tests;

-import io.osv.ContextIsolator;
+import io.osv.isolated.IsolatedJvm;

 import java.util.concurrent.CyclicBarrier;

@@ -14,7 +14,7 @@
  */
 public class PropertySetter {
     public static void main(String[] args) throws Exception {
- CyclicBarrier barrier = (CyclicBarrier) ContextIsolator.getInstance().receive(); + CyclicBarrier barrier = (CyclicBarrier) IsolatedJvm.getInstance().receive();
         String property = args[0];
         String value = args[1];

diff --git a/java/tests-isolates/src/main/java/tests/StaticFieldSetter.java b/java/tests-isolates/src/main/java/tests/StaticFieldSetter.java
--- a/java/tests-isolates/src/main/java/tests/StaticFieldSetter.java
+++ b/java/tests-isolates/src/main/java/tests/StaticFieldSetter.java
@@ -1,6 +1,6 @@
 package tests;

-import io.osv.ContextIsolator;
+import io.osv.isolated.IsolatedJvm;

 import java.util.concurrent.BrokenBarrierException;
 import java.util.concurrent.CyclicBarrier;
@@ -26,7 +26,7 @@ public static void main(String[] args) {

     public static class Party {
public static void main(String[] args) throws InterruptedException, BrokenBarrierException { - CyclicBarrier barrier = (CyclicBarrier) ContextIsolator.getInstance().receive(); + CyclicBarrier barrier = (CyclicBarrier) IsolatedJvm.getInstance().receive();

             String value = args[0];
             staticField = value;
diff --git a/java/tests/src/main/java/io/osv/AllTestsThatTestIsolatedApp.java b/java/tests/src/main/java/io/osv/AllTestsThatTestIsolatedApp.java
--- a/java/tests/src/main/java/io/osv/AllTestsThatTestIsolatedApp.java
+++ b/java/tests/src/main/java/io/osv/AllTestsThatTestIsolatedApp.java
@@ -17,5 +17,5 @@
         PropertyIsolationTest.class,
         OsvApiTest.class
 })
-public class AllTests {
+public class AllTestsThatTestIsolatedApp {
 }
diff --git a/java/tests/src/main/java/io/osv/AllTestsThatTestNonIsolatedApp.java b/java/tests/src/main/java/io/osv/AllTestsThatTestNonIsolatedApp.java
--- a/java/tests/src/main/java/io/osv/AllTestsThatTestNonIsolatedApp.java
+++ b/java/tests/src/main/java/io/osv/AllTestsThatTestNonIsolatedApp.java
@@ -0,0 +1,20 @@
+package io.osv;
+
+/*
+ * Copyright (C) 2016 Waldemar Kozaczuk
+ * Copyright (C) 2014 Cloudius Systems, Ltd.
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+        LoggingWithoutIsolationTest.class,
+        ClassLoaderWithoutIsolationTest.class,
+        OsvApiTest.class
+})
+public class AllTestsThatTestNonIsolatedApp {
+}
diff --git a/java/tests/src/main/java/io/osv/ClassLoaderIsolationTest.java b/java/tests/src/main/java/io/osv/ClassLoaderIsolationTest.java
--- a/java/tests/src/main/java/io/osv/ClassLoaderIsolationTest.java
+++ b/java/tests/src/main/java/io/osv/ClassLoaderIsolationTest.java
@@ -5,7 +5,10 @@

 import java.util.concurrent.CyclicBarrier;

-import static io.osv.TestIsolateLaunching.runIsolate;
+import io.osv.isolated.Context;
+import io.osv.isolated.ContextFailedException;
+
+import static io.osv.TestLaunching.runIsolate;
 import static org.junit.Assert.*;

 /*
diff --git a/java/tests/src/main/java/io/osv/ClassLoaderWithoutIsolationTest.java b/java/tests/src/main/java/io/osv/ClassLoaderWithoutIsolationTest.java
--- a/java/tests/src/main/java/io/osv/ClassLoaderWithoutIsolationTest.java
+++ b/java/tests/src/main/java/io/osv/ClassLoaderWithoutIsolationTest.java
@@ -0,0 +1,89 @@
+package io.osv;
+
+import io.osv.nonisolated.NonIsolatedJvm;
+import org.junit.Test;
+import tests.*;
+
+import static io.osv.TestLaunching.runWithoutIsolation;
+import static org.junit.Assert.*;
+
+/*
+ * Copyright (C) 2016 Waldemar Kozaczuk
+ * Copyright (C) 2014 Cloudius Systems, Ltd.
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+public class ClassLoaderWithoutIsolationTest {
+ private static final Class<?> THIS_CLASS = ClassLoaderWithoutIsolationTest.class;
+
+    @Test
+ public void testParentContextSeesModificationsOfStaticFields() throws Throwable { + Thread thread = runWithoutIsolation(StaticFieldSetter.class); // This is where the class is loaded and available to child one
+        thread.join();
+
+        //
+ // Rethrow any exception that may have been raised and led to the thread terminating + final Throwable exception = NonIsolatedJvm.getInstance().getThrownExceptionIfAny();
+        if( null != exception)
+            throw exception;
+        //
+ // There is one class instance of StaticFieldSetter loaded as there is no isolation + // between the parent app classloader (at the tests runner level) and the child app + // classloader level which is created when runWithoutIsolation is called + assertEquals(StaticFieldSetter.NEW_VALUE, StaticFieldSetter.staticField);
+    }
+
+    @Test
+ public void testChildSeesSameVersionOfAClassDefinedInParentContext() throws Throwable {
+        String fieldName = "field_existing_only_in_isolate_context";
+
+        try {
+            ClassPresentInBothContexts.class.getDeclaredField(fieldName);
+ throw new AssertionError("The field should be absent in parent context");
+        } catch (NoSuchFieldException e) {
+            // expected
+        }
+
+ Thread thread = runWithoutIsolation(FieldTester.class, ClassPresentInBothContexts.class.getName(), fieldName);
+        thread.join();
+        //
+ // Rethrow any exception that may have been raised and led to the thread terminating + final Throwable exception = NonIsolatedJvm.getInstance().getThrownExceptionIfAny(); + if( null != exception && exception instanceof NoSuchFieldException) { + // It is what is expected as there is no isolation between child and parent classloader the class loaded + // by parent classloader from tests.jar which is a first jar in the classpath
+        }
+        else if( null != exception) {
+            throw exception;
+        }
+        else {
+ throw new AssertionError("The field should be also absent in child context");
+        }
+    }
+
+    @Test
+ public void testClassesDefinedInParentContextAreVisibleToChild() throws Throwable { + Thread thread = runWithoutIsolation(ClassFinder.class, ClassPresentOnlyInParentContext.class.getName());
+        thread.join();
+        //
+ // Rethrow any exception that may have been raised and led to the thread terminating + final Throwable exception = NonIsolatedJvm.getInstance().getThrownExceptionIfAny();
+        if( null != exception)
+            throw exception;
+        //
+ // As there is no isolation between child and parent classloader the class loaded + // by parent classloader ClassPresentOnlyInParentContext from tests.jar will
+        // actually be visible in the children
+    }
+
+    @Test
+ public void testClassesFromExtensionDirectoryCanBeLoaded() throws Exception {
+        assertNotNull(SomeExtensionClass.class);
+    }
+
+    @Test
+ public void testClassPutInRootDirectoryIsNotPickedUpByDefaultSystemClassLoader() throws Exception { + assertSame(ClassPutInRoot.class.getClassLoader(), THIS_CLASS.getClassLoader());
+    }
+}
\ No newline at end of file
diff --git a/java/tests/src/main/java/io/osv/LoggingIsolationTest.java b/java/tests/src/main/java/io/osv/LoggingIsolationTest.java
--- a/java/tests/src/main/java/io/osv/LoggingIsolationTest.java
+++ b/java/tests/src/main/java/io/osv/LoggingIsolationTest.java
@@ -7,7 +7,9 @@
 import java.io.IOException;
 import java.util.concurrent.CyclicBarrier;

-import static io.osv.TestIsolateLaunching.runIsolate;
+import io.osv.isolated.Context;
+
+import static io.osv.TestLaunching.runIsolate;
 import static org.apache.commons.io.FileUtils.forceDeleteOnExit;
 import static org.apache.commons.io.FileUtils.readLines;
 import static org.fest.assertions.Assertions.assertThat;
diff --git a/java/tests/src/main/java/io/osv/LoggingWithoutIsolationTest.java b/java/tests/src/main/java/io/osv/LoggingWithoutIsolationTest.java
--- a/java/tests/src/main/java/io/osv/LoggingWithoutIsolationTest.java
+++ b/java/tests/src/main/java/io/osv/LoggingWithoutIsolationTest.java
@@ -0,0 +1,54 @@
+package io.osv;
+
+import io.osv.nonisolated.NonIsolatedJvm;
+import org.junit.Test;
+import tests.NonIsolatedLoggingProcess;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import static io.osv.TestLaunching.runWithoutIsolation;
+import static org.apache.commons.io.FileUtils.forceDeleteOnExit;
+import static org.apache.commons.io.FileUtils.readLines;
+import static org.fest.assertions.Assertions.assertThat;
+
+/*
+ * Copyright (C) 2016 Waldemar Kozaczuk
+ * Copyright (C) 2014 Cloudius Systems, Ltd.
+ *
+ * This work is open source software, licensed under the terms of the
+ * BSD license as described in the LICENSE file in the top-level directory.
+ */
+public class LoggingWithoutIsolationTest {
+    private static final String LOGGER_NAME = "test-logger";
+
+    @Test
+    public void testLogger() throws Throwable {
+        File log = newTemporaryFile();
+
+ Thread thread = runWithoutIsolation(NonIsolatedLoggingProcess.class, log.getAbsolutePath(), LOGGER_NAME, "INFO", "ctx");
+        thread.join();
+
+        //
+ // Rethrow any exception that may have been raised and led to the thread terminating + final Throwable exception = NonIsolatedJvm.getInstance().getThrownExceptionIfAny();
+        if( null != exception)
+            throw exception;
+
+        final List<String> logLines = readLines(log);
+        for( String line : logLines)
+            System.out.println(line);
+
+        assertThat(logLines)
+                .hasSize(4)
+                .contains("INFO: ctx")
+                .contains("WARNING: ctx");
+    }
+
+    private File newTemporaryFile() throws IOException {
+        File file = File.createTempFile("test", null);
+        forceDeleteOnExit(file);
+        return file;
+    }
+}
diff --git a/java/tests/src/main/java/io/osv/PropertyIsolationTest.java b/java/tests/src/main/java/io/osv/PropertyIsolationTest.java
--- a/java/tests/src/main/java/io/osv/PropertyIsolationTest.java
+++ b/java/tests/src/main/java/io/osv/PropertyIsolationTest.java
@@ -6,7 +6,9 @@

 import java.util.concurrent.CyclicBarrier;

-import static io.osv.TestIsolateLaunching.runIsolate;
+import io.osv.isolated.Context;
+
+import static io.osv.TestLaunching.runIsolate;
 import static java.util.Arrays.asList;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
diff --git a/java/tests/src/main/java/io/osv/TestLaunching.java b/java/tests/src/main/java/io/osv/TestLaunching.java
--- a/java/tests/src/main/java/io/osv/TestLaunching.java
+++ b/java/tests/src/main/java/io/osv/TestLaunching.java
@@ -5,6 +5,10 @@
 import java.util.Collections;
 import java.util.List;

+import io.osv.isolated.Context;
+import io.osv.isolated.IsolatedJvm;
+import io.osv.nonisolated.NonIsolatedJvm;
+
 import static java.util.Arrays.asList;
 import static org.fest.assertions.Assertions.assertThat;

@@ -14,13 +18,27 @@
  * This work is open source software, licensed under the terms of the
  * BSD license as described in the LICENSE file in the top-level directory.
  */
-public class TestIsolateLaunching {
+public class TestLaunching {

public static Context runIsolate(Class<?> clazz, String... programArgs) throws Throwable { return runIsolate(clazz, Collections.<String>emptyList(), programArgs);
     }

public static Context runIsolate(Class<?> clazz, List<String> args, String... programArgs) throws Throwable { + List<String> allArgs = testJarAndPrepareArgs(clazz, args, programArgs); + return IsolatedJvm.getInstance().run(allArgs.toArray(new String[allArgs.size()]));
+    }
+
+ public static Thread runWithoutIsolation(Class<?> clazz, String... programArgs) throws Throwable { + return runWithoutIsolation(clazz, Collections.<String>emptyList(), programArgs);
+    }
+
+ public static Thread runWithoutIsolation(Class<?> clazz, List<String> args, String... programArgs) throws Throwable { + List<String> allArgs = testJarAndPrepareArgs(clazz, args, programArgs); + return NonIsolatedJvm.getInstance().run(allArgs.toArray(new String[allArgs.size()]));
+    }
+
+ private static List<String> testJarAndPrepareArgs(Class<?> clazz, List<String> args, String... programArgs) {
         String jarPath = System.getProperty("isolates.jar");
         assertThat(jarPath).isNotEmpty();
         assertThat(new File(jarPath)).exists();
@@ -32,7 +50,6 @@ public static Context runIsolate(Class<?> clazz, List<String> args, String... pr
         allArgs.add(clazz.getName());
         allArgs.addAll(asList(programArgs));

- return ContextIsolator.getInstance().run(allArgs.toArray(new String[allArgs.size()]));
+        return allArgs;
     }
-
 }
diff --git a/modules/java-tests/usr.manifest b/modules/java-tests/usr.manifest
--- a/modules/java-tests/usr.manifest
+++ b/modules/java-tests/usr.manifest
@@ -0,0 +1,9 @@
+#
+# Copyright (C) 2013-2014 Cloudius Systems, Ltd.
+#
+# This work is open source software, licensed under the terms of the
+# BSD license as described in the LICENSE file in the top-level directory.
+#
+
+[manifest]
+/java_non_isolated.so: java/jvm/java_non_isolated.so
diff --git a/scripts/test.py b/scripts/test.py
--- a/scripts/test.py
+++ b/scripts/test.py
@@ -22,8 +22,10 @@
 ]

 add_tests([
- SingleCommandTest('java', '/java.so -cp /tests/java/tests.jar:/tests/java/isolates.jar \ - -Disolates.jar=/tests/java/isolates.jar org.junit.runner.JUnitCore io.osv.AllTests'), + SingleCommandTest('java_isolated', '/java.so -cp /tests/java/tests.jar:/tests/java/isolates.jar \ + -Disolates.jar=/tests/java/isolates.jar org.junit.runner.JUnitCore io.osv.AllTestsThatTestIsolatedApp'), + SingleCommandTest('java_non_isolated', '/java_non_isolated.so -cp /tests/java/tests.jar:/tests/java/isolates.jar \ + -Disolates.jar=/tests/java/isolates.jar org.junit.runner.JUnitCore io.osv.AllTestsThatTestNonIsolatedApp'), SingleCommandTest('java-perms', '/java.so -cp /tests/java/tests.jar io.osv.TestDomainPermissions'),
 ])

diff --git a/scripts/tests/testing.py b/scripts/tests/testing.py
--- a/scripts/tests/testing.py
+++ b/scripts/tests/testing.py
@@ -73,6 +73,7 @@ def scan_errors(s):
         "at org.junit.runner.JUnitCore.main",
         "ContextFailedException",
        "\[backtrace\]",
+        "Failed to load object",
     ]
     for pattern in patterns:
         if re.findall(pattern, s):

--
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to