Thanks. Looks like this indeed fixes the scripts/build
image=java-non-isolated,tomcat which I asked about. Committed.


--
Nadav Har'El
n...@scylladb.com

On Fri, Oct 21, 2016 at 1:05 AM, Waldemar Kozaczuk <jwkozac...@gmail.com>
wrote:

> The bulk of the changes that are part of this patch are about modifying
> runjava and java.cc so that runjava classes
> are loaded by system classloader instead of extension classloader that is
> deprecated in Java 8 and removed from Java 9. That
> way OSv can run Java applications in Java 9 JRE which will be demostrated
> in the seperate patch.
>
> Following changes are part of this commit:
>  * Added number of missing permissions to the AppClassLoader that loads
> application classes in isolated mode only (see issue #804)
>  * Added ClassDiagnostics utility class that can determine what
> classloader along with its parents was used to load individual class
>  * Added handling of -Dosv.java.diagnostics switch to  MultiJarLoader,
> RunIsolatedJvmApp, RunNonIsolatedJvmApp, RunJvmAppHelper to show
> classloader and security information
>  * Added NonIsolatingOsvSystemClassLoader intended for non-isolated mode
> so that applications (like Tomcat) that rely on standard Java LogManager
> (JUL) can properly initialize logging
>  * Changed java.cc to set JVM system classpath to /java/runjava.jar and
> set relevant classloader (NonIsolatingOsvSystemClassLoader or
> IsolatingOsvSystemClassLoader) depending on the mode
>  * Added java.policy to make runjava.jar have all permissions as if it was
> loaded by extension classloader which matters when security manager is
> enabled (see derby)
>  * Changed modules/java/module.py to place runjava under /java/runjava.jar
> instead of JRE extension folder
>
> Fixes #802
> Fixes #803
> Fixed #804
>
> Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com>
> ---
>  java/jvm/java.cc                                   |  21 ++--
>  java/runjava/src/main/java/io/osv/Jvm.java         |  72 ++++--------
>  .../src/main/java/io/osv/RunJvmAppHelper.java      |   9 ++
>  .../src/main/java/io/osv/isolated/IsolatedJvm.java |  55 +++++++--
>  ...der.java => IsolatingOsvSystemClassLoader.java} |   4 +-
>  .../main/java/io/osv/isolated/MultiJarLoader.java  |  43 ++++---
>  .../java/io/osv/isolated/RunIsolatedJvmApp.java    |   7 ++
>  .../java/io/osv/nonisolated/NonIsolatedJvm.java    |  33 ++++--
>  .../NonIsolatingOsvSystemClassLoader.java          |  26 +++++
>  .../io/osv/nonisolated/RunNonIsolatedJvmApp.java   |   7 ++
>  .../main/java/io/osv/util/ClassDiagnostics.java    | 129
> +++++++++++++++++++++
>  modules/java-non-isolated/.java.policy             |   3 +
>  modules/java-non-isolated/usr.manifest             |   3 +-
>  modules/java/.java.policy                          |   3 +
>  modules/java/usr.manifest                          |   3 +-
>  15 files changed, 330 insertions(+), 88 deletions(-)
>  rename java/runjava/src/main/java/io/osv/isolated/{OsvSystemClassLoader.java
> => IsolatingOsvSystemClassLoader.java} (97%)
>  create mode 100644 java/runjava/src/main/java/io/osv/nonisolated/
> NonIsolatingOsvSystemClassLoader.java
>  create mode 100644 java/runjava/src/main/java/io/
> osv/util/ClassDiagnostics.java
>  create mode 100644 modules/java-non-isolated/.java.policy
>  create mode 100644 modules/java/.java.policy
>
> diff --git a/java/jvm/java.cc b/java/jvm/java.cc
> index b00d937..e1b6da8 100644
> --- a/java/jvm/java.cc
> +++ b/java/jvm/java.cc
> @@ -29,11 +29,13 @@ extern size_t jvm_heap_size;
>  // sets up the class path, and runs the jar or class specified in these
>  // parameters.
>
> -#define JVM_PATH        "/usr/lib/jvm/jre/lib/amd64/server/libjvm.so"
> +#define JVM_PATH         "/usr/lib/jvm/jre/lib/amd64/server/libjvm.so"
> +#define RUNJAVA_JAR_PATH "/java/runjava.jar"
> +
>  #if defined(RUN_JAVA_NON_ISOLATED)
> -#define RUNJAVA         "io/osv/nonisolated/RunNonIsolatedJvmApp"    //
> separated by slashes, not dots
> +#define RUNJAVA          "io/osv/nonisolated/RunNonIsolatedJvmApp"    //
> separated by slashes, not dots
>  #else
> -#define RUNJAVA         "io/osv/isolated/RunIsolatedJvmApp"    //
> separated by slashes, not dots
> +#define RUNJAVA          "io/osv/isolated/RunIsolatedJvmApp"    //
> separated by slashes, not dots
>  #endif
>
>  JavaVMOption mkoption(const char* s)
> @@ -113,12 +115,17 @@ static int java_main(int argc, char **argv)
>      JNI_GetDefaultJavaVMInitArgs(&vm_args);
>
>      std::vector<JavaVMOption> options;
> -    options.push_back(mkoption("-Djava.class.path=/dev/null"));
> -#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.class.path=%s",
> RUNJAVA_JAR_PATH));
> +
> +#if defined(RUN_JAVA_NON_ISOLATED)
> +    std::cout << "java.so: Setting Java system classloader to
> NonIsolatingOsvSystemClassLoader" << "\n";
> +    options.push_back(mkoption("-Djava.system.class.loader=io.
> osv.nonisolated.NonIsolatingOsvSystemClassLoader"));
> +#else
> +    std::cout << "java.so: Setting Java system classloader to
> IsolatingOsvSystemClassLoader and logging manager to IsolatingLogManager"
> << "\n";
> +    options.push_back(mkoption("-Djava.system.class.loader=io.
> osv.isolated.IsolatingOsvSystemClassLoader"));
>      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/Jvm.java
> b/java/runjava/src/main/java/io/osv/Jvm.java
> index 4918377..209dfab 100644
> --- a/java/runjava/src/main/java/io/osv/Jvm.java
> +++ b/java/runjava/src/main/java/io/osv/Jvm.java
> @@ -1,15 +1,13 @@
>  package io.osv;
>
> +import io.osv.util.ClassDiagnostics;
> +
>  import java.io.File;
>  import java.io.FileNotFoundException;
> -import java.io.FilePermission;
>  import java.lang.reflect.InvocationTargetException;
>  import java.lang.reflect.Method;
>  import java.net.MalformedURLException;
>  import java.net.URL;
> -import java.net.URLClassLoader;
> -import java.security.CodeSource;
> -import java.security.PermissionCollection;
>  import java.util.ArrayList;
>  import java.util.List;
>  import java.util.Properties;
> @@ -84,23 +82,9 @@ public abstract class Jvm<T> {
>          }
>      }
>
> -    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);
> -    }
> -
> -    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);
> -    }
> +    protected abstract T runClass(String mainClass, String[] args,
> Iterable<String> classpath, Properties properties) throws
> MalformedURLException;
>
> -    private List<URL> toUrls(Iterable<String> classpath) throws
> MalformedURLException {
> +    protected List<URL> toUrls(Iterable<String> classpath) throws
> MalformedURLException {
>          ArrayList<URL> urls = new ArrayList<>();
>          for (String path : classpath) {
>              urls.add(toUrl(path));
> @@ -108,7 +92,28 @@ public abstract class Jvm<T> {
>          return urls;
>      }
>
> +    protected String joinClassPath(Iterable<String> classpath) {
> +        StringBuilder sb = new StringBuilder();
> +        boolean first = true;
> +        for (String path : classpath) {
> +            if (!first) {
> +                sb.append(":");
> +            }
> +            first = false;
> +            sb.append(path);
> +        }
> +        return sb.toString();
> +    }
> +
>      protected void runMain(Class<?> klass, String[] args) throws
> Throwable {
> +
> +        if(ClassDiagnostics.showDiagnostics(args)) {
> +            System.out.println("Classpath: " + System.getProperty("java.
> class.path"));
> +            System.out.println("------ Main class information --------");
> +            System.out.println("Classloader: " + ClassDiagnostics.
> showClassLoaderHierarchy(klass,false));
> +            System.out.println("Security: " + ClassDiagnostics.
> showClassSecurity(klass));
> +        }
> +
>          Method main = klass.getMethod("main", String[].class);
>          try {
>              main.invoke(null, new Object[]{args});
> @@ -125,19 +130,6 @@ public abstract class Jvm<T> {
>          }
>      }
>
> -    private String joinClassPath(Iterable<String> classpath) {
> -        StringBuilder sb = new StringBuilder();
> -        boolean first = true;
> -        for (String path : classpath) {
> -            if (!first) {
> -                sb.append(":");
> -            }
> -            first = false;
> -            sb.append(path);
> -        }
> -        return sb.toString();
> -    }
> -
>      private URL toUrl(String path) throws MalformedURLException {
>          return new URL("file:///" + path + (isDirectory(path) ? "/" :
> ""));
>      }
> @@ -176,18 +168,4 @@ public abstract class Jvm<T> {
>          }
>          return ret;
>      }
> -
> -    private static class AppClassLoader extends URLClassLoader {
> -        public AppClassLoader(URL[] urlArray, ClassLoader parent) {
> -            super(urlArray, parent);
> -        }
> -
> -        @Override
> -        protected PermissionCollection getPermissions(CodeSource
> codesource) {
> -            PermissionCollection permissions = super.getPermissions(
> codesource);
> -            permissions.add(new 
> FilePermission("/usr/lib/jvm/jre/lib/ext/runjava.jar",
> "read"));
> -            permissions.add(new RuntimePermission("exitVM"));
> -            return permissions;
> -        }
> -    }
>  }
> diff --git a/java/runjava/src/main/java/io/osv/RunJvmAppHelper.java
> b/java/runjava/src/main/java/io/osv/RunJvmAppHelper.java
> index 10ae7b5..f7b791e 100644
> --- a/java/runjava/src/main/java/io/osv/RunJvmAppHelper.java
> +++ b/java/runjava/src/main/java/io/osv/RunJvmAppHelper.java
> @@ -1,5 +1,7 @@
>  package io.osv;
>
> +import io.osv.util.ClassDiagnostics;
> +
>  /*
>   * Copyright (C) 2016 Waldemar Kozaczuk
>   * Copyright (C) 2013-2016 Cloudius Systems, Ltd.
> @@ -27,6 +29,13 @@ public class RunJvmAppHelper {
>              return;
>          }
>
> +        if(ClassDiagnostics.showDiagnostics(args)) {
> +            System.out.println("Arguments:");
> +            for(String arg:args) {
> +                System.out.println("\t[" + arg + "]");
> +            }
> +        }
> +
>          try {
>              jvmFactory.getJvm().runSync(args);
>          } catch (IllegalArgumentException ex) {
> diff --git a/java/runjava/src/main/java/io/osv/isolated/IsolatedJvm.java
> b/java/runjava/src/main/java/io/osv/isolated/IsolatedJvm.java
> index 605cac1..217d00a 100644
> --- a/java/runjava/src/main/java/io/osv/isolated/IsolatedJvm.java
> +++ b/java/runjava/src/main/java/io/osv/isolated/IsolatedJvm.java
> @@ -6,9 +6,19 @@ import io.osv.jul.IsolatingLogManager;
>  import net.sf.cglib.proxy.Dispatcher;
>  import net.sf.cglib.proxy.Enhancer;
>
> +import java.io.FilePermission;
>  import java.lang.reflect.Field;
> +import java.lang.reflect.ReflectPermission;
> +import java.net.MalformedURLException;
> +import java.net.URL;
> +import java.net.URLClassLoader;
> +import java.security.CodeSource;
> +import java.security.PermissionCollection;
> +import java.util.List;
>  import java.util.Properties;
> +import java.util.PropertyPermission;
>  import java.util.logging.LogManager;
> +import java.util.logging.LoggingPermission;
>
>  /*
>   * Copyright (C) 2016 Waldemar Kozaczuk
> @@ -88,8 +98,8 @@ public class IsolatedJvm extends Jvm<Context> {
>          return currentContext.get();
>      }
>
> -    protected Context run(ClassLoader classLoader, final String
> classpath, final String mainClass,
> -                          final String[] args, final Properties
> properties) {
> +    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);
> @@ -126,7 +136,18 @@ public class IsolatedJvm extends Jvm<Context> {
>          return context;
>      }
>
> -    protected ClassLoader getParentClassLoader() {
> +    protected Context 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 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 ClassLoader getParentClassLoader() {
>          return parentClassLoaderForIsolates;
>      }
>
> @@ -143,18 +164,38 @@ public class IsolatedJvm extends Jvm<Context> {
>          }
>      }
>
> -    private OsvSystemClassLoader getOsvClassLoader() {
> +    private IsolatingOsvSystemClassLoader getOsvClassLoader() {
>          ClassLoader systemClassLoader = ClassLoader.
> getSystemClassLoader();
> -        if (!(systemClassLoader instanceof OsvSystemClassLoader)) {
> +        if (!(systemClassLoader instanceof IsolatingOsvSystemClassLoader))
> {
>              throw new AssertionError("System class loader should be an
> instance of "
> -                    + OsvSystemClassLoader.class.getName() + " but is "
> +                    + IsolatingOsvSystemClassLoader.class.getName() + "
> but is "
>                      + systemClassLoader.getClass().getName());
>          }
>
> -        return (OsvSystemClassLoader) systemClassLoader;
> +        return (IsolatingOsvSystemClassLoader) systemClassLoader;
>      }
>
>      public Object receive() throws InterruptedException {
>          return getContext().takeMessage();
>      }
> +
> +
> +    private static class AppClassLoader extends URLClassLoader {
> +        AppClassLoader(URL[] urlArray, ClassLoader parent) {
> +            super(urlArray, parent);
> +        }
> +
> +        @Override
> +        protected PermissionCollection getPermissions(CodeSource
> codesource) {
> +            PermissionCollection permissions = super.getPermissions(
> codesource);
> +            permissions.add(new FilePermission("/java/runjava.jar",
> "read"));
> +            permissions.add(new RuntimePermission("exitVM"));
> +            permissions.add(new RuntimePermission("shutdownHooks"));
> +            permissions.add(new RuntimePermission("
> setContextClassLoader"));
> +            permissions.add(new ReflectPermission("
> suppressAccessChecks"));
> +            permissions.add(new LoggingPermission("control",null));
> +            permissions.add(new 
> PropertyPermission("java.util.logging.config.*",
> "read"));
> +            return permissions;
> +        }
> +    }
>  }
> diff --git 
> a/java/runjava/src/main/java/io/osv/isolated/OsvSystemClassLoader.java
> b/java/runjava/src/main/java/io/osv/isolated/
> IsolatingOsvSystemClassLoader.java
> similarity index 97%
> rename from java/runjava/src/main/java/io/osv/isolated/
> OsvSystemClassLoader.java
> rename to java/runjava/src/main/java/io/osv/isolated/
> IsolatingOsvSystemClassLoader.java
> index fee72cf..21a04d7 100644
> --- a/java/runjava/src/main/java/io/osv/isolated/OsvSystemClassLoader.java
> +++ b/java/runjava/src/main/java/io/osv/isolated/
> IsolatingOsvSystemClassLoader.java
> @@ -14,7 +14,7 @@ import java.lang.reflect.Method;
>  import java.net.URL;
>  import java.util.Enumeration;
>
> -public class OsvSystemClassLoader extends ClassLoader {
> +public class IsolatingOsvSystemClassLoader extends ClassLoader {
>      private final ClassLoader defaultSystemClassLoader;
>
>      static {
> @@ -31,7 +31,7 @@ public class OsvSystemClassLoader extends ClassLoader {
>      private final Method findLibrary;
>      private final Method findResources;
>
> -    public OsvSystemClassLoader(ClassLoader defaultSystemClassLoader)
> throws NoSuchMethodException {
> +    public IsolatingOsvSystemClassLoader(ClassLoader
> defaultSystemClassLoader) throws NoSuchMethodException {
>          super(defaultSystemClassLoader);
>          this.defaultSystemClassLoader = defaultSystemClassLoader;
>
> diff --git a/java/runjava/src/main/java/io/osv/isolated/MultiJarLoader.java
> b/java/runjava/src/main/java/io/osv/isolated/MultiJarLoader.java
> index 7790e3d..7c9555b 100644
> --- a/java/runjava/src/main/java/io/osv/isolated/MultiJarLoader.java
> +++ b/java/runjava/src/main/java/io/osv/isolated/MultiJarLoader.java
> @@ -1,9 +1,16 @@
>  package io.osv.isolated;
>
> +import io.osv.util.ClassDiagnostics;
> +
>  import java.io.BufferedReader;
>  import java.io.File;
>  import java.io.FileReader;
>  import java.io.IOException;
> +import java.util.ArrayList;
> +import java.util.Arrays;
> +import java.util.List;
> +
> +import static io.osv.util.ClassDiagnostics.JAVA_DIAGNOSTICS_PROPERTY_
> NAME;
>
>  /**
>   * MultiJarLoader load multiple jars with their main and command line
> when using
> @@ -21,18 +28,19 @@ public class MultiJarLoader {
>       *             - mains /usr/mgmt/myfile.txt
>       */
>      public static void main(String[] args) {
> +        final boolean showDiagnostics = ClassDiagnostics.
> showDiagnostics(args);
>          for (int i = 0; i < args.length; i++) {
>              if (args[i].equals("-mains")) {
>                  if (i + 1 >= args.length) {
>                      System.err.println("No file specified for load from
> file");
>                  }
> -                runFromFile(args[i + 1]);
> +                runFromFile(args[i + 1],showDiagnostics);
>                  return;
>              }
>          }
>          System.err
>                  .println("No load file was specified, using default
> /usr/mgmt/javamains, use -mains to overide");
> -        runFromFile("/usr/mgmt/javamains");
> +        runFromFile("/usr/mgmt/javamains",showDiagnostics);
>      }
>
>      /**
> @@ -41,8 +49,8 @@ public class MultiJarLoader {
>       *
>       * @param fileName the file name to read from
>       */
> -    private static void runFromFile(String fileName) {
> -        FileReader fr = null;
> +    private static void runFromFile(String fileName,boolean
> showDiagnostics) {
> +        FileReader fr;
>          try {
>              File f = new File(fileName);
>              fr = new FileReader(f);
> @@ -51,14 +59,14 @@ public class MultiJarLoader {
>                      + " with exception " + e);
>              return;
>          }
> -        BufferedReader reader = new BufferedReader(fr);
> -        String line;
> -        try {
> +
> +        try(final BufferedReader reader = new BufferedReader(fr)) {
> +            String line;
>              while ((line = reader.readLine()) != null) {
> -                String trimedLine = line.trim();
> -                if (isExec(trimedLine)) {
> -                    RunOnThread thrd = new RunOnThread(trimedLine);
> -                    thrd.start();
> +                String trimmedLine = line.trim();
> +                if (isExec(trimmedLine)) {
> +                    final RunOnThread thread = new
> RunOnThread(trimmedLine,showDiagnostics);
> +                    thread.start();
>                  }
>              }
>          } catch (IOException e) {
> @@ -102,15 +110,24 @@ public class MultiJarLoader {
>       */
>      private static class RunOnThread extends Thread {
>          private String args;
> +        private boolean showDiagnostics;
>
> -        public RunOnThread(String args) {
> +        RunOnThread(String args,boolean showDiagnostics) {
>              this.args = args;
> +            this.showDiagnostics = showDiagnostics;
>          }
>
>          @Override
>          public void run() {
>              try {
> -                IsolatedJvm.getInstance().runSync(args.split("\\s+"));
> +                final List<String> argumentsList = new ArrayList<>();
> +                if(showDiagnostics) {
> +                    argumentsList.add("-D" + JAVA_DIAGNOSTICS_PROPERTY_
> NAME);
> +                }
> +                argumentsList.addAll(Arrays.asList(args.split("\\s+")));
> +
> +                final String[] argumentsArray = argumentsList.toArray(new
> String[] {});
> +                IsolatedJvm.getInstance().runSync(argumentsArray);
>              } 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/RunIsolatedJvmApp.java
> b/java/runjava/src/main/java/io/osv/isolated/RunIsolatedJvmApp.java
> index 689eaca..124eb75 100644
> --- a/java/runjava/src/main/java/io/osv/isolated/RunIsolatedJvmApp.java
> +++ b/java/runjava/src/main/java/io/osv/isolated/RunIsolatedJvmApp.java
> @@ -9,6 +9,7 @@ package io.osv.isolated;
>   */
>
>  import io.osv.Jvm;
> +import io.osv.util.ClassDiagnostics;
>
>  import static io.osv.RunJvmAppHelper.runSync;
>  import static io.osv.RunJvmAppHelper.JvmFactory;
> @@ -25,6 +26,12 @@ public class RunIsolatedJvmApp {
>      }
>
>      public static void main(String[] args) {
> +        if(ClassDiagnostics.showDiagnostics(args)) {
> +            System.out.println("------ Run Java class information
> --------");
> +            System.out.println("Classloader: " + ClassDiagnostics.
> showClassLoaderHierarchy(RunIsolatedJvmApp.class,false));
> +            System.out.println("Security: " + ClassDiagnostics.
> showClassSecurity(RunIsolatedJvmApp.class));
> +        }
> +
>          runSync(new JvmFactory() {
>              public Jvm getJvm() {
>                  return IsolatedJvm.getInstance();
> diff --git a/java/runjava/src/main/java/io/osv/nonisolated/NonIsolatedJvm.java
> b/java/runjava/src/main/java/io/osv/nonisolated/NonIsolatedJvm.java
> index e1c1fcb..68767f9 100644
> --- a/java/runjava/src/main/java/io/osv/nonisolated/NonIsolatedJvm.java
> +++ b/java/runjava/src/main/java/io/osv/nonisolated/NonIsolatedJvm.java
> @@ -4,6 +4,9 @@ import io.osv.AppThreadTerminatedWithUncaughtException;
>  import io.osv.Jvm;
>  import io.osv.MainClassNotFoundException;
>
> +import java.net.MalformedURLException;
> +import java.net.URL;
> +import java.util.List;
>  import java.util.Properties;
>  import java.util.Map;
>  import java.util.concurrent.atomic.AtomicReference;
> @@ -18,7 +21,9 @@ public class NonIsolatedJvm extends Jvm<Thread> {
>
>      private static final NonIsolatedJvm instance = new NonIsolatedJvm();
>
> -    private AtomicReference<Throwable> thrownException = new
> AtomicReference<>();
> +    private final AtomicReference<Throwable> thrownException = new
> AtomicReference<>();
> +
> +    private final NonIsolatingOsvSystemClassLoader osvSystemClassLoader
> = getOsvClassLoader();
>
>      public static NonIsolatedJvm getInstance() {
>          return instance;
> @@ -27,8 +32,7 @@ public class NonIsolatedJvm extends Jvm<Thread> {
>      private NonIsolatedJvm() {
>      }
>
> -    @Override
> -    protected Thread run(ClassLoader classLoader, final String classpath,
> final String mainClass, final String[] args, final Properties properties) {
> +    private Thread run(final String classpath, final String mainClass,
> final String[] args, final Properties properties) {
>          thrownException.set(null);
>          Thread thread = new Thread() {
>              @Override
> @@ -56,11 +60,16 @@ public class NonIsolatedJvm extends Jvm<Thread> {
>                  thrownException.set(e);
>              }
>          });
> -        thread.setContextClassLoader(classLoader);
>          thread.start();
>          return thread;
>      }
>
> +    protected Thread runClass(String mainClass, String[] args,
> Iterable<String> classpath, Properties properties) throws
> MalformedURLException {
> +        final List<URL> appUrls = toUrls(classpath);
> +        osvSystemClassLoader.addURLs(appUrls);
> +        return run(joinClassPath(classpath), mainClass, args, properties);
> +    }
> +
>      public void runSync(String... args) throws Throwable {
>          Thread thread = run(args);
>
> @@ -78,12 +87,16 @@ public class NonIsolatedJvm extends Jvm<Thread> {
>          }
>      }
>
> -    @Override
> -    protected ClassLoader getParentClassLoader() {
> -        return Thread.currentThread().getContextClassLoader();
> -    }
> +    private NonIsolatingOsvSystemClassLoader getOsvClassLoader() {
> +        ClassLoader systemClassLoader = ClassLoader.
> getSystemClassLoader();
> +        if (!(systemClassLoader instanceof NonIsolatingOsvSystemClassLoader))
> {
> +            throw new AssertionError("System class loader should be an
> instance of "
> +                    + NonIsolatingOsvSystemClassLoader.class.getName() +
> " but is "
> +                    + systemClassLoader.getClass().getName());
> +        }
>
> -    public Throwable getThrownExceptionIfAny() {
> -        return thrownException.get();
> +        return (NonIsolatingOsvSystemClassLoader) systemClassLoader;
>      }
> +
> +    public Throwable getThrownExceptionIfAny() { return
> thrownException.get(); }
>  }
> diff --git a/java/runjava/src/main/java/io/osv/nonisolated/
> NonIsolatingOsvSystemClassLoader.java b/java/runjava/src/main/java/
> io/osv/nonisolated/NonIsolatingOsvSystemClassLoader.java
> new file mode 100644
> index 0000000..5d16607
> --- /dev/null
> +++ b/java/runjava/src/main/java/io/osv/nonisolated/
> NonIsolatingOsvSystemClassLoader.java
> @@ -0,0 +1,26 @@
> +package io.osv.nonisolated;
> +
> +import java.net.URL;
> +import java.net.URLClassLoader;
> +import java.util.List;
> +
> +/**
> + * Created by wkozaczuk on 10/5/16.
> + */
> +public class NonIsolatingOsvSystemClassLoader extends URLClassLoader {
> +    static {
> +        registerAsParallelCapable();
> +    }
> +
> +    public NonIsolatingOsvSystemClassLoader(ClassLoader parent) {
> +        super(new URL[] {}, parent);
> +    }
> +
> +    final void addURLs(List<URL> newURLs) {
> +        if(null != newURLs) {
> +            for(URL url: newURLs) {
> +                super.addURL(url);
> +            }
> +        }
> +    }
> +}
> diff --git 
> a/java/runjava/src/main/java/io/osv/nonisolated/RunNonIsolatedJvmApp.java
> b/java/runjava/src/main/java/io/osv/nonisolated/RunNonIsolatedJvmApp.java
> index c7ffa2b..a05ae6c 100644
> --- a/java/runjava/src/main/java/io/osv/nonisolated/
> RunNonIsolatedJvmApp.java
> +++ b/java/runjava/src/main/java/io/osv/nonisolated/
> RunNonIsolatedJvmApp.java
> @@ -8,6 +8,7 @@ package io.osv.nonisolated;
>   */
>
>  import io.osv.Jvm;
> +import io.osv.util.ClassDiagnostics;
>
>  import static io.osv.RunJvmAppHelper.runSync;
>  import static io.osv.RunJvmAppHelper.JvmFactory;
> @@ -24,6 +25,12 @@ public class RunNonIsolatedJvmApp {
>      }
>
>      public static void main(String[] args) {
> +        if(ClassDiagnostics.showDiagnostics(args)) {
> +            System.out.println("------ Run Java class information
> --------");
> +            System.out.println("Classloader: " + ClassDiagnostics.
> showClassLoaderHierarchy(RunNonIsolatedJvmApp.class,false));
> +            System.out.println("Security: " + ClassDiagnostics.
> showClassSecurity(RunNonIsolatedJvmApp.class));
> +        }
> +
>          runSync(new JvmFactory() {
>              public Jvm getJvm() {
>                  return NonIsolatedJvm.getInstance();
> diff --git a/java/runjava/src/main/java/io/osv/util/ClassDiagnostics.java
> b/java/runjava/src/main/java/io/osv/util/ClassDiagnostics.java
> new file mode 100644
> index 0000000..4a19eba
> --- /dev/null
> +++ b/java/runjava/src/main/java/io/osv/util/ClassDiagnostics.java
> @@ -0,0 +1,129 @@
> +package io.osv.util;
> +
> +import java.net.URL;
> +import java.net.URLClassLoader;
> +import java.security.CodeSource;
> +import java.security.ProtectionDomain;
> +
> +/*
> + * 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.
> + */
> +
> +/**
> + * Utility class for class diagnostic purposes, to analyze the
> + * ClassLoader hierarchy and security information for any given class.
> + *
> + * @author Waldemar Kozaczuk
> + * @see java.lang.ClassLoader
> + */
> +public class ClassDiagnostics {
> +
> +    public static final String JAVA_DIAGNOSTICS_PROPERTY_NAME =
> "osv.java.diagnostics";
> +
> +    public static boolean showDiagnostics(String args[]) {
> +        if (null != System.getProperty(JAVA_DIAGNOSTICS_PROPERTY_NAME)) {
> +            return true;
> +        }
> +        if (args == null) {
> +            return false;
> +        }
> +        final String diagnosticsPropertyToCompare = ("-D" +
> JAVA_DIAGNOSTICS_PROPERTY_NAME).toLowerCase();
> +        for (String arg : args) {
> +            if (null != arg && 
> arg.toLowerCase().startsWith(diagnosticsPropertyToCompare))
> {
> +                return true;
> +            }
> +        }
> +        return false;
> +    }
> +
> +    /**
> +     * Show security information in terms of permissions granted for the
> given class.
> +     *
> +     * @param clazz class to analyze security for
> +     * @return a String showing the security information about class as
> well which code source (typically jar)
> +     * it has been loaded from
> +     */
> +    public static String showClassSecurity(final Class clazz) {
> +        if (null != clazz) {
> +            final ProtectionDomain protectionDomain =
> clazz.getProtectionDomain();
> +            final CodeSource codeSource = protectionDomain.
> getCodeSource();
> +            return "class=[" + clazz.getName() + "] loaded from\n" +
> +                    "\tcode source=[" + (codeSource != null ?
> protectionDomain.getCodeSource().getLocation() : "BOOTSTRAP code source
> (rt.jar)") + "]\n" +
> +                    "\twith permissions=[" + 
> protectionDomain.getPermissions()
> + "]";
> +        } else
> +            throw new IllegalArgumentException("Received null clazz
> argument");
> +    }
> +
> +    /**
> +     * Show the class loader hierarchy for the given class.
> +     *
> +     * @param clazz class to analyze hierarchy for
> +     * @return a String showing the class loader hierarchy for this class
> +     */
> +    public static String showClassLoaderHierarchy(final Class clazz,
> final boolean showContextClassLoader) {
> +        if (null != clazz) {
> +            if (showContextClassLoader) {
> +                final ClassLoader contextClassLoader =
> Thread.currentThread().getContextClassLoader();
> +
> +                return "context class loader=[" + 
> buildClassLoaderInfo(contextClassLoader,
> "\t") + "] hashCode=" + contextClassLoader.hashCode() + "\n" +
> +                        "class=[" + clazz.getName() + "] loaded by " +
> +                        buildClassLoaderHierarchyInfo(clazz.getClassLoader(),
> "\n", "\t", 0);
> +            } else {
> +                return "class=[" + clazz.getName() + "] loaded by " +
> +                        buildClassLoaderHierarchyInfo(clazz.getClassLoader(),
> "\n", "\t", 0);
> +            }
> +        } else
> +            throw new IllegalArgumentException("Received null clazz
> argument");
> +    }
> +
> +    private static String buildClassLoaderHierarchyInfo(ClassLoader
> classLoader, String lineBreak, String tabText, int indent) {
> +        final StringBuilder builder = new StringBuilder();
> +        for (int i = 0; i < indent; i++) {
> +            builder.append(tabText);
> +        }
> +
> +        if (classLoader == null) {
> +            builder.append("[BOOTSTRAP classloader]").append(lineBreak);
> +        } else {
> +            final String urlIndent = builder.toString() + tabText;
> +            builder.append("[").append(buildClassLoaderInfo(classLoader,
> urlIndent)).
> +                    append("] hashCode=").
> +                    append(classLoader.hashCode()).
> +                    append(" which is PARENT of: ").
> +                    append(lineBreak);
> +
> +            final ClassLoader parent = classLoader.getParent();
> +            builder.append(buildClassLoaderHierarchyInfo(parent,
> lineBreak, tabText, indent + 1));
> +        }
> +        return builder.toString();
> +    }
> +
> +    private static String buildClassLoaderInfo(ClassLoader classLoader,
> String urlIndent) {
> +        if (classLoader instanceof URLClassLoader) {
> +            final URLClassLoader urlClassLoader = (URLClassLoader)
> classLoader;
> +            final String baseInformation = classLoader.toString() + ",
> URLs=[";
> +
> +            final StringBuilder builder = new StringBuilder();
> +            for (URL url : urlClassLoader.getURLs()) {
> +                if (builder.length() > 0) {
> +                    builder.append(",");
> +                }
> +                builder.append("\n").append(urlIndent).append(url);
> +            }
> +            builder.append("]");
> +
> +            return baseInformation + builder.toString();
> +        } else {
> +            return classLoader.toString();
> +        }
> +    }
> +
> +    public static void main(String args[]) throws ClassNotFoundException {
> +        final Class clazz = Class.forName(args[0]);
> +        System.out.println(showClassLoaderHierarchy(clazz, false));
> +        System.out.println(showClassSecurity(clazz));
> +    }
> +}
> diff --git a/modules/java-non-isolated/.java.policy
> b/modules/java-non-isolated/.java.policy
> new file mode 100644
> index 0000000..af1cdc7
> --- /dev/null
> +++ b/modules/java-non-isolated/.java.policy
> @@ -0,0 +1,3 @@
> +grant codeBase "file:/java/runjava.jar" {
> +        permission java.security.AllPermission;
> +};
> diff --git a/modules/java-non-isolated/usr.manifest
> b/modules/java-non-isolated/usr.manifest
> index 63b11bc..cd02161 100644
> --- a/modules/java-non-isolated/usr.manifest
> +++ b/modules/java-non-isolated/usr.manifest
> @@ -17,5 +17,6 @@
>  /usr/lib/&/jni/power.so: java/&
>  /java.so: java/jvm/java_non_isolated.so
>  /usr/lib/libosv.so: libosv.so
> -/usr/lib/jvm/java/jre/lib/ext/runjava.jar: ${OSV_BASE}/java/runjava/
> target/runjava.jar
> +/java/runjava.jar: ${OSV_BASE}/java/runjava/target/runjava.jar
>  /java/cloudius.jar: ${OSV_BASE}/java/cloudius/target/cloudius.jar
> +/.java.policy: ${OSV_BASE}/modules/java/.java.policy
> diff --git a/modules/java/.java.policy b/modules/java/.java.policy
> new file mode 100644
> index 0000000..af1cdc7
> --- /dev/null
> +++ b/modules/java/.java.policy
> @@ -0,0 +1,3 @@
> +grant codeBase "file:/java/runjava.jar" {
> +        permission java.security.AllPermission;
> +};
> diff --git a/modules/java/usr.manifest b/modules/java/usr.manifest
> index ced9413..d19879e 100644
> --- a/modules/java/usr.manifest
> +++ b/modules/java/usr.manifest
> @@ -17,5 +17,6 @@
>  /usr/lib/&/jni/power.so: java/&
>  /java.so: java/jvm/java.so
>  /usr/lib/libosv.so: libosv.so
> -/usr/lib/jvm/java/jre/lib/ext/runjava.jar: ${OSV_BASE}/java/runjava/
> target/runjava.jar
> +/java/runjava.jar: ${OSV_BASE}/java/runjava/target/runjava.jar
>  /java/cloudius.jar: ${OSV_BASE}/java/cloudius/target/cloudius.jar
> +/.java.policy: ${OSV_BASE}/modules/java/.java.policy
> --
> 2.7.4
>
> --
> 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.
>

-- 
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