8211037: Load jib jars dynamically from JibArtifactManager
authorerikj
Mon, 24 Sep 2018 13:51:22 -0700
changeset 51856 11b9d3a6f31c
parent 51855 8bbb5cbac92c
child 51857 9978fea8a371
8211037: Load jib jars dynamically from JibArtifactManager Reviewed-by: ihse
make/RunTests.gmk
make/autoconf/spec.gmk.in
make/autoconf/toolchain.m4
make/conf/jib-profiles.js
test/TestCommon.gmk
test/lib/jdk/test/lib/artifacts/ArtifactResolver.java
test/lib/jdk/test/lib/artifacts/JibArtifactManager.java
--- a/make/RunTests.gmk	Mon Sep 24 20:45:06 2018 +0200
+++ b/make/RunTests.gmk	Mon Sep 24 13:51:22 2018 -0700
@@ -531,8 +531,8 @@
     $1_JTREG_BASIC_OPTIONS += $$(addprefix -exclude:, $$($1_JTREG_PROBLEM_LIST))
   endif
 
-  ifneq ($$(JIB_JAR), )
-    $1_JTREG_BASIC_OPTIONS += -cpa:$$(JIB_JAR)
+  ifneq ($$(JIB_HOME), )
+    $1_JTREG_BASIC_OPTIONS += -e:JIB_HOME=$$(JIB_HOME)
   endif
 
   $1_JTREG_BASIC_OPTIONS += -e:TEST_IMAGE_GRAAL_DIR=${TEST_IMAGE_DIR}/hotspot/jtreg/graal
--- a/make/autoconf/spec.gmk.in	Mon Sep 24 20:45:06 2018 +0200
+++ b/make/autoconf/spec.gmk.in	Mon Sep 24 13:51:22 2018 -0700
@@ -723,7 +723,7 @@
 XATTR:=@XATTR@
 JT_HOME:=@JT_HOME@
 JTREGEXE:=@JTREGEXE@
-JIB_JAR:=@JIB_JAR@
+JIB_HOME:=@JIB_HOME@
 XCODEBUILD=@XCODEBUILD@
 DTRACE := @DTRACE@
 FIXPATH:=@FIXPATH@
--- a/make/autoconf/toolchain.m4	Mon Sep 24 20:45:06 2018 +0200
+++ b/make/autoconf/toolchain.m4	Mon Sep 24 13:51:22 2018 -0700
@@ -1144,5 +1144,5 @@
     fi
   fi
 
-  AC_SUBST(JIB_JAR)
+  AC_SUBST(JIB_HOME)
 ])
--- a/make/conf/jib-profiles.js	Mon Sep 24 20:45:06 2018 +0200
+++ b/make/conf/jib-profiles.js	Mon Sep 24 13:51:22 2018 -0700
@@ -961,9 +961,9 @@
             ext: "zip",
             classifier: "distribution",
             revision: "3.0-SNAPSHOT",
-            environment_name: "JIB_JAR",
+            environment_name: "JIB_HOME",
             environment_value: input.get("jib", "install_path")
-                + "/jib-3.0-SNAPSHOT-distribution/lib/jib-3.0-SNAPSHOT.jar"
+                + "/jib-3.0-SNAPSHOT-distribution"
         },
 
         ant: {
--- a/test/TestCommon.gmk	Mon Sep 24 20:45:06 2018 +0200
+++ b/test/TestCommon.gmk	Mon Sep 24 13:51:22 2018 -0700
@@ -453,8 +453,8 @@
 
 # Set other vm and test options
 JTREG_TEST_OPTIONS += $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_VM_ARGS:%=-vmoption:%)
-ifneq ($(JIB_JAR), )
-  JTREG_BASIC_OPTIONS += -cpa:$(shell $(GETMIXEDPATH) "$(JIB_JAR)")
+ifneq ($(JIB_HOME), )
+  JTREG_BASIC_OPTIONS += -e:JIB_HOME=$(shell $(GETMIXEDPATH) "$(JIB_HOME)")
 endif
 ifeq ($(IGNORE_MARKED_TESTS), true)
   # Option to tell jtreg to not run tests marked with "ignore"
--- a/test/lib/jdk/test/lib/artifacts/ArtifactResolver.java	Mon Sep 24 20:45:06 2018 +0200
+++ b/test/lib/jdk/test/lib/artifacts/ArtifactResolver.java	Mon Sep 24 13:51:22 2018 -0700
@@ -23,7 +23,6 @@
 
 package jdk.test.lib.artifacts;
 
-import java.io.FileNotFoundException;
 import java.nio.file.Path;
 import java.util.HashMap;
 import java.util.Map;
@@ -35,7 +34,7 @@
             String managerName = System.getProperty("jdk.test.lib.artifacts.artifactmanager");
             if (managerName != null) {
                 manager = (ArtifactManager) Class.forName(managerName).newInstance();
-            } else {
+            } else if (System.getenv().containsKey(JibArtifactManager.JIB_HOME_ENV_NAME)) {
                 manager = JibArtifactManager.newInstance();
             }
         } catch (Exception e) {
--- a/test/lib/jdk/test/lib/artifacts/JibArtifactManager.java	Mon Sep 24 20:45:06 2018 +0200
+++ b/test/lib/jdk/test/lib/artifacts/JibArtifactManager.java	Mon Sep 24 13:51:22 2018 -0700
@@ -23,26 +23,66 @@
 
 package jdk.test.lib.artifacts;
 
-import java.io.FileNotFoundException;
+import java.io.UncheckedIOException;
 import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.stream.Stream;
 
 public class JibArtifactManager implements ArtifactManager {
     private static final String JIB_SERVICE_FACTORY = "com.oracle.jib.api.JibServiceFactory";
+    public static final String JIB_HOME_ENV_NAME = "JIB_HOME";
     private static String jibVersion = "1.0";
-    private Object installerObject;
 
-    private JibArtifactManager(Object o) {
-        installerObject = o;
+    private Object installerObject;
+    private ClassLoader classLoader;
+
+    private JibArtifactManager(Object installerObject, ClassLoader classLoader) {
+        this.installerObject = installerObject;
+        this.classLoader = classLoader;
     }
 
     public static JibArtifactManager newInstance() throws ClassNotFoundException {
+        Path jibInstallDir = Paths.get(System.getenv(JIB_HOME_ENV_NAME));
+        Path libDir = jibInstallDir.resolve("lib");
+        if (!Files.isDirectory(libDir)) {
+            throw new ClassNotFoundException(JIB_SERVICE_FACTORY);
+        }
         try {
-            Class jibServiceFactory = Class.forName(JIB_SERVICE_FACTORY);
-            Object jibArtifactInstaller = jibServiceFactory.getMethod("createJibArtifactInstaller").invoke(null);
-            return new JibArtifactManager(jibArtifactInstaller);
+            URL[] jarUrls;
+            try (Stream<Path> files = Files.list(libDir)) {
+                jarUrls = files.filter(path -> path.toString().endsWith(".jar"))
+                        .map(path -> {
+                            try {
+                                return path.toUri().toURL();
+                            } catch (MalformedURLException e) {
+                                throw new UncheckedIOException(e);
+                            }
+                        }).toArray(URL[]::new);
+            }
+            // Create a class loader using all those jars and set the parent to the
+            // current class loader's parent.
+            ClassLoader classLoader = new URLClassLoader(jarUrls, JibArtifactManager.class.getClassLoader().getParent());
+
+            // Temporarily replace the context classLoader
+            Thread currentThread = Thread.currentThread();
+            ClassLoader oldContextLoader = currentThread.getContextClassLoader();
+            currentThread.setContextClassLoader(classLoader);
+
+            Class jibServiceFactory = classLoader.loadClass(JIB_SERVICE_FACTORY);
+            try {
+                Object jibArtifactInstaller = jibServiceFactory.getMethod("createJibArtifactInstaller").invoke(null);
+                return new JibArtifactManager(jibArtifactInstaller, classLoader);
+            } finally {
+                currentThread.setContextClassLoader(oldContextLoader);
+            }
+
         } catch (Exception e) {
             throw new ClassNotFoundException(JIB_SERVICE_FACTORY, e);
         }
@@ -56,9 +96,19 @@
         return invokeInstallerMethod("install", jibVersion, artifactDescription);
     }
 
-    private Path invokeInstallerMethod(String methodName, String jibVersion, HashMap<String, Object> artifactDescription) throws Exception {
-        Method m = Class.forName("com.oracle.jib.api.JibArtifactInstaller").getMethod(methodName, String.class, Map.class);
-        return (Path)m.invoke(installerObject, jibVersion, artifactDescription);
+    private Path invokeInstallerMethod(String methodName, String jibVersion,
+                                       HashMap<String, Object> artifactDescription) throws Exception {
+        // Temporarily replace the context classLoader
+        Thread currentThread = Thread.currentThread();
+        ClassLoader oldContextLoader = currentThread.getContextClassLoader();
+        currentThread.setContextClassLoader(classLoader);
+        try {
+            Method m = classLoader.loadClass("com.oracle.jib.api.JibArtifactInstaller")
+                    .getMethod(methodName, String.class, Map.class);
+            return (Path) m.invoke(installerObject, jibVersion, artifactDescription);
+        } finally {
+            currentThread.setContextClassLoader(oldContextLoader);
+        }
     }
 
     @Override
@@ -89,5 +139,5 @@
             }
         }
         return path;
-   }
+    }
 }