8080608: Missing archive name from jdeps -v -e output if no dependency on other JAR
Reviewed-by: mchung
This commit is contained in:
parent
7a711fe858
commit
e39d4f074f
@ -33,6 +33,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.sun.tools.classfile.Dependency.Location;
|
||||
|
||||
@ -137,8 +138,16 @@ public class Analyzer {
|
||||
public void visitDependences(Archive source, Visitor v, Type level) {
|
||||
if (level == Type.SUMMARY) {
|
||||
final ArchiveDeps result = results.get(source);
|
||||
result.requires().stream()
|
||||
.sorted(Comparator.comparing(Archive::getName))
|
||||
final Set<Archive> reqs = result.requires();
|
||||
Stream<Archive> stream = reqs.stream();
|
||||
if (reqs.isEmpty()) {
|
||||
if (hasDependences(source)) {
|
||||
// If reqs.isEmpty() and we have dependences, then it means
|
||||
// that the dependences are from 'source' onto itself.
|
||||
stream = Stream.of(source);
|
||||
}
|
||||
}
|
||||
stream.sorted(Comparator.comparing(Archive::getName))
|
||||
.forEach(archive -> {
|
||||
Profile profile = result.getTargetProfile(archive);
|
||||
v.visitDependence(source.getName(), source,
|
||||
|
@ -0,0 +1,496 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8080608
|
||||
* @summary Test that jdeps verbose output has a summary line when dependencies
|
||||
* are found within the same archive. For each testcase, compare the
|
||||
* result obtained from jdeps with the expected result.
|
||||
* @modules jdk.dev/com.sun.tools.jdeps
|
||||
* @build use.indirect.DontUseUnsafe2
|
||||
* @build use.indirect.UseUnsafeIndirectly
|
||||
* @build use.indirect2.DontUseUnsafe3
|
||||
* @build use.indirect2.UseUnsafeIndirectly2
|
||||
* @build use.unsafe.DontUseUnsafe
|
||||
* @build use.unsafe.UseClassWithUnsafe
|
||||
* @build use.unsafe.UseUnsafeClass
|
||||
* @build use.unsafe.UseUnsafeClass2
|
||||
* @run main JdepsDependencyClosure --test:0
|
||||
* @run main JdepsDependencyClosure --test:1
|
||||
* @run main JdepsDependencyClosure --test:2
|
||||
* @run main JdepsDependencyClosure --test:3
|
||||
*/
|
||||
public class JdepsDependencyClosure {
|
||||
|
||||
static boolean VERBOSE = false;
|
||||
static boolean COMPARE_TEXT = true;
|
||||
|
||||
static final String JDEPS_SUMMARY_TEXT_FORMAT = "%s -> %s%n";
|
||||
static final String JDEPS_VERBOSE_TEXT_FORMAT = " %-50s -> %-50s %s%n";
|
||||
|
||||
/**
|
||||
* Helper class used to store arguments to pass to
|
||||
* {@code JdepsDependencyClosure.test} as well as expected
|
||||
* results.
|
||||
*/
|
||||
static class TestCaseData {
|
||||
final Map<String, Set<String>> expectedDependencies;
|
||||
final String expectedText;
|
||||
final String[] args;
|
||||
final boolean closure;
|
||||
|
||||
TestCaseData(Map<String, Set<String>> expectedDependencies,
|
||||
String expectedText,
|
||||
boolean closure,
|
||||
String[] args) {
|
||||
this.expectedDependencies = expectedDependencies;
|
||||
this.expectedText = expectedText;
|
||||
this.closure = closure;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public void test() {
|
||||
if (expectedDependencies != null) {
|
||||
String format = closure
|
||||
? "Running (closure): jdeps %s %s %s %s"
|
||||
: "Running: jdeps %s %s %s %s";
|
||||
System.out.println(String.format(format, (Object[])args));
|
||||
}
|
||||
JdepsDependencyClosure.test(args, expectedDependencies, expectedText, closure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a new test case data to invoke jdeps and test its output.
|
||||
* @param pattern The pattern that will passed through to jdeps -e
|
||||
* This is expected to match only one class.
|
||||
* @param arcPath The archive to analyze. A jar or a class directory.
|
||||
* @param classes For each reported archive dependency couple, the
|
||||
* expected list of classes in the source that will
|
||||
* be reported as having a dependency on the class
|
||||
* in the target that matches the given pattern.
|
||||
* @param dependencies For each archive dependency couple, a singleton list
|
||||
* containing the name of the class in the target that
|
||||
* matches the pattern. It is expected that the pattern
|
||||
* will match only one class in the target.
|
||||
* If the pattern matches several classes the
|
||||
* expected text may no longer match the jdeps output.
|
||||
* @param archives A list of archive dependency couple in the form
|
||||
* {{sourceName1, sourcePath1, targetDescription1, targetPath1}
|
||||
* {sourceName2, sourcePath2, targetDescription2, targetPath2}
|
||||
* ... }
|
||||
* For a JDK module - e.g. java.base, the targetDescription
|
||||
* is usually something like "JDK internal API (java.base)"
|
||||
* and the targetPath is usually the module name "java.base".
|
||||
* @param closure Whether jdeps should be recursively invoked to build
|
||||
* the closure.
|
||||
* @return An instance of TestCaseData containing all the information
|
||||
* needed to perform the jdeps invokation and test its output.
|
||||
*/
|
||||
public static TestCaseData make(String pattern, String arcPath, String[][] classes,
|
||||
String[][] dependencies, String[][] archives, boolean closure) {
|
||||
final String[] args = new String[] {
|
||||
"-e", pattern, "-v", arcPath
|
||||
};
|
||||
Map<String, Set<String>> expected = new HashMap<>();
|
||||
String expectedText = "";
|
||||
for (int i=0; i<classes.length; i++) {
|
||||
final int index = i;
|
||||
expectedText += Stream.of(classes[i])
|
||||
.map((cn) -> String.format(JDEPS_VERBOSE_TEXT_FORMAT, cn,
|
||||
dependencies[index][0], archives[index][2]))
|
||||
.reduce(String.format(JDEPS_SUMMARY_TEXT_FORMAT, archives[i][0],
|
||||
archives[index][3]), (s1,s2) -> s1.concat(s2));
|
||||
for (String cn : classes[index]) {
|
||||
expected.putIfAbsent(cn, new HashSet<>());
|
||||
expected.get(cn).add(dependencies[index][0]);
|
||||
}
|
||||
}
|
||||
return new TestCaseData(expected, expectedText, closure, args);
|
||||
}
|
||||
|
||||
public static TestCaseData valueOf(String[] args) {
|
||||
if (args.length == 1 && args[0].startsWith("--test:")) {
|
||||
// invoked from jtreg. build test case data for selected test.
|
||||
int index = Integer.parseInt(args[0].substring("--test:".length()));
|
||||
if (index >= dataSuppliers.size()) {
|
||||
throw new RuntimeException("No such test case: " + index
|
||||
+ " - available testcases are [0.."
|
||||
+ (dataSuppliers.size()-1) + "]");
|
||||
}
|
||||
return dataSuppliers.get(index).get();
|
||||
} else {
|
||||
// invoked in standalone. just take the given argument
|
||||
// and perform no validation on the output (except that it
|
||||
// must start with a summary line)
|
||||
return new TestCaseData(null, null, true, args);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static TestCaseData makeTestCaseOne() {
|
||||
final String arcPath = System.getProperty("test.classes", "build/classes");
|
||||
final String arcName = Paths.get(arcPath).getFileName().toString();
|
||||
final String[][] classes = new String[][] {
|
||||
{"use.indirect2.UseUnsafeIndirectly2", "use.unsafe.UseClassWithUnsafe"},
|
||||
};
|
||||
final String[][] dependencies = new String[][] {
|
||||
{"use.unsafe.UseUnsafeClass"},
|
||||
};
|
||||
final String[][] archives = new String[][] {
|
||||
{arcName, arcPath, arcName, arcPath},
|
||||
};
|
||||
return TestCaseData.make("use.unsafe.UseUnsafeClass", arcPath, classes,
|
||||
dependencies, archives, false);
|
||||
}
|
||||
|
||||
static TestCaseData makeTestCaseTwo() {
|
||||
String arcPath = System.getProperty("test.classes", "build/classes");
|
||||
String arcName = Paths.get(arcPath).getFileName().toString();
|
||||
String[][] classes = new String[][] {
|
||||
{"use.unsafe.UseUnsafeClass", "use.unsafe.UseUnsafeClass2"}
|
||||
};
|
||||
String[][] dependencies = new String[][] {
|
||||
{"sun.misc.Unsafe"}
|
||||
};
|
||||
String[][] archive = new String[][] {
|
||||
{arcName, arcPath, "JDK internal API (java.base)", "java.base"},
|
||||
};
|
||||
return TestCaseData.make("sun.misc.Unsafe", arcPath, classes,
|
||||
dependencies, archive, false);
|
||||
}
|
||||
|
||||
static TestCaseData makeTestCaseThree() {
|
||||
final String arcPath = System.getProperty("test.classes", "build/classes");
|
||||
final String arcName = Paths.get(arcPath).getFileName().toString();
|
||||
final String[][] classes = new String[][] {
|
||||
{"use.indirect2.UseUnsafeIndirectly2", "use.unsafe.UseClassWithUnsafe"},
|
||||
{"use.indirect.UseUnsafeIndirectly"}
|
||||
};
|
||||
final String[][] dependencies = new String[][] {
|
||||
{"use.unsafe.UseUnsafeClass"},
|
||||
{"use.unsafe.UseClassWithUnsafe"}
|
||||
};
|
||||
final String[][] archives = new String[][] {
|
||||
{arcName, arcPath, arcName, arcPath},
|
||||
{arcName, arcPath, arcName, arcPath}
|
||||
};
|
||||
return TestCaseData.make("use.unsafe.UseUnsafeClass", arcPath, classes,
|
||||
dependencies, archives, true);
|
||||
}
|
||||
|
||||
|
||||
static TestCaseData makeTestCaseFour() {
|
||||
final String arcPath = System.getProperty("test.classes", "build/classes");
|
||||
final String arcName = Paths.get(arcPath).getFileName().toString();
|
||||
final String[][] classes = new String[][] {
|
||||
{"use.unsafe.UseUnsafeClass", "use.unsafe.UseUnsafeClass2"},
|
||||
{"use.indirect2.UseUnsafeIndirectly2", "use.unsafe.UseClassWithUnsafe"},
|
||||
{"use.indirect.UseUnsafeIndirectly"}
|
||||
};
|
||||
final String[][] dependencies = new String[][] {
|
||||
{"sun.misc.Unsafe"},
|
||||
{"use.unsafe.UseUnsafeClass"},
|
||||
{"use.unsafe.UseClassWithUnsafe"}
|
||||
};
|
||||
final String[][] archives = new String[][] {
|
||||
{arcName, arcPath, "JDK internal API (java.base)", "java.base"},
|
||||
{arcName, arcPath, arcName, arcPath},
|
||||
{arcName, arcPath, arcName, arcPath}
|
||||
};
|
||||
return TestCaseData.make("sun.misc.Unsafe", arcPath, classes, dependencies,
|
||||
archives, true);
|
||||
}
|
||||
|
||||
static final List<Supplier<TestCaseData>> dataSuppliers = Arrays.asList(
|
||||
JdepsDependencyClosure::makeTestCaseOne,
|
||||
JdepsDependencyClosure::makeTestCaseTwo,
|
||||
JdepsDependencyClosure::makeTestCaseThree,
|
||||
JdepsDependencyClosure::makeTestCaseFour
|
||||
);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The OutputStreamParser is used to parse the format of jdeps.
|
||||
* It is thus dependent on that format.
|
||||
*/
|
||||
static class OutputStreamParser extends OutputStream {
|
||||
// OutputStreamParser will populate this map:
|
||||
//
|
||||
// For each archive, a list of class in where dependencies where
|
||||
// found...
|
||||
final Map<String, Set<String>> deps;
|
||||
final StringBuilder text = new StringBuilder();
|
||||
|
||||
StringBuilder[] lines = { new StringBuilder(), new StringBuilder() };
|
||||
int line = 0;
|
||||
int sepi = 0;
|
||||
char[] sep;
|
||||
|
||||
public OutputStreamParser(Map<String, Set<String>> deps) {
|
||||
this.deps = deps;
|
||||
this.sep = System.getProperty("line.separator").toCharArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
lines[line].append((char)b);
|
||||
if (b == sep[sepi]) {
|
||||
if (++sepi == sep.length) {
|
||||
text.append(lines[line]);
|
||||
if (lines[0].toString().startsWith(" ")) {
|
||||
throw new RuntimeException("Bad formatting: "
|
||||
+ "summary line missing for\n"+lines[0]);
|
||||
}
|
||||
// Usually the output looks like that:
|
||||
// <archive-1> -> java.base
|
||||
// <class-1> -> <dependency> <dependency description>
|
||||
// <class-2> -> <dependency> <dependency description>
|
||||
// ...
|
||||
// <archive-2> -> java.base
|
||||
// <class-3> -> <dependency> <dependency description>
|
||||
// <class-4> -> <dependency> <dependency description>
|
||||
// ...
|
||||
//
|
||||
// We want to keep the <archive> line in lines[0]
|
||||
// and have the ith <class-i> line in lines[1]
|
||||
if (line == 1) {
|
||||
// we have either a <class> line or an <archive> line.
|
||||
String line1 = lines[0].toString();
|
||||
String line2 = lines[1].toString();
|
||||
if (line2.startsWith(" ")) {
|
||||
// we have a class line, record it.
|
||||
parse(line1, line2);
|
||||
// prepare for next <class> line.
|
||||
lines[1] = new StringBuilder();
|
||||
} else {
|
||||
// We have an archive line: We are switching to the next archive.
|
||||
// put the new <archive> line in lines[0], and prepare
|
||||
// for reading the next <class> line
|
||||
lines[0] = lines[1];
|
||||
lines[1] = new StringBuilder();
|
||||
}
|
||||
} else {
|
||||
// we just read the first <archive> line.
|
||||
// prepare to read <class> lines.
|
||||
line = 1;
|
||||
}
|
||||
sepi = 0;
|
||||
}
|
||||
} else {
|
||||
sepi = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Takes a couple of lines, where line1 is an <archive> line and
|
||||
// line 2 is a <class> line. Parses the line to extract the archive
|
||||
// name and dependent class name, and record them in the map...
|
||||
void parse(String line1, String line2) {
|
||||
String archive = line1.substring(0, line1.indexOf(" -> "));
|
||||
int l2ArrowIndex = line2.indexOf(" -> ");
|
||||
String className = line2.substring(2, l2ArrowIndex).replace(" ", "");
|
||||
String depdescr = line2.substring(l2ArrowIndex + 4);
|
||||
String depclass = depdescr.substring(0, depdescr.indexOf(" "));
|
||||
deps.computeIfAbsent(archive, (k) -> new HashSet<>());
|
||||
deps.get(archive).add(className);
|
||||
if (VERBOSE) {
|
||||
System.out.println(archive+": "+className+" depends on "+depclass);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The main method.
|
||||
*
|
||||
* Can be run in two modes:
|
||||
* <ul>
|
||||
* <li>From jtreg: expects 1 argument in the form {@code --test:<test-nb>}</li>
|
||||
* <li>From command line: expected syntax is {@code -e <pattern> -v jar [jars..]}</li>
|
||||
* </ul>
|
||||
* <p>When called from the command line this method will call jdeps recursively
|
||||
* to build a closure of the dependencies on {@code <pattern>} and print a summary.
|
||||
* <p>When called from jtreg - it will call jdeps either once only or
|
||||
* recursively depending on the pattern.
|
||||
* @param args either {@code --test:<test-nb>} or {@code -e <pattern> -v jar [jars..]}.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
runWithLocale(Locale.ENGLISH, TestCaseData.valueOf(args)::test);
|
||||
}
|
||||
|
||||
private static void runWithLocale(Locale loc, Runnable run) {
|
||||
final Locale defaultLocale = Locale.getDefault();
|
||||
Locale.setDefault(loc);
|
||||
try {
|
||||
run.run();
|
||||
} finally {
|
||||
Locale.setDefault(defaultLocale);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void test(String[] args, Map<String, Set<String>> expected,
|
||||
String expectedText, boolean closure) {
|
||||
try {
|
||||
doTest(args, expected, expectedText, closure);
|
||||
} catch (Throwable t) {
|
||||
try {
|
||||
printDiagnostic(args, expectedText, t, closure);
|
||||
} catch(Throwable tt) {
|
||||
throw t;
|
||||
}
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
|
||||
static class TextFormatException extends RuntimeException {
|
||||
final String expected;
|
||||
final String actual;
|
||||
TextFormatException(String message, String expected, String actual) {
|
||||
super(message);
|
||||
this.expected = expected;
|
||||
this.actual = actual;
|
||||
}
|
||||
}
|
||||
|
||||
public static void printDiagnostic(String[] args, String expectedText,
|
||||
Throwable t, boolean closure) {
|
||||
if (expectedText != null || t instanceof TextFormatException) {
|
||||
System.err.println("===== TEST FAILED =======");
|
||||
System.err.println("command: " + Stream.of(args)
|
||||
.reduce("jdeps", (s1,s2) -> s1.concat(" ").concat(s2)));
|
||||
System.err.println("===== Expected Output =======");
|
||||
System.err.append(expectedText);
|
||||
System.err.println("===== Command Output =======");
|
||||
if (t instanceof TextFormatException) {
|
||||
System.err.print(((TextFormatException)t).actual);
|
||||
} else {
|
||||
com.sun.tools.jdeps.Main.run(args, new PrintWriter(System.err));
|
||||
if (closure) System.err.println("... (closure not available) ...");
|
||||
}
|
||||
System.err.println("=============================");
|
||||
}
|
||||
}
|
||||
|
||||
public static void doTest(String[] args, Map<String, Set<String>> expected,
|
||||
String expectedText, boolean closure) {
|
||||
if (args.length < 3 || !"-e".equals(args[0]) || !"-v".equals(args[2])) {
|
||||
System.err.println("Syntax: -e <classname> -v [list of jars or directories]");
|
||||
return;
|
||||
}
|
||||
Map<String, Map<String, Set<String>>> alldeps = new HashMap<>();
|
||||
String depName = args[1];
|
||||
List<String> search = new ArrayList<>();
|
||||
search.add(depName);
|
||||
Set<String> searched = new LinkedHashSet<>();
|
||||
StringBuilder text = new StringBuilder();
|
||||
while(!search.isEmpty()) {
|
||||
args[1] = search.remove(0);
|
||||
if (VERBOSE) {
|
||||
System.out.println("Looking for " + args[1]);
|
||||
}
|
||||
searched.add(args[1]);
|
||||
Map<String, Set<String>> deps =
|
||||
alldeps.computeIfAbsent(args[1], (k) -> new HashMap<>());
|
||||
OutputStreamParser parser = new OutputStreamParser(deps);
|
||||
PrintWriter writer = new PrintWriter(parser);
|
||||
com.sun.tools.jdeps.Main.run(args, writer);
|
||||
if (VERBOSE) {
|
||||
System.out.println("Found: " + deps.values().stream()
|
||||
.flatMap(s -> s.stream()).collect(Collectors.toSet()));
|
||||
}
|
||||
if (expectedText != null) {
|
||||
text.append(parser.text.toString());
|
||||
}
|
||||
search.addAll(deps.values().stream()
|
||||
.flatMap(s -> s.stream())
|
||||
.filter(k -> !searched.contains(k))
|
||||
.collect(Collectors.toSet()));
|
||||
if (!closure) break;
|
||||
}
|
||||
|
||||
// Print summary...
|
||||
final Set<String> classes = alldeps.values().stream()
|
||||
.flatMap((m) -> m.values().stream())
|
||||
.flatMap(s -> s.stream()).collect(Collectors.toSet());
|
||||
Map<String, Set<String>> result = new HashMap<>();
|
||||
for (String c : classes) {
|
||||
Set<String> archives = new HashSet<>();
|
||||
Set<String> dependencies = new HashSet<>();
|
||||
for (String d : alldeps.keySet()) {
|
||||
Map<String, Set<String>> m = alldeps.get(d);
|
||||
for (String a : m.keySet()) {
|
||||
Set<String> s = m.get(a);
|
||||
if (s.contains(c)) {
|
||||
archives.add(a);
|
||||
dependencies.add(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
result.put(c, dependencies);
|
||||
System.out.println(c + " " + archives + " depends on " + dependencies);
|
||||
}
|
||||
|
||||
// If we're in jtreg, then check result (expectedText != null)
|
||||
if (expectedText != null && COMPARE_TEXT) {
|
||||
//text.append(String.format("%n"));
|
||||
if (text.toString().equals(expectedText)) {
|
||||
System.out.println("SUCCESS - got expected text");
|
||||
} else {
|
||||
throw new TextFormatException("jdeps output is not as expected",
|
||||
expectedText, text.toString());
|
||||
}
|
||||
}
|
||||
if (expected != null) {
|
||||
if (expected.equals(result)) {
|
||||
System.out.println("SUCCESS - found expected dependencies");
|
||||
} else if (expectedText == null) {
|
||||
throw new RuntimeException("Bad dependencies: Expected " + expected
|
||||
+ " but found " + result);
|
||||
} else {
|
||||
throw new TextFormatException("Bad dependencies: Expected "
|
||||
+ expected
|
||||
+ " but found " + result,
|
||||
expectedText, text.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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 use.indirect;
|
||||
|
||||
import use.unsafe.*;
|
||||
|
||||
public class DontUseUnsafe2 {
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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 use.indirect;
|
||||
|
||||
import use.unsafe.UseClassWithUnsafe;
|
||||
|
||||
public class UseUnsafeIndirectly {
|
||||
static UseClassWithUnsafe use = new UseClassWithUnsafe();
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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 use.indirect2;
|
||||
|
||||
import use.unsafe.*;
|
||||
|
||||
public class DontUseUnsafe3 {
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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 use.indirect2;
|
||||
|
||||
import use.unsafe.UseUnsafeClass;
|
||||
|
||||
public class UseUnsafeIndirectly2 {
|
||||
static UseUnsafeClass use = new UseUnsafeClass();
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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 use.unsafe;
|
||||
|
||||
public class DontUseUnsafe {
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package use.unsafe;
|
||||
|
||||
public class UseClassWithUnsafe {
|
||||
|
||||
static UseUnsafeClass use = new UseUnsafeClass();
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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 use.unsafe;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
public class UseUnsafeClass {
|
||||
static Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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 use.unsafe;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
public class UseUnsafeClass2 {
|
||||
static Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user