8153654: Update jdeps to be multi-release jar aware
Reviewed-by: mchung
This commit is contained in:
parent
87803ca0e8
commit
18b1c7cd8b
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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\
|
||||
|
274
langtools/test/tools/jdeps/MultiReleaseJar.java
Normal file
274
langtools/test/tools/jdeps/MultiReleaseJar.java
Normal 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();
|
||||
}
|
||||
}
|
40
langtools/test/tools/jdeps/mrjar/10/test/Version.java
Normal file
40
langtools/test/tools/jdeps/mrjar/10/test/Version.java
Normal 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();
|
||||
}
|
||||
}
|
30
langtools/test/tools/jdeps/mrjar/9/test/NonPublic.java
Normal file
30
langtools/test/tools/jdeps/mrjar/9/test/NonPublic.java
Normal 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";
|
||||
}
|
||||
}
|
36
langtools/test/tools/jdeps/mrjar/9/test/Version.java
Normal file
36
langtools/test/tools/jdeps/mrjar/9/test/Version.java
Normal 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();
|
||||
}
|
||||
}
|
28
langtools/test/tools/jdeps/mrjar/base/p/Foo.java
Normal file
28
langtools/test/tools/jdeps/mrjar/base/p/Foo.java
Normal 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 {
|
||||
}
|
34
langtools/test/tools/jdeps/mrjar/base/test/Version.java
Normal file
34
langtools/test/tools/jdeps/mrjar/base/test/Version.java
Normal 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();
|
||||
}
|
||||
}
|
35
langtools/test/tools/jdeps/mrjar/test/Main.java
Normal file
35
langtools/test/tools/jdeps/mrjar/test/Main.java
Normal 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();
|
||||
}
|
||||
}
|
29
langtools/test/tools/jdeps/mrjar/v10/q/Bar.java
Normal file
29
langtools/test/tools/jdeps/mrjar/v10/q/Bar.java
Normal 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();
|
||||
}
|
28
langtools/test/tools/jdeps/mrjar/v10/q/Gee.java
Normal file
28
langtools/test/tools/jdeps/mrjar/v10/q/Gee.java
Normal 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 {
|
||||
}
|
31
langtools/test/tools/jdeps/mrjar/v9/p/Foo.java
Normal file
31
langtools/test/tools/jdeps/mrjar/v9/p/Foo.java
Normal 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();
|
||||
}
|
||||
}
|
28
langtools/test/tools/jdeps/mrjar/v9/q/Bar.java
Normal file
28
langtools/test/tools/jdeps/mrjar/v9/q/Bar.java
Normal 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 {
|
||||
}
|
Loading…
Reference in New Issue
Block a user