8153654: Update jdeps to be multi-release jar aware

Reviewed-by: mchung
This commit is contained in:
Steve Drach 2016-09-26 13:39:50 -07:00
parent 87803ca0e8
commit 18b1c7cd8b
19 changed files with 854 additions and 30 deletions

View File

@ -256,7 +256,7 @@ public class Analyzer {
// return classname or package name depending on the level
private String getLocationName(Location o) {
if (level == Type.CLASS || level == Type.VERBOSE) {
return o.getClassName();
return VersionHelper.get(o.getClassName());
} else {
String pkg = o.getPackageName();
return pkg.isEmpty() ? "<unnamed>" : pkg;

View File

@ -45,9 +45,9 @@ import java.util.stream.Stream;
* Represents the source of the class files.
*/
public class Archive implements Closeable {
public static Archive getInstance(Path p) {
public static Archive getInstance(Path p, Runtime.Version version) {
try {
return new Archive(p, ClassFileReader.newInstance(p));
return new Archive(p, ClassFileReader.newInstance(p, version));
} catch (IOException e) {
throw new UncheckedIOException(e);
}

View File

@ -29,6 +29,8 @@ import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Dependencies.ClassFileError;
import jdk.internal.util.jar.VersionedStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
@ -50,6 +52,7 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipFile;
/**
* ClassFileReader reads ClassFile(s) of a given path that can be
@ -60,6 +63,13 @@ public class ClassFileReader implements Closeable {
* Returns a ClassFileReader instance of a given path.
*/
public static ClassFileReader newInstance(Path path) throws IOException {
return newInstance(path, JarFile.baseVersion());
}
/**
* Returns a ClassFileReader instance of a given path.
*/
public static ClassFileReader newInstance(Path path, Runtime.Version version) throws IOException {
if (Files.notExists(path)) {
throw new FileNotFoundException(path.toString());
}
@ -67,19 +77,12 @@ public class ClassFileReader implements Closeable {
if (Files.isDirectory(path)) {
return new DirectoryReader(path);
} else if (path.getFileName().toString().endsWith(".jar")) {
return new JarFileReader(path);
return new JarFileReader(path, version);
} else {
return new ClassFileReader(path);
}
}
/**
* Returns a ClassFileReader instance of a given JarFile.
*/
public static ClassFileReader newInstance(Path path, JarFile jf) throws IOException {
return new JarFileReader(path, jf);
}
/**
* Returns a ClassFileReader instance of a given FileSystem and path.
*
@ -302,13 +305,16 @@ public class ClassFileReader implements Closeable {
static class JarFileReader extends ClassFileReader {
private final JarFile jarfile;
JarFileReader(Path path) throws IOException {
this(path, new JarFile(path.toFile(), false));
private final Runtime.Version version;
JarFileReader(Path path, Runtime.Version version) throws IOException {
this(path, openJarFile(path.toFile(), version), version);
}
JarFileReader(Path path, JarFile jf) throws IOException {
JarFileReader(Path path, JarFile jf, Runtime.Version version) throws IOException {
super(path);
this.jarfile = jf;
this.version = version;
}
@Override
@ -316,9 +322,26 @@ public class ClassFileReader implements Closeable {
jarfile.close();
}
private static JarFile openJarFile(File f, Runtime.Version version)
throws IOException {
JarFile jf;
if (version == null) {
jf = new JarFile(f, false);
if (jf.isMultiRelease()) {
throw new MultiReleaseException("err.multirelease.option.notfound", f.getName());
}
} else {
jf = new JarFile(f, false, ZipFile.OPEN_READ, version);
if (!jf.isMultiRelease()) {
throw new MultiReleaseException("err.multirelease.option.exists", f.getName());
}
}
return jf;
}
protected Set<String> scan() {
try (JarFile jf = new JarFile(path.toFile())) {
return jf.stream().map(JarEntry::getName)
try (JarFile jf = openJarFile(path.toFile(), version)) {
return VersionedStream.stream(jf).map(JarEntry::getName)
.filter(n -> n.endsWith(".class"))
.collect(Collectors.toSet());
} catch (IOException e) {
@ -348,15 +371,14 @@ public class ClassFileReader implements Closeable {
}
protected ClassFile readClassFile(JarFile jarfile, JarEntry e) throws IOException {
InputStream is = null;
try {
is = jarfile.getInputStream(e);
return ClassFile.read(is);
try (InputStream is = jarfile.getInputStream(e)) {
ClassFile cf = ClassFile.read(is);
if (jarfile.isMultiRelease()) {
VersionHelper.add(jarfile, e, cf);
}
return cf;
} catch (ConstantPoolException ex) {
throw new ClassFileError(ex);
} finally {
if (is != null)
is.close();
}
}
@ -370,6 +392,21 @@ public class ClassFileReader implements Closeable {
}
}
Enumeration<JarEntry> versionedEntries(JarFile jf) {
Iterator<JarEntry> it = VersionedStream.stream(jf).iterator();
return new Enumeration<>() {
@Override
public boolean hasMoreElements() {
return it.hasNext();
}
@Override
public JarEntry nextElement() {
return it.next();
}
};
}
class JarFileIterator implements Iterator<ClassFile> {
protected final JarFileReader reader;
protected Enumeration<JarEntry> entries;
@ -388,7 +425,7 @@ public class ClassFileReader implements Closeable {
if (jarfile == null) return;
this.jf = jarfile;
this.entries = jf.entries();
this.entries = versionedEntries(jf);
this.nextEntry = nextEntry();
}

View File

@ -81,19 +81,22 @@ public class JdepsConfiguration implements AutoCloseable {
private final List<Archive> initialArchives = new ArrayList<>();
private final Set<Module> rootModules = new HashSet<>();
private final Configuration configuration;
private final Runtime.Version version;
private JdepsConfiguration(SystemModuleFinder systemModulePath,
ModuleFinder finder,
Set<String> roots,
List<Path> classpaths,
List<Archive> initialArchives,
boolean allDefaultModules)
boolean allDefaultModules,
Runtime.Version version)
throws IOException
{
trace("root: %s%n", roots);
this.system = systemModulePath;
this.finder = finder;
this.version = version;
// build root set for resolution
Set<String> mods = new HashSet<>(roots);
@ -121,7 +124,7 @@ public class JdepsConfiguration implements AutoCloseable {
// classpath archives
for (Path p : classpaths) {
if (Files.exists(p)) {
Archive archive = Archive.getInstance(p);
Archive archive = Archive.getInstance(p, version);
addPackagesInUnnamedModule(archive);
classpathArchives.add(archive);
}
@ -292,7 +295,7 @@ public class JdepsConfiguration implements AutoCloseable {
if (location.getScheme().equals("jrt")) {
reader = system.getClassReader(mn);
} else {
reader = ClassFileReader.newInstance(Paths.get(location));
reader = ClassFileReader.newInstance(Paths.get(location), version);
}
builder.classes(reader);
@ -304,6 +307,10 @@ public class JdepsConfiguration implements AutoCloseable {
}
}
public Runtime.Version getVersion() {
return version;
}
/*
* Close all archives e.g. JarFile
*/
@ -476,6 +483,7 @@ public class JdepsConfiguration implements AutoCloseable {
ModuleFinder appModulePath;
boolean addAllApplicationModules;
boolean addAllDefaultModules;
Runtime.Version version;
public Builder() {
this.systemModulePath = new SystemModuleFinder();
@ -526,8 +534,13 @@ public class JdepsConfiguration implements AutoCloseable {
return this;
}
public Builder multiRelease(Runtime.Version version) {
this.version = version;
return this;
}
public Builder addRoot(Path path) {
Archive archive = Archive.getInstance(path);
Archive archive = Archive.getInstance(path, version);
if (archive.contains(MODULE_INFO)) {
paths.add(path);
} else {
@ -569,7 +582,8 @@ public class JdepsConfiguration implements AutoCloseable {
rootModules,
classPaths,
initialArchives,
addAllDefaultModules);
addAllDefaultModules,
version);
}
private static ModuleFinder createModulePathFinder(String mpaths) {

View File

@ -36,6 +36,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.MessageFormat;
import java.util.*;
import java.util.jar.JarFile;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -389,6 +390,23 @@ class JdepsTask {
}
}
},
new Option(true, "--multi-release") {
void process(JdepsTask task, String opt, String arg) throws BadArgs {
if (arg.equalsIgnoreCase("base")) {
task.options.multiRelease = JarFile.baseVersion();
} else {
try {
int v = Integer.parseInt(arg);
if (v < 9) {
throw new BadArgs("err.invalid.arg.for.option", arg);
}
} catch (NumberFormatException x) {
throw new BadArgs("err.invalid.arg.for.option", arg);
}
task.options.multiRelease = Runtime.Version.parse(arg);
}
}
},
};
private static final String PROGNAME = "jdeps";
@ -481,6 +499,9 @@ class JdepsTask {
} catch (IOException e) {
e.printStackTrace();
return EXIT_CMDERR;
} catch (MultiReleaseException e) {
reportError(e.getKey(), (Object)e.getMsg());
return EXIT_CMDERR; // could be EXIT_ABNORMAL sometimes
} finally {
log.flush();
}
@ -541,11 +562,16 @@ class JdepsTask {
if (options.classpath != null)
builder.addClassPath(options.classpath);
if (options.multiRelease != null)
builder.multiRelease(options.multiRelease);
// build the root set of archives to be analyzed
for (String s : inputArgs) {
Path p = Paths.get(s);
if (Files.exists(p)) {
builder.addRoot(p);
} else {
warning("warn.invalid.arg", s);
}
}
@ -839,6 +865,7 @@ class JdepsTask {
String modulePath;
String rootModule;
Set<String> addmods = new HashSet<>();
Runtime.Version multiRelease;
boolean hasFilter() {
return numFilters() > 0;

View File

@ -0,0 +1,69 @@
/*
* 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. 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.
*/
package com.sun.tools.jdeps;
/**
* Signals that an exception of some sort has occurred while processing
* a multi-release jar file.
*
* @since 9
*/
class MultiReleaseException extends RuntimeException {
private static final long serialVersionUID = 4474870142461654108L;
private final String key;
private final String[] msg;
/**
* Constructs an {@code MultiReleaseException} with the specified detail
* error message array.
*
* @param key
* The key that identifies the message in the jdeps.properties file
* @param msg
* The detail message array
*/
public MultiReleaseException(String key, String... msg) {
super();
this.key = key;
this.msg = msg;
}
/**
* Returns the resource message key
*/
public String getKey() {
return key;
}
/**
* Returns the detailed error message array.
*
* @return the detailed error message array
*/
public String[] getMsg() {
return msg;
}
}

View File

@ -0,0 +1,75 @@
/*
* 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. 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.
*/
package com.sun.tools.jdeps;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ConstantPoolException;
import jdk.internal.misc.SharedSecrets;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class VersionHelper {
private static final String META_INF_VERSIONS = "META-INF/versions/";
private static final Map<String,String> nameToVersion = new ConcurrentHashMap<>();
public static String get(String classname) {
if (nameToVersion.containsKey(classname)) {
return nameToVersion.get(classname) + "/" + classname;
}
return classname;
}
public static void add(JarFile jarfile, JarEntry e, ClassFile cf)
throws ConstantPoolException
{
String realName = SharedSecrets.javaUtilJarAccess().getRealName(jarfile, e);
if (realName.startsWith(META_INF_VERSIONS)) {
int len = META_INF_VERSIONS.length();
int n = realName.indexOf('/', len);
if (n > 0) {
String version = realName.substring(len, n);
assert (Integer.parseInt(version) > 8);
String name = cf.getName().replace('/', '.');
if (nameToVersion.containsKey(name)) {
if (!version.equals(nameToVersion.get(name))) {
throw new MultiReleaseException(
"err.multirelease.version.associated",
name, nameToVersion.get(name), version
);
}
} else {
nameToVersion.put(name, version);
}
} else {
throw new MultiReleaseException("err.multirelease.jar.malformed",
jarfile.getName(), realName);
}
}
}
}

View File

@ -150,6 +150,11 @@ main.opt.q=\
\ -q -quiet Do not show missing dependencies from \n\
\ -genmoduleinfo output.
main.opt.multi-release=\
\ --multi-release <version> Specifies the version when processing\n\
\ multi-release jar files. <version> should\n\
\ be integer >= 9 or base.
err.unknown.option=unknown option: {0}
err.missing.arg=no value given for {0}
err.invalid.arg.for.option=invalid argument for option: {0}
@ -164,7 +169,11 @@ err.module.not.found=module not found: {0}
err.root.module.not.set=root module set empty
err.invalid.inverse.option={0} cannot be used with -inverse option
err.inverse.filter.not.set={0} cannot be used with -inverse option
warn.invalid.arg=Path not exist: {0}
err.multirelease.option.exists={0} is not a multi-release jar file, but the --multi-release option is set
err.multirelease.option.notfound={0} is a multi-release jar file, but the --multi-release option is not set
err.multirelease.version.associated=class {0} already associated with version {1}, trying to add version {2}
err.multirelease.jar.malformed=malformed multi-release jar, {0}, bad entry: {1}
warn.invalid.arg=Path does not exist: {0}
warn.split.package=package {0} defined in {1} {2}
warn.replace.useJDKInternals=\
JDK internal APIs are unsupported and private to JDK implementation that are\n\

View File

@ -0,0 +1,274 @@
/*
* 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 8153654
* @summary Tests for jdeps tool with multi-release jar files
* @modules jdk.jdeps/com.sun.tools.jdeps
* @library mrjar mrjar/base mrjar/9 mrjar/10 mrjar/v9 mrjar/v10
* @build test.* p.* q.*
* @run testng MultiReleaseJar
*/
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
public class MultiReleaseJar {
Path mrjar;
String testJdk;
String fileSep;
Path cmdPath;
@BeforeClass
public void initialize() throws Exception {
mrjar = Paths.get(System.getProperty("test.classes", "."), "mrjar");
testJdk = System.getProperty("test.jdk");
fileSep = System.getProperty("file.separator");
cmdPath = Paths.get(testJdk, "bin");
}
@Test
public void basic() throws Exception {
// build the jar file
Result r = run("jar -cf Version.jar -C base test --release 9 -C 9 test --release 10 -C 10 test");
checkResult(r);
// try out a bunch of things
r = run("jdeps --multi-release 9 -v missing.jar");
checkResult(r, false, "Warning: Path does not exist: missing.jar");
r = run("jdeps -v Version.jar");
checkResult(r, false, "the --multi-release option is not set");
r = run("jdeps --multi-release base -v Version.jar");
checkResult(r, true,
"Version.jar ->",
"test.Version",
"test.Version"
);
r = run("jdeps --multi-release 9 -v Version.jar");
checkResult(r, true,
"Version.jar ->",
"9/test.NonPublic",
"9/test.NonPublic",
"9/test.Version",
"9/test.Version",
"9/test.Version",
"9/test.Version"
);
r = run("jdeps --multi-release 10 -v Version.jar");
checkResult(r, true,
"Version.jar ->",
"10/test.Version",
"10/test.Version",
"10/test.Version",
"10/test.Version",
"9/test.NonPublic",
"9/test.NonPublic"
);
r = run("jdeps --multi-release 8 -v Version.jar");
checkResult(r, false, "Error: invalid argument for option: 8");
r = run("jdeps --multi-release 9.1 -v Version.jar");
checkResult(r, false, "Error: invalid argument for option: 9.1");
r = run("jdeps -v -R -cp Version.jar test/Main.class");
checkResult(r, false, "the --multi-release option is not set");
r = run("jdeps -v -R -cp Version.jar -multi-release 9 test/Main.class");
checkResult(r, false,
"Error: unknown option: -multi-release",
"Usage: jdeps <options> <path",
"use -h, -?, -help, or --help"
);
r = run("jdeps -v -R -cp Version.jar --multi-release 9 test/Main.class");
checkResult(r, true,
"Main.class ->",
"Main.class ->",
"test.Main",
"test.Main",
"test.Main",
"Version.jar ->",
"9/test.NonPublic",
"9/test.NonPublic",
"9/test.Version",
"9/test.Version",
"9/test.Version",
"9/test.Version"
);
r = run("jdeps -v -R -cp Version.jar --multi-release 10 test/Main.class");
checkResult(r, true,
"Main.class ->",
"Main.class ->",
"test.Main",
"test.Main",
"test.Main",
"Version.jar ->",
"10/test.Version",
"10/test.Version",
"10/test.Version",
"10/test.Version",
"9/test.NonPublic",
"9/test.NonPublic"
);
r = run("jdeps -v -R -cp Version.jar --multi-release base test/Main.class");
checkResult(r, true,
"Main.class ->",
"Main.class ->",
"test.Main",
"test.Main",
"test.Main",
"Version.jar ->",
"test.Version",
"test.Version"
);
r = run("jdeps -v -R -cp Version.jar --multi-release 9.1 test/Main.class");
checkResult(r, false, "Error: invalid argument for option: 9.1");
// Rebuild jar without version 10
r = run("jar -cf Version.jar -C base test --release 9 -C 9 test");
checkResult(r);
// but ask for version 10
r = run("jdeps -v -R -cp Version.jar --multi-release 10 test/Main.class");
checkResult(r, true,
"Main.class ->",
"Main.class ->",
"test.Main",
"test.Main",
"test.Main",
"Version.jar ->",
"9/test.NonPublic",
"9/test.NonPublic",
"9/test.Version",
"9/test.Version",
"9/test.Version",
"9/test.Version"
);
}
@Test
public void ps_and_qs() throws Exception {
// build the jar file
Result r = run("jar -cf PQ.jar -C base p --release 9 -C v9 p -C v9 q --release 10 -C v10 q");
checkResult(r);
r = run("jdeps -v -R -cp PQ.jar --multi-release base PQ.jar");
checkResult(r, true,
"PQ.jar -> java.base",
"p.Foo"
);
r = run("jdeps -v -R -cp PQ.jar --multi-release 9 PQ.jar");
checkResult(r, true,
"PQ.jar -> java.base",
"9/p.Foo",
"9/p.Foo",
"9/q.Bar"
);
r = run("jdeps -v -R -cp PQ.jar --multi-release 10 PQ.jar");
checkResult(r, true,
"PQ.jar -> java.base",
"10/q.Bar",
"10/q.Bar",
"10/q.Gee",
"9/p.Foo",
"9/p.Foo"
);
}
static class Result {
final String cmd;
final int rc;
final String out;
final String err;
Result(String cmd, int rc, String out, String err) {
this.cmd = cmd;
this.rc = rc;
this.out = out;
this.err = err;
}
}
Result run(String cmd) throws Exception {
String[] cmds = cmd.split(" +");
cmds[0] = cmdPath.resolve(cmds[0]).toString();
ProcessBuilder pb = new ProcessBuilder(cmds);
pb.directory(mrjar.toFile());
Process p = pb.start();
p.waitFor(10, TimeUnit.SECONDS);
String out;
try (InputStream is = p.getInputStream()) {
out = new String(is.readAllBytes());
}
String err;
try (InputStream is = p.getErrorStream()) {
err = new String(is.readAllBytes());
}
return new Result(cmd, p.exitValue(), out, err);
}
void checkResult(Result r) throws Exception {
System.out.println(r.cmd);
System.out.println(r.out);
if (r.rc != 0) {
System.out.println(r.err);
throw new Exception("rc=" + r.rc);
}
System.out.println();
}
void checkResult(Result r, boolean checkrc, String... lines) throws Exception {
System.out.println(r.cmd);
System.out.println(r.out);
if (checkrc && r.rc != 0) {
System.out.println(r.err);
throw new Exception("rc=" + r.rc);
}
String[] out = r.out.split("\r?\n");
Assert.assertEquals(out.length, lines.length);
int n = 0;
for (String line : lines) {
Assert.assertTrue(out[n++].contains(line), "\"" + line + "\"");
}
System.out.println();
}
}

View File

@ -0,0 +1,40 @@
/*
* 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 test;
public class Version {
public int getVersion() {
NonPublic np = new NonPublic();
String ignore = np.toString();
return 10;
}
private String getStringVersion() {
return "10";
}
private void foo() {
if (getStringVersion() == null) throw new NullPointerException();
}
}

View File

@ -0,0 +1,30 @@
/*
* 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 test;
class NonPublic {
public String toString() {
return "NonPublic";
}
}

View File

@ -0,0 +1,36 @@
/*
* 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 test;
public class Version {
public int getVersion() {
NonPublic np = new NonPublic();
String ignore = np.toString();
return 9;
}
private void foo() {
if (getVersion() != 9) throw new RuntimeException();
}
}

View File

@ -0,0 +1,28 @@
/*
* 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 p;
// dependencies: Object
public class Foo {
}

View File

@ -0,0 +1,34 @@
/*
* 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 test;
public class Version {
public int getVersion() {
return 8;
}
private void foo() {
if (getVersion() != 8) throw new IllegalStateException();
}
}

View File

@ -0,0 +1,35 @@
/*
* 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 test;
public class Main {
public void run() {
Version v = new Version();
v.getVersion();
}
public static void main(String[] args) {
(new Main()).run();
}
}

View File

@ -0,0 +1,29 @@
/*
* 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 q;
// dependencies: Object, q.Gee
class Bar {
Gee gee = new Gee();
}

View File

@ -0,0 +1,28 @@
/*
* 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 q;
// dependencies: Object
class Gee {
}

View File

@ -0,0 +1,31 @@
/*
* 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 p;
// dependencies: Object, q.Bar
public class Foo {
void crash() {
throw new RuntimeException();
}
}

View File

@ -0,0 +1,28 @@
/*
* 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 q;
// dependecies: Object
class Bar {
}