changeset 14629:db9fc4b93cfe

8238225: Issues reported after replacing symlink at Contents/MacOS/libjli.dylib with binary Reviewed-by: clanger, alanb, ihse
author erikj
date Thu, 12 Dec 2019 19:35:57 +0000
parents f15b3ddc5024
children fc6f591fbd8a
files src/macosx/bin/java_md_macosx.c test/jdk/tools/launcher/JliLaunchTest.java test/jdk/tools/launcher/JliLaunchTest.sh test/jdk/tools/launcher/exeJliLaunchTest.c test/lib/jdk/test/lib/Platform.java
diffstat 5 files changed, 186 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/macosx/bin/java_md_macosx.c	Thu Dec 12 19:35:57 2019 +0000
+++ b/src/macosx/bin/java_md_macosx.c	Thu Dec 12 19:35:57 2019 +0000
@@ -651,11 +651,31 @@
     }
 
     size_t indexOfLastPathComponent = pathLen - sizeOfLastPathComponent;
-    if (0 == strncmp(realPathToSelf + indexOfLastPathComponent, lastPathComponent, sizeOfLastPathComponent - 1)) {
+    if (0 == strncmp(realPathToSelf + indexOfLastPathComponent, lastPathComponent, sizeOfLastPathComponent)) {
         realPathToSelf[indexOfLastPathComponent + 1] = '\0';
         return JNI_TRUE;
     }
 
+    // If libjli.dylib is loaded from a macos bundle MacOS dir, find the JRE dir
+    // in ../Home.
+    const char altLastPathComponent[] = "/MacOS/libjli.dylib";
+    size_t sizeOfAltLastPathComponent = sizeof(altLastPathComponent) - 1;
+    if (pathLen < sizeOfLastPathComponent) {
+        return JNI_FALSE;
+    }
+
+    size_t indexOfAltLastPathComponent = pathLen - sizeOfAltLastPathComponent;
+    if (0 == strncmp(realPathToSelf + indexOfAltLastPathComponent, altLastPathComponent, sizeOfAltLastPathComponent)) {
+        JLI_Snprintf(realPathToSelf + indexOfAltLastPathComponent, sizeOfAltLastPathComponent, "%s", "/Home/jre");
+        if (access(realPathToSelf, F_OK) == 0) {
+            return JNI_TRUE;
+        }
+        JLI_Snprintf(realPathToSelf + indexOfAltLastPathComponent, sizeOfAltLastPathComponent, "%s", "/Home");
+        if (access(realPathToSelf, F_OK) == 0) {
+            return JNI_TRUE;
+        }
+    }
+
     if (!speculative)
       JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL);
     return JNI_FALSE;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/JliLaunchTest.java	Thu Dec 12 19:35:57 2019 +0000
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+import java.util.Map;
+import jdk.test.lib.Utils;
+import jdk.test.lib.Platform;
+import jdk.test.lib.process.OutputAnalyzer;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class JliLaunchTest {
+    public static void main(String[] args) throws IOException {
+        Path launcher = Paths.get(System.getProperty("test.nativepath"),
+            "JliLaunchTest" + (Platform.isWindows() ? ".exe" : ""));
+        System.out.println("Launcher = " + launcher + (Files.exists(launcher) ? " (exists)" : " (not exists)"));
+        ProcessBuilder pb = new ProcessBuilder(launcher.toString(), "-version");
+        Map<String, String> env = pb.environment();
+        // On windows, the DLL should be in JDK/bin, else in JDK/lib.
+        String libdir = Paths.get(Utils.TEST_JDK).resolve(Platform.isWindows() ? "bin" : "jre/lib/jli")
+            .toAbsolutePath().toString();
+        String pathEnvVar = Platform.sharedLibraryPathVariableName();
+        env.compute(pathEnvVar, (k, v) -> (v == null) ? libdir : libdir + File.pathSeparator + v);
+
+        OutputAnalyzer outputf = new OutputAnalyzer(pb.start());
+        outputf.shouldHaveExitValue(0);
+
+        if (Platform.isOSX()) {
+            Path javaHome = Paths.get(Utils.TEST_JDK);
+            if (javaHome.getFileName().toString().equals("Home")) {
+                // To exercise this test path you need to make sure the JDK under test is
+                // the MacOS bundle and not the simple jdk image. This can currently be
+                // achieved by running something like this (from the build output dir):
+                // $ JDK_IMAGE_DIR=$PWD/images/j2sdk-bundle/jdk1.8.0.jdk/Contents/Home
+                // $ jtreg -jdk:$JDK_IMAGE_DIR $TESTROOT/jdk/tools/launcher/JliLaunchTest.sh
+                System.out.println("MacOS bundle distribution detected, also testing Contents/MacOS/libjli.dylib");
+                String macosDir = javaHome.getParent().resolve("MacOS").toString();
+                ProcessBuilder pb2 = new ProcessBuilder(launcher.toString(), "-version");
+                env = pb2.environment();
+                env.compute(pathEnvVar, (k, v) -> (v == null) ? macosDir : macosDir + File.pathSeparator + v);
+
+                OutputAnalyzer output2 = new OutputAnalyzer(pb2.start());
+                output2.shouldHaveExitValue(0);
+            } else {
+                System.out.println("Not a MacOS bundle distribution, not testing Contents/MacOS/libjli.dylib");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/JliLaunchTest.sh	Thu Dec 12 19:35:57 2019 +0000
@@ -0,0 +1,33 @@
+#!/bin/bash -xe
+
+# @test JliLaunchTest.sh
+# @bug 8238225
+# @library /lib
+# @build JliLaunchTest
+# @run shell JliLaunchTest.sh
+
+OS=`uname -s`
+if [ "${OS}" != "Darwin" ]; then
+    echo "This is a MacOSX only test"
+    exit 0;
+fi
+
+gcc_cmd=`which gcc`
+if [ "x$gcc_cmd" == "x" ]; then
+    echo "WARNING: gcc not found. Cannot execute test." 2>&1
+    exit 0;
+fi
+
+JDK_TOPDIR="${TESTROOT}/.."
+
+$gcc_cmd -o ${TESTCLASSES}/JliLaunchTest \
+    -I${JDK_TOPDIR}/src/share/bin \
+    -I${JDK_TOPDIR}/src/share/javavm/export \
+    -I${JDK_TOPDIR}/src/macosx/javavm/export \
+    -I${JDK_TOPDIR}/src/solaris/bin \
+    -L${TESTJAVA}/jre/lib/jli -ljli \
+    ${TESTSRC}/exeJliLaunchTest.c
+
+${TESTJAVA}/bin/java -Dtest.jdk=${TESTJAVA} \
+    -Dtest.nativepath=${TESTCLASSES} \
+    -cp ${TESTCLASSPATH} JliLaunchTest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/launcher/exeJliLaunchTest.c	Thu Dec 12 19:35:57 2019 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * This file contains the main entry point into the launcher code
+ * this is the only file which will be repeatedly compiled by other
+ * tools. The rest of the files will be linked in.
+ */
+
+#include "java.h"
+
+int
+main(int argc, char **argv)
+{
+    return JLI_Launch(argc, argv,
+                   0, NULL,
+                   0, NULL,
+                   "1", "0",
+                   *argv, *argv,
+                   0, 0, 0, 0);
+}
--- a/test/lib/jdk/test/lib/Platform.java	Thu Dec 12 19:35:57 2019 +0000
+++ b/test/lib/jdk/test/lib/Platform.java	Thu Dec 12 19:35:57 2019 +0000
@@ -351,6 +351,21 @@
     }
 
     /*
+     * Returns name of system variable containing paths to shared native libraries.
+     */
+    public static String sharedLibraryPathVariableName() {
+        if (isWindows()) {
+            return "PATH";
+        } else if (isOSX()) {
+            return "DYLD_LIBRARY_PATH";
+        } else if (isAix()) {
+            return "LIBPATH";
+        } else {
+            return "LD_LIBRARY_PATH";
+        }
+    }
+
+    /*
      * This should match the #if condition in ClassListParser::load_class_from_source().
      */
     public static boolean areCustomLoadersSupportedForCDS() {