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.