8169909: java agent fails to add to class path when the initial module is a named module

Reviewed-by: alanb
This commit is contained in:
Mandy Chung 2016-11-20 07:57:57 -08:00
parent 709d9ee9d0
commit 671d12ce6b
7 changed files with 290 additions and 18 deletions

View File

@ -72,13 +72,13 @@ public class ClassLoaders {
// If neither is specified then default to -cp <working directory>
// If -cp is not specified and -m is specified, the value of
// java.class.path is an empty string, then no class path.
URLClassPath ucp = null;
URLClassPath ucp = new URLClassPath(new URL[0]);
String mainMid = System.getProperty("jdk.module.main");
String cp = System.getProperty("java.class.path");
if (cp == null)
cp = "";
if (mainMid == null || cp.length() > 0)
ucp = toURLClassPath(cp);
addClassPathToUCP(cp, ucp);
// create the class loaders
BOOT_LOADER = new BootClassLoader(bcp);

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2016, 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.
*/
/**
* @test
* @bug 8169909
* @library src /lib/testlibrary
* @build test/*
* @run shell AppendToClassPathModuleTest.sh
* @run main AppendToClassPathModuleTest
*/
import java.util.Map;
import static jdk.testlibrary.ProcessTools.*;
/**
* Launch a modular test with no class path and no CLASSPATH set.
* The java agent appends to the "hidden" directory to the class path
* at runtime.
*/
public class AppendToClassPathModuleTest {
public static void main(String... args) throws Throwable {
String modulepath = System.getProperty("test.module.path");
ProcessBuilder pb =
createJavaProcessBuilder("-javaagent:Agent.jar",
"--module-path", modulepath,
"-m", "test/jdk.test.Main");
// remove CLASSPATH environment variable
Map<String,String> env = pb.environment();
String value = env.remove("CLASSPATH");
int exitCode = executeCommand(pb).getExitValue();
if (exitCode != 0) {
throw new RuntimeException("Test failed: " + exitCode);
}
}
}

View File

@ -0,0 +1,67 @@
#!/bin/sh
#
# Copyright (c) 2016, 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.
#
if [ "${TESTSRC}" = "" ]
then
echo "TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
echo "TESTSRC=${TESTSRC}"
if [ "${TESTJAVA}" = "" ]
then
echo "TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
echo "TESTJAVA=${TESTJAVA}"
if [ "${COMPILEJAVA}" = "" ]
then
COMPILEJAVA="${TESTJAVA}"
fi
echo "COMPILEJAVA=${COMPILEJAVA}"
if [ "${TESTCLASSES}" = "" ]
then
echo "TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
echo "TESTCLASSES=${TESTCLASSES}"
mkdir -p hidden
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
-d hidden ${TESTSRC}/../ExampleForClassPath.java
mkdir -p classes
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
-d classes ${TESTSRC}/../InstrumentationHandoff.java
echo "Manifest-Version: 1.0" > Agent.mf
echo "Class-Path: hidden/" >> Agent.mf
echo "Premain-Class: InstrumentationHandoff" >> Agent.mf
${TESTJAVA}/bin/jar ${TESTTOOLVMOPTS} cvfm Agent.jar \
Agent.mf -C classes InstrumentationHandoff.class

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2016, 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.
*/
package jdk.test;
/**
* Launched by AppendToClassPathModuleTest.
*/
public class Main {
public static void main(String... args) throws Exception {
// "java.class.path" system property is expected to be empty.
String value = System.getProperty("java.class.path");
if (!value.isEmpty()) {
throw new RuntimeException("Non-empty java.class.path=" + value);
}
// load the "hidden" class that should be loaded by the system loader
Class<?> c = Class.forName("ExampleForClassPath");
if (c.getClassLoader() != ClassLoader.getSystemClassLoader()) {
throw new RuntimeException(c + " loaderd by " + c.getClassLoader());
}
}
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2016, 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.
*/
module test {
}

View File

@ -21,12 +21,14 @@
* questions.
*/
import java.io.BufferedWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.spi.ToolProvider;
import jdk.testlibrary.OutputAnalyzer;
import org.testng.annotations.BeforeTest;
@ -42,6 +44,7 @@ import static jdk.testlibrary.ProcessTools.*;
* @summary Test the default class path if -Djava.class.path is set
* @library /lib/testlibrary
* @modules jdk.compiler
* jdk.jartool
* @build CompilerUtils jdk.testlibrary.*
* @run testng JavaClassPathTest
*/
@ -50,6 +53,7 @@ public class JavaClassPathTest {
private static final Path SRC_DIR = Paths.get(System.getProperty("test.src"),
"src");
private static final Path MODS_DIR = Paths.get("mods");
private static final Path LIB_DIR = Paths.get("lib");
private static final String TEST_MODULE = "m";
private static final String TEST_MAIN = "jdk.test.Main";
@ -66,27 +70,47 @@ public class JavaClassPathTest {
Path res = Paths.get("jdk/test/res.properties");
Files.createFile(res);
ToolProvider jartool = ToolProvider.findFirst("jar").orElseThrow(
() -> new RuntimeException("jar tool not found")
);
Path jarfile = LIB_DIR.resolve("m.jar");
Files.createDirectories(LIB_DIR);
assertTrue(jartool.run(System.out, System.err, "cfe",
jarfile.toString(), TEST_MAIN,
file.toString()) == 0);
Path manifest = LIB_DIR.resolve("manifest");
try (BufferedWriter writer = Files.newBufferedWriter(manifest)) {
writer.write("CLASS-PATH: lib/m.jar");
}
jarfile = LIB_DIR.resolve("m1.jar");
assertTrue(jartool.run(System.out, System.err, "cfme",
jarfile.toString(), manifest.toString(), TEST_MAIN,
file.toString()) == 0);
}
@DataProvider(name = "classpath")
public Object[][] classpath() {
return new Object[][]{
// true indicates that class path default to current working directory
{ "", true },
{ "-Djava.class.path", true },
{ "-Djava.class.path=", true },
{ "-Djava.class.path=.", true },
{ "", "." },
{ "-Djava.class.path", "." },
{ "-Djava.class.path=", "" },
{ "-Djava.class.path=.", "." },
};
}
@Test(dataProvider = "classpath")
public void testUnnamedModule(String option, boolean expected) throws Throwable {
public void testUnnamedModule(String option, String expected) throws Throwable {
List<String> args = new ArrayList<>();
if (!option.isEmpty()) {
args.add(option);
}
args.add(TEST_MAIN);
args.add(Boolean.toString(expected));
args.add(Boolean.toString(true));
args.add(expected);
assertTrue(execute(args).getExitValue() == 0);
}
@ -95,15 +119,14 @@ public class JavaClassPathTest {
public Object[][] moduleAndClassPath() {
return new Object[][]{
// true indicates that class path default to current working directory
{ "", false },
{ "-Djava.class.path", false },
{ "-Djava.class.path=", false },
{ "-Djava.class.path=.", true },
{ "", "" },
{ "-Djava.class.path", "" },
{ "-Djava.class.path=", "" },
};
}
@Test(dataProvider = "moduleAndClassPath")
public void testNamedModule(String option, boolean expected) throws Throwable {
public void testNamedModule(String option, String expected) throws Throwable {
List<String> args = new ArrayList<>();
if (!option.isEmpty()) {
args.add(option);
@ -112,7 +135,61 @@ public class JavaClassPathTest {
args.add(MODS_DIR.toString());
args.add("-m");
args.add(TEST_MODULE + "/" + TEST_MAIN);
args.add(Boolean.toString(expected));
// not default to CWD
args.add(Boolean.toString(false));
args.add(expected);
assertTrue(execute(args).getExitValue() == 0);
}
@Test
public void testClassPath() throws Throwable {
List<String> args = new ArrayList<>();
args.add("-Djava.class.path=.");
args.add("--module-path");
args.add(MODS_DIR.toString());
args.add("-m");
args.add(TEST_MODULE + "/" + TEST_MAIN);
args.add(Boolean.toString(true));
args.add(".");
assertTrue(execute(args).getExitValue() == 0);
}
@Test
public void testJAR() throws Throwable {
String jarfile = LIB_DIR.resolve("m.jar").toString();
List<String> args = new ArrayList<>();
args.add("-jar");
args.add(jarfile);
args.add(Boolean.toString(false));
args.add(jarfile);
assertTrue(execute(args).getExitValue() == 0);
}
/*
* Test CLASS-PATH attribute in manifest
*/
@Test
public void testClassPathAttribute() throws Throwable {
String jarfile = LIB_DIR.resolve("m1.jar").toString();
List<String> args = new ArrayList<>();
args.add("-jar");
args.add(jarfile);
args.add(Boolean.toString(false));
args.add(jarfile);
assertTrue(execute(args).getExitValue() == 0);
args.clear();
args.add("-cp");
args.add(jarfile);
args.add(TEST_MAIN);
args.add(Boolean.toString(false));
args.add(jarfile);
assertTrue(execute(args).getExitValue() == 0);
}

View File

@ -29,13 +29,14 @@ public class Main {
static final String JAVA_CLASS_PATH = "java.class.path";
public static void main(String[] args) throws Exception {
boolean expected = args[0].equals("true");
String cpath = args.length > 1 ? args[1] : "";
String value = System.getProperty(JAVA_CLASS_PATH);
if (value == null) {
throw new RuntimeException(JAVA_CLASS_PATH + " is expected non-null" +
" for compatibility");
if (!value.equals(cpath)) {
throw new RuntimeException(JAVA_CLASS_PATH + "=" + value +
" expected=" + cpath);
}
boolean expected = args[0].equals("true");
ClassLoader loader = ClassLoader.getSystemClassLoader();
URL url = loader.getResource("jdk/test/res.properties");
if ((expected && url == null) || (!expected && url != null)) {