8173777: Merge javac -Xmodule into javac--patch-module

Merging -Xmodule: functionality into --patch-module.

Reviewed-by: jjg, mchung, rfield
This commit is contained in:
Jan Lahoda 2017-02-13 09:37:26 +01:00
parent 0fcd98980c
commit 261ce92be5
42 changed files with 933 additions and 314 deletions

View file

@ -107,7 +107,14 @@ public enum StandardLocation implements Location {
* @spec JPMS * @spec JPMS
* @since 9 * @since 9
*/ */
MODULE_PATH; MODULE_PATH,
/**
* Location to search for module patches.
* @since 9
* @spec JPMS
*/
PATCH_MODULE_PATH;
/** /**
* Returns a location object with the given name. The following * Returns a location object with the given name. The following
@ -166,6 +173,7 @@ public enum StandardLocation implements Location {
case UPGRADE_MODULE_PATH: case UPGRADE_MODULE_PATH:
case SYSTEM_MODULES: case SYSTEM_MODULES:
case MODULE_PATH: case MODULE_PATH:
case PATCH_MODULE_PATH:
return true; return true;
default: default:
return false; return false;

View file

@ -361,7 +361,7 @@ public class ClientCodeWrapper {
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException { public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
try { try {
return clientJavaFileManager.getLocationForModule(location, fo, pkgName); return clientJavaFileManager.getLocationForModule(location, unwrap(fo), pkgName);
} catch (ClientCodeException e) { } catch (ClientCodeException e) {
throw e; throw e;
} catch (RuntimeException | Error e) { } catch (RuntimeException | Error e) {

View file

@ -553,20 +553,47 @@ public class ClassFinder {
Location classLocn = msym.classLocation; Location classLocn = msym.classLocation;
Location sourceLocn = msym.sourceLocation; Location sourceLocn = msym.sourceLocation;
Location patchLocn = msym.patchLocation;
Location patchOutLocn = msym.patchOutputLocation;
if (wantClassFiles && (classLocn != null)) { boolean prevPreferCurrent = preferCurrent;
fillIn(p, classLocn,
list(classLocn, try {
p, preferCurrent = false;
packageName, if (wantClassFiles && (patchOutLocn != null)) {
classKinds)); fillIn(p, patchOutLocn,
} list(patchOutLocn,
if (wantSourceFiles && (sourceLocn != null)) { p,
fillIn(p, sourceLocn, packageName,
list(sourceLocn, classKinds));
p, }
packageName, if ((wantClassFiles || wantSourceFiles) && (patchLocn != null)) {
sourceKinds)); Set<JavaFileObject.Kind> combined = EnumSet.noneOf(JavaFileObject.Kind.class);
combined.addAll(classKinds);
combined.addAll(sourceKinds);
fillIn(p, patchLocn,
list(patchLocn,
p,
packageName,
combined));
}
preferCurrent = true;
if (wantClassFiles && (classLocn != null)) {
fillIn(p, classLocn,
list(classLocn,
p,
packageName,
classKinds));
}
if (wantSourceFiles && (sourceLocn != null)) {
fillIn(p, sourceLocn,
list(sourceLocn,
p,
packageName,
sourceKinds));
}
} finally {
preferCurrent = prevPreferCurrent;
} }
} }

View file

@ -267,6 +267,7 @@ public class ModuleFinder {
private List<ModuleSymbol> scanModulePath(ModuleSymbol toFind) { private List<ModuleSymbol> scanModulePath(ModuleSymbol toFind) {
ListBuffer<ModuleSymbol> results = new ListBuffer<>(); ListBuffer<ModuleSymbol> results = new ListBuffer<>();
Map<Name, Location> namesInSet = new HashMap<>(); Map<Name, Location> namesInSet = new HashMap<>();
boolean multiModuleMode = fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH);
while (moduleLocationIterator.hasNext()) { while (moduleLocationIterator.hasNext()) {
Set<Location> locns = (moduleLocationIterator.next()); Set<Location> locns = (moduleLocationIterator.next());
namesInSet.clear(); namesInSet.clear();
@ -279,10 +280,29 @@ public class ModuleFinder {
// module has already been found, so ignore this instance // module has already been found, so ignore this instance
continue; continue;
} }
if (fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH) &&
msym.patchLocation == null) {
msym.patchLocation =
fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH,
msym.name.toString());
checkModuleInfoOnLocation(msym.patchLocation, Kind.CLASS, Kind.SOURCE);
if (msym.patchLocation != null &&
multiModuleMode &&
fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
msym.patchOutputLocation =
fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT,
msym.name.toString());
checkModuleInfoOnLocation(msym.patchOutputLocation, Kind.CLASS);
}
}
if (moduleLocationIterator.outer == StandardLocation.MODULE_SOURCE_PATH) { if (moduleLocationIterator.outer == StandardLocation.MODULE_SOURCE_PATH) {
msym.sourceLocation = l; if (msym.patchLocation == null) {
if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) { msym.sourceLocation = l;
msym.classLocation = fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT, msym.name.toString()); if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
msym.classLocation =
fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT,
msym.name.toString());
}
} }
} else { } else {
msym.classLocation = l; msym.classLocation = l;
@ -291,7 +311,8 @@ public class ModuleFinder {
moduleLocationIterator.outer == StandardLocation.UPGRADE_MODULE_PATH) { moduleLocationIterator.outer == StandardLocation.UPGRADE_MODULE_PATH) {
msym.flags_field |= Flags.SYSTEM_MODULE; msym.flags_field |= Flags.SYSTEM_MODULE;
} }
if (toFind == msym || toFind == null) { if (toFind == null ||
(toFind == msym && (msym.sourceLocation != null || msym.classLocation != null))) {
// Note: cannot return msym directly, because we must finish // Note: cannot return msym directly, because we must finish
// processing this set first // processing this set first
results.add(msym); results.add(msym);
@ -311,6 +332,21 @@ public class ModuleFinder {
return results.toList(); return results.toList();
} }
private void checkModuleInfoOnLocation(Location location, Kind... kinds) throws IOException {
if (location == null)
return ;
for (Kind kind : kinds) {
JavaFileObject file = fileManager.getJavaFileForInput(location,
names.module_info.toString(),
kind);
if (file != null) {
log.error(Errors.LocnModuleInfoNotAllowedOnPatchPath(file));
return;
}
}
}
private void findModuleInfo(ModuleSymbol msym) { private void findModuleInfo(ModuleSymbol msym) {
try { try {
JavaFileObject src_fo = (msym.sourceLocation == null) ? null JavaFileObject src_fo = (msym.sourceLocation == null) ? null

View file

@ -908,6 +908,8 @@ public abstract class Symbol extends AnnoConstruct implements Element {
public Name version; public Name version;
public JavaFileManager.Location sourceLocation; public JavaFileManager.Location sourceLocation;
public JavaFileManager.Location classLocation; public JavaFileManager.Location classLocation;
public JavaFileManager.Location patchLocation;
public JavaFileManager.Location patchOutputLocation;
/** All directives, in natural order. */ /** All directives, in natural order. */
public List<com.sun.tools.javac.code.Directive> directives; public List<com.sun.tools.javac.code.Directive> directives;

View file

@ -145,7 +145,7 @@ public class Modules extends JCTree.Visitor {
public final boolean multiModuleMode; public final boolean multiModuleMode;
private final String moduleOverride; private final String legacyModuleOverride;
private final Name java_se; private final Name java_se;
private final Name java_; private final Name java_;
@ -192,7 +192,7 @@ public class Modules extends JCTree.Visitor {
lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option); lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option);
moduleOverride = options.get(Option.XMODULE); legacyModuleOverride = options.get(Option.XMODULE);
multiModuleMode = fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH); multiModuleMode = fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH);
ClassWriter classWriter = ClassWriter.instance(context); ClassWriter classWriter = ClassWriter.instance(context);
@ -366,9 +366,26 @@ public class Modules extends JCTree.Visitor {
JavaFileObject prev = log.useSource(tree.sourcefile); JavaFileObject prev = log.useSource(tree.sourcefile);
try { try {
Location locn = getModuleLocation(tree); Location msplocn = getModuleLocation(tree);
if (locn != null) { Location plocn = fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH) ?
Name name = names.fromString(fileManager.inferModuleName(locn)); fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH,
tree.sourcefile, getPackageName(tree)) :
null;
if (plocn != null) {
Name name = names.fromString(fileManager.inferModuleName(plocn));
ModuleSymbol msym = moduleFinder.findModule(name);
tree.modle = msym;
rootModules.add(msym);
if (msplocn != null) {
Name mspname = names.fromString(fileManager.inferModuleName(msplocn));
if (name != mspname) {
log.error(tree.pos(), Errors.FilePatchedAndMsp(name, mspname));
}
}
} else if (msplocn != null) {
Name name = names.fromString(fileManager.inferModuleName(msplocn));
ModuleSymbol msym; ModuleSymbol msym;
JCModuleDecl decl = tree.getModuleDecl(); JCModuleDecl decl = tree.getModuleDecl();
if (decl != null) { if (decl != null) {
@ -383,7 +400,7 @@ public class Modules extends JCTree.Visitor {
msym = syms.enterModule(name); msym = syms.enterModule(name);
} }
if (msym.sourceLocation == null) { if (msym.sourceLocation == null) {
msym.sourceLocation = locn; msym.sourceLocation = msplocn;
if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) { if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
msym.classLocation = fileManager.getLocationForModule( msym.classLocation = fileManager.getLocationForModule(
StandardLocation.CLASS_OUTPUT, msym.name.toString()); StandardLocation.CLASS_OUTPUT, msym.name.toString());
@ -414,7 +431,9 @@ public class Modules extends JCTree.Visitor {
} }
defaultModule = syms.unnamedModule; defaultModule = syms.unnamedModule;
} else { } else {
ModuleSymbol module = null;
if (defaultModule == null) { if (defaultModule == null) {
String moduleOverride = singleModuleOverride(trees);
switch (rootModules.size()) { switch (rootModules.size()) {
case 0: case 0:
defaultModule = moduleFinder.findSingleModule(); defaultModule = moduleFinder.findSingleModule();
@ -422,38 +441,49 @@ public class Modules extends JCTree.Visitor {
if (moduleOverride != null) { if (moduleOverride != null) {
checkNoAllModulePath(); checkNoAllModulePath();
defaultModule = moduleFinder.findModule(names.fromString(moduleOverride)); defaultModule = moduleFinder.findModule(names.fromString(moduleOverride));
defaultModule.sourceLocation = StandardLocation.SOURCE_PATH; if (legacyModuleOverride != null) {
defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
}
defaultModule.patchOutputLocation = StandardLocation.CLASS_OUTPUT;
} else { } else {
// Question: why not do findAllModules and initVisiblePackages here? // Question: why not do findAllModules and initVisiblePackages here?
// i.e. body of unnamedModuleCompleter // i.e. body of unnamedModuleCompleter
defaultModule.completer = getUnnamedModuleCompleter(); defaultModule.completer = getUnnamedModuleCompleter();
defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
defaultModule.classLocation = StandardLocation.CLASS_PATH; defaultModule.classLocation = StandardLocation.CLASS_PATH;
} }
} else { } else {
checkSpecifiedModule(trees, Errors.ModuleInfoWithXmoduleClasspath); checkSpecifiedModule(trees, moduleOverride, Errors.ModuleInfoWithPatchedModuleClassoutput);
checkNoAllModulePath(); checkNoAllModulePath();
defaultModule.complete(); defaultModule.complete();
// Question: why not do completeModule here? // Question: why not do completeModule here?
defaultModule.completer = sym -> completeModule((ModuleSymbol) sym); defaultModule.completer = sym -> completeModule((ModuleSymbol) sym);
defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
} }
rootModules.add(defaultModule); rootModules.add(defaultModule);
break; break;
case 1: case 1:
checkSpecifiedModule(trees, Errors.ModuleInfoWithXmoduleSourcepath); checkSpecifiedModule(trees, moduleOverride, Errors.ModuleInfoWithPatchedModuleSourcepath);
checkNoAllModulePath(); checkNoAllModulePath();
defaultModule = rootModules.iterator().next(); defaultModule = rootModules.iterator().next();
defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
defaultModule.classLocation = StandardLocation.CLASS_OUTPUT; defaultModule.classLocation = StandardLocation.CLASS_OUTPUT;
break; break;
default: default:
Assert.error("too many modules"); Assert.error("too many modules");
} }
defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
} else if (rootModules.size() == 1 && defaultModule == rootModules.iterator().next()) { } else if (rootModules.size() == 1 && defaultModule == rootModules.iterator().next()) {
defaultModule.complete(); defaultModule.complete();
defaultModule.completer = sym -> completeModule((ModuleSymbol) sym); defaultModule.completer = sym -> completeModule((ModuleSymbol) sym);
} else { } else {
Assert.check(rootModules.isEmpty()); Assert.check(rootModules.isEmpty());
rootModules.add(defaultModule); String moduleOverride = singleModuleOverride(trees);
if (moduleOverride != null) {
module = moduleFinder.findModule(names.fromString(moduleOverride));
} else {
module = defaultModule;
}
rootModules.add(module);
} }
if (defaultModule != syms.unnamedModule) { if (defaultModule != syms.unnamedModule) {
@ -461,9 +491,53 @@ public class Modules extends JCTree.Visitor {
syms.unnamedModule.classLocation = StandardLocation.CLASS_PATH; syms.unnamedModule.classLocation = StandardLocation.CLASS_PATH;
} }
for (JCCompilationUnit tree: trees) { if (module == null) {
tree.modle = defaultModule; module = defaultModule;
} }
for (JCCompilationUnit tree: trees) {
tree.modle = module;
}
}
}
private String singleModuleOverride(List<JCCompilationUnit> trees) {
if (!fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH)) {
return legacyModuleOverride;
}
Set<String> override = new LinkedHashSet<>();
for (JCCompilationUnit tree : trees) {
JavaFileObject fo = tree.sourcefile;
try {
Location loc =
fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH,
fo, getPackageName(tree));
if (loc != null) {
override.add(fileManager.inferModuleName(loc));
}
} catch (IOException ex) {
throw new Error(ex);
}
}
switch (override.size()) {
case 0: return legacyModuleOverride;
case 1: return override.iterator().next();
default:
log.error(Errors.TooManyPatchedModules(override));
return null;
}
}
private String getPackageName(JCCompilationUnit tree) {
if (tree.getModuleDecl() != null) {
return null;
} else {
JCPackageDecl pkg = tree.getPackage();
return (pkg == null) ? "" : TreeInfo.fullName(pkg.pid).toString();
} }
} }
@ -478,32 +552,23 @@ public class Modules extends JCTree.Visitor {
* @throws IOException if there is a problem while searching for the module. * @throws IOException if there is a problem while searching for the module.
*/ */
private Location getModuleLocation(JCCompilationUnit tree) throws IOException { private Location getModuleLocation(JCCompilationUnit tree) throws IOException {
Name pkgName; String pkgName = getPackageName(tree);
if (tree.getModuleDecl() != null) {
pkgName = null;
} else {
JCPackageDecl pkg = tree.getPackage();
pkgName = (pkg == null) ? names.empty : TreeInfo.fullName(pkg.pid);
}
JavaFileObject fo = tree.sourcefile; JavaFileObject fo = tree.sourcefile;
// For now, just check module source path.
// We may want to check source path as well.
Location loc = Location loc =
fileManager.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH, fileManager.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH,
fo, (pkgName == null) ? null : pkgName.toString()); fo, (pkgName == null) ? null : pkgName);
if (loc == null) { if (loc == null) {
Location sourceOutput = fileManager.hasLocation(StandardLocation.SOURCE_OUTPUT) ? Location sourceOutput = fileManager.hasLocation(StandardLocation.SOURCE_OUTPUT) ?
StandardLocation.SOURCE_OUTPUT : StandardLocation.CLASS_OUTPUT; StandardLocation.SOURCE_OUTPUT : StandardLocation.CLASS_OUTPUT;
loc = loc =
fileManager.getLocationForModule(sourceOutput, fileManager.getLocationForModule(sourceOutput,
fo, (pkgName == null) ? null : pkgName.toString()); fo, (pkgName == null) ? null : pkgName);
} }
return loc; return loc;
} }
private void checkSpecifiedModule(List<JCCompilationUnit> trees, JCDiagnostic.Error error) { private void checkSpecifiedModule(List<JCCompilationUnit> trees, String moduleOverride, JCDiagnostic.Error error) {
if (moduleOverride != null) { if (moduleOverride != null) {
JavaFileObject prev = log.useSource(trees.head.sourcefile); JavaFileObject prev = log.useSource(trees.head.sourcefile);
try { try {
@ -1594,8 +1659,8 @@ public class Modules extends JCTree.Visitor {
} }
public void newRound() { public void newRound() {
rootModules = null;
allModules = null; allModules = null;
rootModules = null;
warnedMissing.clear(); warnedMissing.clear();
} }
} }

View file

@ -980,7 +980,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException { public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
checkModuleOrientedOrOutputLocation(location); checkModuleOrientedOrOutputLocation(location);
if (!(fo instanceof PathFileObject)) if (!(fo instanceof PathFileObject))
throw new IllegalArgumentException(fo.getName()); return null;
int depth = 1; // allow 1 for filename int depth = 1; // allow 1 for filename
if (pkgName != null && !pkgName.isEmpty()) { if (pkgName != null && !pkgName.isEmpty()) {
depth += 1; depth += 1;

View file

@ -432,7 +432,7 @@ public class Locations {
/** /**
* @see JavaFileManager#getLocationForModule(Location, JavaFileObject, String) * @see JavaFileManager#getLocationForModule(Location, JavaFileObject, String)
*/ */
Location getLocationForModule(Path dir) { Location getLocationForModule(Path dir) throws IOException {
return null; return null;
} }
@ -545,7 +545,7 @@ public class Locations {
l = new ModuleLocationHandler(location.getName() + "[" + name + "]", l = new ModuleLocationHandler(location.getName() + "[" + name + "]",
name, name,
Collections.singleton(out), Collections.singleton(out),
true, false); true);
moduleLocations.put(name, l); moduleLocations.put(name, l);
pathLocations.put(out.toAbsolutePath(), l); pathLocations.put(out.toAbsolutePath(), l);
} }
@ -864,29 +864,14 @@ public class Locations {
protected final String name; protected final String name;
protected final String moduleName; protected final String moduleName;
protected final Collection<Path> searchPath; protected final Collection<Path> searchPath;
protected final Collection<Path> searchPathWithOverrides;
protected final boolean output; protected final boolean output;
ModuleLocationHandler(String name, String moduleName, Collection<Path> searchPath, ModuleLocationHandler(String name, String moduleName, Collection<Path> searchPath,
boolean output, boolean allowOverrides) { boolean output) {
this.name = name; this.name = name;
this.moduleName = moduleName; this.moduleName = moduleName;
this.searchPath = searchPath; this.searchPath = searchPath;
this.output = output; this.output = output;
if (allowOverrides && patchMap != null) {
SearchPath mPatch = patchMap.get(moduleName);
if (mPatch != null) {
SearchPath sp = new SearchPath();
sp.addAll(mPatch);
sp.addAll(searchPath);
searchPathWithOverrides = sp;
} else {
searchPathWithOverrides = searchPath;
}
} else {
searchPathWithOverrides = searchPath;
}
} }
@Override @DefinedBy(Api.COMPILER) @Override @DefinedBy(Api.COMPILER)
@ -909,7 +894,7 @@ public class Locations {
// For now, we always return searchPathWithOverrides. This may differ from the // For now, we always return searchPathWithOverrides. This may differ from the
// JVM behavior if there is a module-info.class to be found in the overriding // JVM behavior if there is a module-info.class to be found in the overriding
// classes. // classes.
return searchPathWithOverrides; return searchPath;
} }
@Override // defined by LocationHandler @Override // defined by LocationHandler
@ -1068,7 +1053,7 @@ public class Locations {
String name = location.getName() String name = location.getName()
+ "[" + pathIndex + ":" + moduleName + "]"; + "[" + pathIndex + ":" + moduleName + "]";
ModuleLocationHandler l = new ModuleLocationHandler(name, moduleName, ModuleLocationHandler l = new ModuleLocationHandler(name, moduleName,
Collections.singleton(path), false, true); Collections.singleton(path), false);
return Collections.singleton(l); return Collections.singleton(l);
} catch (ModuleNameReader.BadClassFile e) { } catch (ModuleNameReader.BadClassFile e) {
log.error(Errors.LocnBadModuleInfo(path)); log.error(Errors.LocnBadModuleInfo(path));
@ -1093,7 +1078,7 @@ public class Locations {
String name = location.getName() String name = location.getName()
+ "[" + pathIndex + "." + (index++) + ":" + moduleName + "]"; + "[" + pathIndex + "." + (index++) + ":" + moduleName + "]";
ModuleLocationHandler l = new ModuleLocationHandler(name, moduleName, ModuleLocationHandler l = new ModuleLocationHandler(name, moduleName,
Collections.singleton(modulePath), false, true); Collections.singleton(modulePath), false);
result.add(l); result.add(l);
} }
return result; return result;
@ -1110,7 +1095,7 @@ public class Locations {
String name = location.getName() String name = location.getName()
+ "[" + pathIndex + ":" + moduleName + "]"; + "[" + pathIndex + ":" + moduleName + "]";
ModuleLocationHandler l = new ModuleLocationHandler(name, moduleName, ModuleLocationHandler l = new ModuleLocationHandler(name, moduleName,
Collections.singleton(modulePath), false, true); Collections.singleton(modulePath), false);
return Collections.singleton(l); return Collections.singleton(l);
} }
@ -1277,7 +1262,7 @@ public class Locations {
pathLocations = new LinkedHashMap<>(); pathLocations = new LinkedHashMap<>();
map.forEach((k, v) -> { map.forEach((k, v) -> {
String name = location.getName() + "[" + k + "]"; String name = location.getName() + "[" + k + "]";
ModuleLocationHandler h = new ModuleLocationHandler(name, k, v, false, false); ModuleLocationHandler h = new ModuleLocationHandler(name, k, v, false);
moduleLocations.put(k, h); moduleLocations.put(k, h);
v.forEach(p -> pathLocations.put(normalize(p), h)); v.forEach(p -> pathLocations.put(normalize(p), h));
}); });
@ -1417,6 +1402,7 @@ public class Locations {
private Path systemJavaHome; private Path systemJavaHome;
private Path modules; private Path modules;
private Map<String, ModuleLocationHandler> systemModules; private Map<String, ModuleLocationHandler> systemModules;
private Map<Path, Location> pathLocations;
SystemModulesLocationHandler() { SystemModulesLocationHandler() {
super(StandardLocation.SYSTEM_MODULES, Option.SYSTEM); super(StandardLocation.SYSTEM_MODULES, Option.SYSTEM);
@ -1490,6 +1476,12 @@ public class Locations {
return systemModules.get(name); return systemModules.get(name);
} }
@Override
Location getLocationForModule(Path dir) throws IOException {
initSystemModules();
return (pathLocations == null) ? null : pathLocations.get(dir);
}
@Override @Override
Iterable<Set<Location>> listLocationsForModules() throws IOException { Iterable<Set<Location>> listLocationsForModules() throws IOException {
initSystemModules(); initSystemModules();
@ -1544,18 +1536,96 @@ public class Locations {
} }
systemModules = new LinkedHashMap<>(); systemModules = new LinkedHashMap<>();
pathLocations = new LinkedHashMap<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(modules, Files::isDirectory)) { try (DirectoryStream<Path> stream = Files.newDirectoryStream(modules, Files::isDirectory)) {
for (Path entry : stream) { for (Path entry : stream) {
String moduleName = entry.getFileName().toString(); String moduleName = entry.getFileName().toString();
String name = location.getName() + "[" + moduleName + "]"; String name = location.getName() + "[" + moduleName + "]";
ModuleLocationHandler h = new ModuleLocationHandler(name, moduleName, ModuleLocationHandler h = new ModuleLocationHandler(name, moduleName,
Collections.singleton(entry), false, true); Collections.singleton(entry), false);
systemModules.put(moduleName, h); systemModules.put(moduleName, h);
pathLocations.put(normalize(entry), h);
} }
} }
} }
} }
private class PatchModulesLocationHandler extends BasicLocationHandler {
private final Map<String, ModuleLocationHandler> moduleLocations = new HashMap<>();
private final Map<Path, Location> pathLocations = new HashMap<>();
PatchModulesLocationHandler() {
super(StandardLocation.PATCH_MODULE_PATH, Option.PATCH_MODULE);
}
@Override
boolean handleOption(Option option, String value) {
if (!options.contains(option)) {
return false;
}
// Allow an extended syntax for --patch-module consisting of a series
// of values separated by NULL characters. This is to facilitate
// supporting deferred file manager options on the command line.
// See Option.PATCH_MODULE for the code that composes these multiple
// values.
for (String v : value.split("\0")) {
int eq = v.indexOf('=');
if (eq > 0) {
String moduleName = v.substring(0, eq);
SearchPath mPatchPath = new SearchPath()
.addFiles(v.substring(eq + 1));
String name = location.getName() + "[" + moduleName + "]";
ModuleLocationHandler h = new ModuleLocationHandler(name, moduleName, mPatchPath, false);
moduleLocations.put(moduleName, h);
for (Path r : mPatchPath) {
pathLocations.put(normalize(r), h);
}
} else {
// Should not be able to get here;
// this should be caught and handled in Option.PATCH_MODULE
log.error(Errors.LocnInvalidArgForXpatch(value));
}
}
return true;
}
@Override
boolean isSet() {
return !moduleLocations.isEmpty();
}
@Override
Collection<Path> getPaths() {
throw new UnsupportedOperationException();
}
@Override
void setPaths(Iterable<? extends Path> files) throws IOException {
throw new UnsupportedOperationException();
}
@Override
Location getLocationForModule(String name) throws IOException {
return moduleLocations.get(name);
}
@Override
Location getLocationForModule(Path dir) throws IOException {
return (pathLocations == null) ? null : pathLocations.get(dir);
}
@Override
Iterable<Set<Location>> listLocationsForModules() throws IOException {
Set<Location> locns = new LinkedHashSet<>();
for (Location l: moduleLocations.values())
locns.add(l);
return Collections.singleton(locns);
}
}
Map<Location, LocationHandler> handlersForLocation; Map<Location, LocationHandler> handlersForLocation;
Map<Option, LocationHandler> handlersForOption; Map<Option, LocationHandler> handlersForOption;
@ -1573,6 +1643,7 @@ public class Locations {
new OutputLocationHandler(StandardLocation.SOURCE_OUTPUT, Option.S), new OutputLocationHandler(StandardLocation.SOURCE_OUTPUT, Option.S),
new OutputLocationHandler(StandardLocation.NATIVE_HEADER_OUTPUT, Option.H), new OutputLocationHandler(StandardLocation.NATIVE_HEADER_OUTPUT, Option.H),
new ModuleSourcePathLocationHandler(), new ModuleSourcePathLocationHandler(),
new PatchModulesLocationHandler(),
// TODO: should UPGRADE_MODULE_PATH be merged with SYSTEM_MODULES? // TODO: should UPGRADE_MODULE_PATH be merged with SYSTEM_MODULES?
new ModulePathLocationHandler(StandardLocation.UPGRADE_MODULE_PATH, Option.UPGRADE_MODULE_PATH), new ModulePathLocationHandler(StandardLocation.UPGRADE_MODULE_PATH, Option.UPGRADE_MODULE_PATH),
new ModulePathLocationHandler(StandardLocation.MODULE_PATH, Option.MODULE_PATH), new ModulePathLocationHandler(StandardLocation.MODULE_PATH, Option.MODULE_PATH),
@ -1587,51 +1658,9 @@ public class Locations {
} }
} }
private Map<String, SearchPath> patchMap;
boolean handleOption(Option option, String value) { boolean handleOption(Option option, String value) {
switch (option) { LocationHandler h = handlersForOption.get(option);
case PATCH_MODULE: return (h == null ? false : h.handleOption(option, value));
if (value == null) {
patchMap = null;
} else {
// Allow an extended syntax for --patch-module consisting of a series
// of values separated by NULL characters. This is to facilitate
// supporting deferred file manager options on the command line.
// See Option.PATCH_MODULE for the code that composes these multiple
// values.
for (String v : value.split("\0")) {
int eq = v.indexOf('=');
if (eq > 0) {
String mName = v.substring(0, eq);
SearchPath mPatchPath = new SearchPath()
.addFiles(v.substring(eq + 1));
boolean ok = true;
for (Path p : mPatchPath) {
Path mi = p.resolve("module-info.class");
if (Files.exists(mi)) {
log.error(Errors.LocnModuleInfoNotAllowedOnPatchPath(mi));
ok = false;
}
}
if (ok) {
if (patchMap == null) {
patchMap = new LinkedHashMap<>();
}
patchMap.put(mName, mPatchPath);
}
} else {
// Should not be able to get here;
// this should be caught and handled in Option.PATCH_MODULE
log.error(Errors.LocnInvalidArgForXpatch(value));
}
}
}
return true;
default:
LocationHandler h = handlersForOption.get(option);
return (h == null ? false : h.handleOption(option, value));
}
} }
boolean hasLocation(Location location) { boolean hasLocation(Location location) {
@ -1670,7 +1699,7 @@ public class Locations {
return (h == null ? null : h.getLocationForModule(name)); return (h == null ? null : h.getLocationForModule(name));
} }
Location getLocationForModule(Location location, Path dir) { Location getLocationForModule(Location location, Path dir) throws IOException {
LocationHandler h = getHandler(location); LocationHandler h = getHandler(location);
return (h == null ? null : h.getLocationForModule(dir)); return (h == null ? null : h.getLocationForModule(dir));
} }

View file

@ -598,9 +598,6 @@ public class Arguments {
&& !fm.hasLocation(StandardLocation.CLASS_OUTPUT)) { && !fm.hasLocation(StandardLocation.CLASS_OUTPUT)) {
log.error(Errors.NoOutputDir); log.error(Errors.NoOutputDir);
} }
if (options.isSet(Option.XMODULE)) {
log.error(Errors.XmoduleNoModuleSourcepath);
}
} }
if (fm.hasLocation(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH) && if (fm.hasLocation(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH) &&

View file

@ -1450,6 +1450,11 @@ public class JavaCompiler {
return; return;
} }
if (!modules.multiModuleMode && env.toplevel.modle != modules.getDefaultModule()) {
//can only generate classfiles for a single module:
return;
}
if (compileStates.isDone(env, CompileState.LOWER)) { if (compileStates.isDone(env, CompileState.LOWER)) {
results.addAll(desugaredEnvs.get(env)); results.addAll(desugaredEnvs.get(env));
return; return;

View file

@ -579,7 +579,7 @@ public enum Option {
} }
}, },
XMODULE("-Xmodule:", "opt.arg.module", "opt.module", EXTENDED, BASIC) { XMODULE("-Xmodule:", "opt.arg.module", "opt.module", HIDDEN, BASIC) {
@Override @Override
public void process(OptionHelper helper, String option, String arg) throws InvalidValueException { public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
String prev = helper.get(XMODULE); String prev = helper.get(XMODULE);

View file

@ -1292,7 +1292,7 @@ compiler.err.multi-module.outdir.cannot.be.exploded.module=\
compiler.warn.outdir.is.in.exploded.module=\ compiler.warn.outdir.is.in.exploded.module=\
the output directory is within an exploded module: {0} the output directory is within an exploded module: {0}
# 0: path # 0: file object
compiler.err.locn.module-info.not.allowed.on.patch.path=\ compiler.err.locn.module-info.not.allowed.on.patch.path=\
module-info.class not allowed on patch path: {0} module-info.class not allowed on patch path: {0}
@ -2957,14 +2957,20 @@ compiler.misc.module.non.zero.opens=\
compiler.err.module.decl.sb.in.module-info.java=\ compiler.err.module.decl.sb.in.module-info.java=\
module declarations should be in a file named module-info.java module declarations should be in a file named module-info.java
compiler.err.module-info.with.xmodule.sourcepath=\ compiler.err.module-info.with.patched.module.sourcepath=\
illegal combination of -Xmodule and module-info on sourcepath compiling a module patch with module-info on sourcepath
compiler.err.module-info.with.xmodule.classpath=\ compiler.err.module-info.with.patched.module.classoutput=\
illegal combination of -Xmodule and module-info on classpath compiling a module patch with module-info on class output
compiler.err.xmodule.no.module.sourcepath=\ # 0: set of string
illegal combination of -Xmodule and --module-source-path compiler.err.too.many.patched.modules=\
too many patched modules ({0}), use --module-source-path
# 0: name, 1: name
compiler.err.file.patched.and.msp=\
file accessible from both --patch-module and --module-source-path, \
but belongs to a different module on each path: {0}, {1}
compiler.err.processorpath.no.processormodulepath=\ compiler.err.processorpath.no.processormodulepath=\
illegal combination of -processorpath and --processor-module-path illegal combination of -processorpath and --processor-module-path

View file

@ -204,13 +204,6 @@ public enum ToolOption {
} }
}, },
XMODULE("-Xmodule:", false) {
@Override
public void process(Helper helper, String arg) throws InvalidValueException {
Option.XMODULE.process(helper.getOptionHelper(), arg);
}
},
PATCH_MODULE("--patch-module", true) { PATCH_MODULE("--patch-module", true) {
@Override @Override
public void process(Helper helper, String arg) throws InvalidValueException { public void process(Helper helper, String arg) throws InvalidValueException {

View file

@ -82,7 +82,6 @@ main.Xusage=\
\ Specify additional modules to be considered as required by a\n\ \ Specify additional modules to be considered as required by a\n\
\ given module. <other-module> may be ALL-UNNAMED to require\n\ \ given module. <other-module> may be ALL-UNNAMED to require\n\
\ the unnamed module.\n\ \ the unnamed module.\n\
\ -Xmodule:<module-name> Specify a module to which the classes being compiled belong.\n\
\ --patch-module <module>=<file>(:<file>)*\n\ \ --patch-module <module>=<file>(:<file>)*\n\
\ Override or augment a module with classes and resources\n\ \ Override or augment a module with classes and resources\n\
\ in JAR files or directories\n \ in JAR files or directories\n

View file

@ -181,13 +181,6 @@ public enum ToolOption {
} }
}, },
XMODULE("-Xmodule:", EXTENDED, false) {
@Override
public void process(Helper helper, String arg) throws InvalidValueException {
Option.XMODULE.process(helper.getOptionHelper(), arg);
}
},
PATCH_MODULE("--patch-module", EXTENDED, true) { PATCH_MODULE("--patch-module", EXTENDED, true) {
@Override @Override
public void process(Helper helper, String arg) throws InvalidValueException { public void process(Helper helper, String arg) throws InvalidValueException {

View file

@ -238,11 +238,6 @@ main.opt.add.reads.desc=\
given module. <other-module> may be ALL-UNNAMED to require\n\ given module. <other-module> may be ALL-UNNAMED to require\n\
the unnamed module. the unnamed module.
main.opt.Xmodule.arg=\
<module-name>
main.opt.Xmodule.desc=\
Specify a module to which the classes being compiled belong
main.opt.patch.module.arg=\ main.opt.patch.module.arg=\
<module>=<file>(:<file>)* <module>=<file>(:<file>)*
main.opt.patch.module.desc=\ main.opt.patch.module.desc=\

View file

@ -30,8 +30,6 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI; import java.net.URI;
import java.nio.file.FileSystems; import java.nio.file.FileSystems;
import java.nio.file.Files; import java.nio.file.Files;
@ -71,10 +69,6 @@ class MemoryFileManager implements JavaFileManager {
private final JShell proc; private final JShell proc;
// Upcoming Jigsaw
private Method inferModuleNameMethod = null;
private Method listLocationsForModulesMethod = null;
Iterable<? extends Path> getLocationAsPaths(Location loc) { Iterable<? extends Path> getLocationAsPaths(Location loc) {
return this.stdFileManager.getLocationAsPaths(loc); return this.stdFileManager.getLocationAsPaths(loc);
} }
@ -186,45 +180,6 @@ class MemoryFileManager implements JavaFileManager {
return new SourceMemoryJavaFileObject(origin, name, code); return new SourceMemoryJavaFileObject(origin, name, code);
} }
// Make compatible with Jigsaw
@Override
public String inferModuleName(Location location) {
try {
if (inferModuleNameMethod == null) {
inferModuleNameMethod = JavaFileManager.class.getDeclaredMethod("inferModuleName", Location.class);
}
@SuppressWarnings("unchecked")
String result = (String) inferModuleNameMethod.invoke(stdFileManager, location);
return result;
} catch (NoSuchMethodException | SecurityException ex) {
throw new InternalError("Cannot lookup JavaFileManager method", ex);
} catch (IllegalAccessException |
IllegalArgumentException |
InvocationTargetException ex) {
throw new InternalError("Cannot invoke JavaFileManager method", ex);
}
}
// Make compatible with Jigsaw
@Override
public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
try {
if (listLocationsForModulesMethod == null) {
listLocationsForModulesMethod = JavaFileManager.class.getDeclaredMethod("listLocationsForModules", Location.class);
}
@SuppressWarnings("unchecked")
Iterable<Set<Location>> result = (Iterable<Set<Location>>) listLocationsForModulesMethod.invoke(stdFileManager, location);
return result;
} catch (NoSuchMethodException | SecurityException ex) {
throw new InternalError("Cannot lookup JavaFileManager method", ex);
} catch (IllegalAccessException |
IllegalArgumentException |
InvocationTargetException ex) {
throw new InternalError("Cannot invoke JavaFileManager method", ex);
}
}
/** /**
* Returns a class loader for loading plug-ins from the given location. For * Returns a class loader for loading plug-ins from the given location. For
* example, to load annotation processors, a compiler will request a class * example, to load annotation processors, a compiler will request a class
@ -584,6 +539,26 @@ class MemoryFileManager implements JavaFileManager {
", sibling: " + sibling); ", sibling: " + sibling);
} }
@Override
public Location getLocationForModule(Location location, String moduleName) throws IOException {
return stdFileManager.getLocationForModule(location, moduleName);
}
@Override
public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
return stdFileManager.getLocationForModule(location, fo, pkgName);
}
@Override
public String inferModuleName(Location location) throws IOException {
return stdFileManager.inferModuleName(location);
}
@Override
public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
return stdFileManager.listLocationsForModules(location);
}
/** /**
* Flushes any resources opened for output by this file manager * Flushes any resources opened for output by this file manager
* directly or indirectly. Flushing a closed file manager has no * directly or indirectly. Flushing a closed file manager has no

View file

@ -68,9 +68,9 @@ public class T6627362 {
// compile and disassemble E.java, using modified Object.java, // compile and disassemble E.java, using modified Object.java,
// check for reference to System.arraycopy // check for reference to System.arraycopy
File x = new File(testSrc, "x"); File x = new File(testSrc, "x");
String[] jcArgs = { "-d", ".", "-Xmodule:java.base", String[] jcArgs = { "-d", ".", "--patch-module", "java.base=" + x.getAbsolutePath(),
new File(x, "E.java").getPath(), new File(x, "E.java").getPath(),
new File(x, "Object.java").getPath()}; new File(new File(new File(x, "java"), "lang"), "Object.java").getPath()};
compile(jcArgs); compile(jcArgs);
String[] jpArgs = { "-classpath", ".", "-c", "E" }; String[] jpArgs = { "-classpath", ".", "-c", "E" };

View file

@ -63,6 +63,7 @@ class Example implements Comparable<Example> {
procFiles = new ArrayList<File>(); procFiles = new ArrayList<File>();
srcPathFiles = new ArrayList<File>(); srcPathFiles = new ArrayList<File>();
moduleSourcePathFiles = new ArrayList<File>(); moduleSourcePathFiles = new ArrayList<File>();
patchModulePathFiles = new ArrayList<File>();
modulePathFiles = new ArrayList<File>(); modulePathFiles = new ArrayList<File>();
classPathFiles = new ArrayList<File>(); classPathFiles = new ArrayList<File>();
additionalFiles = new ArrayList<File>(); additionalFiles = new ArrayList<File>();
@ -88,6 +89,9 @@ class Example implements Comparable<Example> {
} else if (files == srcFiles && c.getName().equals("modulesourcepath")) { } else if (files == srcFiles && c.getName().equals("modulesourcepath")) {
moduleSourcePathDir = c; moduleSourcePathDir = c;
findFiles(c, moduleSourcePathFiles); findFiles(c, moduleSourcePathFiles);
} else if (files == srcFiles && c.getName().equals("patchmodule")) {
patchModulePathDir = c;
findFiles(c, patchModulePathFiles);
} else if (files == srcFiles && c.getName().equals("additional")) { } else if (files == srcFiles && c.getName().equals("additional")) {
additionalFilesDir = c; additionalFilesDir = c;
findFiles(c, additionalFiles); findFiles(c, additionalFiles);
@ -272,6 +276,16 @@ class Example implements Comparable<Example> {
files.addAll(nonEmptySrcFiles); // srcFiles containing declarations files.addAll(nonEmptySrcFiles); // srcFiles containing declarations
} }
if (patchModulePathDir != null) {
for (File mod : patchModulePathDir.listFiles()) {
opts.add("--patch-module");
opts.add(mod.getName() + "=" + mod.getPath());
}
files = new ArrayList<>();
files.addAll(patchModulePathFiles);
files.addAll(nonEmptySrcFiles); // srcFiles containing declarations
}
if (additionalFiles.size() > 0) { if (additionalFiles.size() > 0) {
List<String> sOpts = Arrays.asList("-d", classesDir.getPath()); List<String> sOpts = Arrays.asList("-d", classesDir.getPath());
new Jsr199Compiler(verbose).run(null, null, false, sOpts, additionalFiles); new Jsr199Compiler(verbose).run(null, null, false, sOpts, additionalFiles);
@ -343,9 +357,11 @@ class Example implements Comparable<Example> {
List<File> procFiles; List<File> procFiles;
File srcPathDir; File srcPathDir;
File moduleSourcePathDir; File moduleSourcePathDir;
File patchModulePathDir;
File additionalFilesDir; File additionalFilesDir;
List<File> srcPathFiles; List<File> srcPathFiles;
List<File> moduleSourcePathFiles; List<File> moduleSourcePathFiles;
List<File> patchModulePathFiles;
List<File> modulePathFiles; List<File> modulePathFiles;
List<File> classPathFiles; List<File> classPathFiles;
List<File> additionalFiles; List<File> additionalFiles;

View file

@ -5,6 +5,7 @@ compiler.err.bad.functional.intf.anno # seems to be masked by
compiler.err.cant.read.file # (apt.JavaCompiler?) compiler.err.cant.read.file # (apt.JavaCompiler?)
compiler.err.cant.select.static.class.from.param.type compiler.err.cant.select.static.class.from.param.type
compiler.err.dc.unterminated.string # cannot happen compiler.err.dc.unterminated.string # cannot happen
compiler.err.file.patched.and.msp # needs the same dir on --module-source-path and --patch-module
compiler.err.illegal.char.for.encoding compiler.err.illegal.char.for.encoding
compiler.err.invalid.repeatable.annotation # should not happen compiler.err.invalid.repeatable.annotation # should not happen
compiler.err.invalid.repeatable.annotation.invalid.value # "can't" happen compiler.err.invalid.repeatable.annotation.invalid.value # "can't" happen

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2016, 2017, 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.
*/
// key: compiler.err.module-info.with.patched.module.classoutput

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -21,9 +21,6 @@
* questions. * questions.
*/ */
// key: compiler.err.module-info.with.xmodule.sourcepath
// options: -Xmodule:java.compiler
package javax.lang.model.element; package javax.lang.model.element;
public interface Extra {} public interface Extra {}

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2016, 2017, 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.
*/
// key: compiler.err.module-info.with.patched.module.sourcepath

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -21,9 +21,6 @@
* questions. * questions.
*/ */
// key: compiler.err.module-info.with.xmodule.classpath
// options: -Xmodule:java.compiler
package javax.lang.model.element; package javax.lang.model.element;
public interface ModuleInfoWithXModuleClasspath {} public interface Extra {}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,12 +22,3 @@
*/ */
// key: compiler.err.no.superclass // key: compiler.err.no.superclass
// options: -Xmodule:java.base
package java.lang;
class Object {
public Object() {
super();
}
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2010, 2017, 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 java.lang;
class Object {
public Object() {
super();
}
}

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -21,7 +21,4 @@
* questions. * questions.
*/ */
// key: compiler.err.xmodule.no.module.sourcepath // key: compiler.err.too.many.patched.modules
// options: -Xmodule:java.compiler --module-source-path src
class XModuleWithModulePath {}

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2017, 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;
class C {}

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2017, 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;
class C {}

View file

@ -1,12 +0,0 @@
/*
* @test
* @bug 8168774
* @summary Polymorhic signature method check crashes javac
* @compile -Xmodule:java.base BadPolySig.java
*/
package java.lang.invoke;
class MethodHandle {
native Object m();
}

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2016, 2017, 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 8168774
* @summary Polymorhic signature method check crashes javac
* @modules jdk.compiler
* @compile/module=java.base java/lang/invoke/MethodHandle.java
*/

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2016, 2017, 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 java.lang.invoke;
class MethodHandle {
native Object m();
}

View file

@ -293,7 +293,7 @@ public class AddLimitMods extends ModuleTestBase {
} }
actual = new JavacTask(tb) actual = new JavacTask(tb)
.options("-Xmodule:java.base", .options("--patch-module", "java.base=" + cpSrc.toString(),
"-XDrawDiagnostics", "-XDrawDiagnostics",
"--add-modules", "ALL-MODULE-PATH") "--add-modules", "ALL-MODULE-PATH")
.outdir(cpOut) .outdir(cpOut)

View file

@ -217,7 +217,7 @@ public class AddReadsTest extends ModuleTestBase {
new JavacTask(tb) new JavacTask(tb)
.options("--class-path", jar.toString(), .options("--class-path", jar.toString(),
"--add-reads", "java.base=ALL-UNNAMED", "--add-reads", "java.base=ALL-UNNAMED",
"-Xmodule:java.base") "--patch-module", "java.base=" + src)
.outdir(classes) .outdir(classes)
.files(src.resolve("impl").resolve("Impl.java")) .files(src.resolve("impl").resolve("Impl.java"))
.run() .run()
@ -237,7 +237,7 @@ public class AddReadsTest extends ModuleTestBase {
new JavacTask(tb) new JavacTask(tb)
.options("--add-modules", "java.desktop", .options("--add-modules", "java.desktop",
"--add-reads", "java.base=java.desktop", "--add-reads", "java.base=java.desktop",
"-Xmodule:java.base") "--patch-module", "java.base=" + src)
.outdir(classes) .outdir(classes)
.files(findJavaFiles(src)) .files(findJavaFiles(src))
.run() .run()
@ -304,7 +304,7 @@ public class AddReadsTest extends ModuleTestBase {
new JavacTask(tb) new JavacTask(tb)
.options("--add-reads", "m1x=ALL-UNNAMED", .options("--add-reads", "m1x=ALL-UNNAMED",
"-Xmodule:m1x", "--patch-module", "m1x=" + unnamedSrc,
"--module-path", classes.toString()) "--module-path", classes.toString())
.outdir(unnamedClasses) .outdir(unnamedClasses)
.files(findJavaFiles(unnamedSrc)) .files(findJavaFiles(unnamedSrc))

View file

@ -23,6 +23,7 @@
/* /*
* @test * @test
* @bug 8173777
* @summary tests for multi-module mode compilation * @summary tests for multi-module mode compilation
* @library /tools/lib * @library /tools/lib
* @modules * @modules
@ -31,13 +32,15 @@
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.processing * jdk.compiler/com.sun.tools.javac.processing
* @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
* @run main XModuleTest * @run main CompileModulePatchTest
*/ */
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.RoundEnvironment;
@ -54,14 +57,14 @@ import toolbox.ModuleBuilder;
import toolbox.Task; import toolbox.Task;
import toolbox.Task.Expect; import toolbox.Task.Expect;
public class XModuleTest extends ModuleTestBase { public class CompileModulePatchTest extends ModuleTestBase {
public static void main(String... args) throws Exception { public static void main(String... args) throws Exception {
new XModuleTest().runTests(); new CompileModulePatchTest().runTests();
} }
@Test @Test
public void testCorrectXModule(Path base) throws Exception { public void testCorrectModulePatch(Path base) throws Exception {
//note: avoiding use of java.base, as that gets special handling on some places: //note: avoiding use of java.base, as that gets special handling on some places:
Path src = base.resolve("src"); Path src = base.resolve("src");
tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }"); tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }");
@ -69,7 +72,7 @@ public class XModuleTest extends ModuleTestBase {
tb.createDirectories(classes); tb.createDirectories(classes);
String log = new JavacTask(tb) String log = new JavacTask(tb)
.options("-Xmodule:java.compiler") .options("--patch-module", "java.compiler=" + src.toString())
.outdir(classes) .outdir(classes)
.files(findJavaFiles(src)) .files(findJavaFiles(src))
.run() .run()
@ -81,23 +84,136 @@ public class XModuleTest extends ModuleTestBase {
} }
@Test @Test
public void testSourcePath(Path base) throws Exception { public void testCorrectModulePatchMultiModule(Path base) throws Exception {
//note: avoiding use of java.base, as that gets special handling on some places: //note: avoiding use of java.base, as that gets special handling on some places:
Path src = base.resolve("src"); Path src = base.resolve("src");
tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, Other { }", "package javax.lang.model.element; interface Other { }"); Path m1 = src.resolve("m1");
tb.writeJavaFiles(m1, "package javax.lang.model.element; public interface Extra extends Element { }");
Path m2 = src.resolve("m2");
tb.writeJavaFiles(m2, "package com.sun.source.tree; public interface Extra extends Tree { }");
Path classes = base.resolve("classes"); Path classes = base.resolve("classes");
tb.createDirectories(classes); tb.createDirectories(classes);
String log = new JavacTask(tb) String log = new JavacTask(tb)
.options("-Xmodule:java.compiler", "-sourcepath", src.toString()) .options("--patch-module", "java.compiler=" + m1.toString(),
"--patch-module", "jdk.compiler=" + m2.toString(),
"--module-source-path", "dummy")
.outdir(classes) .outdir(classes)
.files(src.resolve("javax/lang/model/element/Extra.java")) .files(findJavaFiles(src))
.run() .run()
.writeAll() .writeAll()
.getOutput(Task.OutputKind.DIRECT); .getOutput(Task.OutputKind.DIRECT);
if (!log.isEmpty()) if (!log.isEmpty())
throw new Exception("expected output not found: " + log); throw new Exception("expected output not found: " + log);
checkFileExists(classes, "java.compiler/javax/lang/model/element/Extra.class");
checkFileExists(classes, "jdk.compiler/com/sun/source/tree/Extra.class");
}
@Test
public void testCorrectModulePatchMultiModule2(Path base) throws Exception {
//note: avoiding use of java.base, as that gets special handling on some places:
Path src = base.resolve("src");
Path m1 = src.resolve("m1");
tb.writeJavaFiles(m1,
"package javax.lang.model.element; public interface Extra extends Element { }");
Path m2 = src.resolve("m2");
tb.writeJavaFiles(m2,
"package com.sun.source.tree; public interface Extra extends Tree { }");
Path msp = base.resolve("msp");
Path m3 = msp.resolve("m3x");
tb.writeJavaFiles(m3,
"module m3x { }",
"package m3; public class Test { }");
Path m4 = msp.resolve("m4x");
tb.writeJavaFiles(m4,
"module m4x { }",
"package m4; public class Test { }");
Path classes = base.resolve("classes");
tb.createDirectories(classes);
String log = new JavacTask(tb)
.options("--patch-module", "java.compiler=" + m1.toString(),
"--patch-module", "jdk.compiler=" + m2.toString(),
"--module-source-path", msp.toString())
.outdir(classes)
.files(findJavaFiles(src, msp))
.run()
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
if (!log.isEmpty())
throw new Exception("expected output not found: " + log);
checkFileExists(classes, "java.compiler/javax/lang/model/element/Extra.class");
checkFileExists(classes, "jdk.compiler/com/sun/source/tree/Extra.class");
checkFileExists(classes, "m3x/m3/Test.class");
checkFileExists(classes, "m4x/m4/Test.class");
}
@Test
public void testPatchModuleModuleSourcePathConflict(Path base) throws Exception {
//note: avoiding use of java.base, as that gets special handling on some places:
Path src = base.resolve("src");
Path m1 = src.resolve("m1x");
tb.writeJavaFiles(m1,
"module m1x { }",
"package m1; public class Test { }");
Path m2 = src.resolve("m2x");
tb.writeJavaFiles(m2,
"module m2x { }",
"package m2; public class Test { }");
Path classes = base.resolve("classes");
tb.createDirectories(classes);
List<String> log = new JavacTask(tb)
.options("--patch-module", "m1x=" + m2.toString(),
"--module-source-path", src.toString(),
"-XDrawDiagnostics")
.outdir(classes)
.files(findJavaFiles(src.resolve("m1x").resolve("m1"),
src.resolve("m2x").resolve("m2")))
.run(Expect.FAIL)
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
List<String> expectedOut = Arrays.asList(
"Test.java:1:1: compiler.err.file.patched.and.msp: m1x, m2x",
"1 error"
);
if (!expectedOut.equals(log))
throw new Exception("expected output not found: " + log);
}
@Test
public void testSourcePath(Path base) throws Exception {
//note: avoiding use of java.base, as that gets special handling on some places:
Path src = base.resolve("src");
tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, Other { }");
Path srcPath = base.resolve("src-path");
tb.writeJavaFiles(srcPath, "package javax.lang.model.element; interface Other { }");
Path classes = base.resolve("classes");
tb.createDirectories(classes);
List<String> log = new JavacTask(tb)
.options("--patch-module", "java.compiler=" + src.toString(),
"-sourcepath", srcPath.toString(),
"-XDrawDiagnostics")
.outdir(classes)
.files(src.resolve("javax/lang/model/element/Extra.java"))
.run(Expect.FAIL)
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
List<String> expectedOut = Arrays.asList(
"Extra.java:1:75: compiler.err.cant.resolve: kindname.class, Other, , ",
"1 error"
);
if (!expectedOut.equals(log))
throw new Exception("expected output not found: " + log);
} }
@Test @Test
@ -124,7 +240,7 @@ public class XModuleTest extends ModuleTestBase {
tb.createDirectories(classes); tb.createDirectories(classes);
List<String> log = new JavacTask(tb) List<String> log = new JavacTask(tb)
.options("-Xmodule:java.compiler", .options("--patch-module", "java.compiler=" + src.toString(),
"--class-path", cpClasses.toString(), "--class-path", cpClasses.toString(),
"-XDrawDiagnostics") "-XDrawDiagnostics")
.outdir(classes) .outdir(classes)
@ -152,16 +268,37 @@ public class XModuleTest extends ModuleTestBase {
Path classes = base.resolve("classes"); Path classes = base.resolve("classes");
tb.createDirectories(classes); tb.createDirectories(classes);
List<String> log = new JavacTask(tb) List<String> log;
.options("-XDrawDiagnostics", "-Xmodule:java.compiler") List<String> expected;
log = new JavacTask(tb)
.options("-XDrawDiagnostics",
"--patch-module", "java.compiler=" + src.toString())
.outdir(classes) .outdir(classes)
.files(findJavaFiles(src)) .files(findJavaFiles(src))
.run(Task.Expect.FAIL) .run(Task.Expect.FAIL)
.writeAll() .writeAll()
.getOutputLines(Task.OutputKind.DIRECT); .getOutputLines(Task.OutputKind.DIRECT);
List<String> expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.xmodule.sourcepath", expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.patched.module.sourcepath",
"1 error"); "1 error");
if (!expected.equals(log))
throw new Exception("expected output not found: " + log);
//multi-module mode:
log = new JavacTask(tb)
.options("-XDrawDiagnostics",
"--patch-module", "java.compiler=" + src.toString(),
"--module-source-path", "dummy")
.outdir(classes)
.files(findJavaFiles(src))
.run(Task.Expect.FAIL)
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
expected = Arrays.asList("- compiler.err.locn.module-info.not.allowed.on.patch.path: module-info.java",
"1 error");
if (!expected.equals(log)) if (!expected.equals(log))
throw new Exception("expected output not found: " + log); throw new Exception("expected output not found: " + log);
@ -173,7 +310,7 @@ public class XModuleTest extends ModuleTestBase {
Path srcMod = base.resolve("src-mod"); Path srcMod = base.resolve("src-mod");
tb.writeJavaFiles(srcMod, tb.writeJavaFiles(srcMod,
"module mod {}"); "module mod {}");
Path classes = base.resolve("classes"); Path classes = base.resolve("classes").resolve("java.compiler");
tb.createDirectories(classes); tb.createDirectories(classes);
String logMod = new JavacTask(tb) String logMod = new JavacTask(tb)
@ -192,62 +329,36 @@ public class XModuleTest extends ModuleTestBase {
"package javax.lang.model.element; public interface Extra { }"); "package javax.lang.model.element; public interface Extra { }");
tb.createDirectories(classes); tb.createDirectories(classes);
List<String> log = new JavacTask(tb) List<String> log;
.options("-XDrawDiagnostics", "-Xmodule:java.compiler") List<String> expected;
log = new JavacTask(tb)
.options("-XDrawDiagnostics",
"--patch-module", "java.compiler=" + src.toString())
.outdir(classes) .outdir(classes)
.files(findJavaFiles(src)) .files(findJavaFiles(src))
.run(Task.Expect.FAIL) .run(Task.Expect.FAIL)
.writeAll() .writeAll()
.getOutputLines(Task.OutputKind.DIRECT); .getOutputLines(Task.OutputKind.DIRECT);
List<String> expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.xmodule.classpath", expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.patched.module.classoutput",
"1 error"); "1 error");
if (!expected.equals(log)) if (!expected.equals(log))
throw new Exception("expected output not found: " + log); throw new Exception("expected output not found: " + log);
}
@Test log = new JavacTask(tb)
public void testModuleSourcePathXModule(Path base) throws Exception { .options("-XDrawDiagnostics",
//note: avoiding use of java.base, as that gets special handling on some places: "--patch-module", "java.compiler=" + src.toString(),
Path src = base.resolve("src"); "--module-source-path", "dummy")
tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }"); .outdir(classes.getParent())
Path classes = base.resolve("classes");
tb.createDirectories(classes);
List<String> log = new JavacTask(tb)
.options("-XDrawDiagnostics", "-Xmodule:java.compiler", "--module-source-path", src.toString())
.outdir(classes)
.files(findJavaFiles(src)) .files(findJavaFiles(src))
.run(Task.Expect.FAIL) .run(Task.Expect.FAIL)
.writeAll() .writeAll()
.getOutputLines(Task.OutputKind.DIRECT); .getOutputLines(Task.OutputKind.DIRECT);
List<String> expected = Arrays.asList("- compiler.err.xmodule.no.module.sourcepath"); expected = Arrays.asList("- compiler.err.locn.module-info.not.allowed.on.patch.path: module-info.class",
"1 error");
if (!expected.equals(log))
throw new Exception("expected output not found: " + log);
}
@Test
public void testXModuleTooMany(Path base) throws Exception {
//note: avoiding use of java.base, as that gets special handling on some places:
Path src = base.resolve("src");
tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }");
Path classes = base.resolve("classes");
tb.createDirectories(classes);
List<String> log = new JavacTask(tb, Task.Mode.CMDLINE)
.options("-XDrawDiagnostics", "-Xmodule:java.compiler", "-Xmodule:java.compiler")
.outdir(classes)
.files(findJavaFiles(src))
.run(Task.Expect.FAIL)
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT);
List<String> expected = Arrays.asList("javac: option -Xmodule: can only be specified once",
"Usage: javac <options> <source files>",
"use --help for a list of possible options");
if (!expected.equals(log)) if (!expected.equals(log))
throw new Exception("expected output not found: " + log); throw new Exception("expected output not found: " + log);
@ -266,7 +377,7 @@ public class XModuleTest extends ModuleTestBase {
new JavacTask(tb, Task.Mode.CMDLINE) new JavacTask(tb, Task.Mode.CMDLINE)
.options("--module-path", modules.toString(), .options("--module-path", modules.toString(),
"-Xmodule:m1") "--patch-module", "m1=" + src.toString())
.files(findJavaFiles(src)) .files(findJavaFiles(src))
.run() .run()
.writeAll(); .writeAll();
@ -282,7 +393,7 @@ public class XModuleTest extends ModuleTestBase {
List<String> log = new JavacTask(tb, Task.Mode.CMDLINE) List<String> log = new JavacTask(tb, Task.Mode.CMDLINE)
.options("-XDrawDiagnostics", .options("-XDrawDiagnostics",
"--module-path", modules.toString(), "--module-path", modules.toString(),
"-Xmodule:m1") "--patch-module", "m1=" + src2.toString())
.files(findJavaFiles(src2)) .files(findJavaFiles(src2))
.run(Task.Expect.FAIL) .run(Task.Expect.FAIL)
.writeAll() .writeAll()
@ -315,7 +426,7 @@ public class XModuleTest extends ModuleTestBase {
new JavacTask(tb, Task.Mode.CMDLINE) new JavacTask(tb, Task.Mode.CMDLINE)
.options("--module-path", modules.toString(), .options("--module-path", modules.toString(),
"--upgrade-module-path", upgrade.toString(), "--upgrade-module-path", upgrade.toString(),
"-Xmodule:m1") "--patch-module", "m1=" + src.toString())
.files(findJavaFiles(src)) .files(findJavaFiles(src))
.run() .run()
.writeAll(); .writeAll();
@ -365,7 +476,7 @@ public class XModuleTest extends ModuleTestBase {
tb.createDirectories(classes); tb.createDirectories(classes);
String log = new JavacTask(tb) String log = new JavacTask(tb)
.options("-Xmodule:m", .options("--patch-module", "m=" + sourcePath.toString(),
"--class-path", classPath.toString(), "--class-path", classPath.toString(),
"--source-path", sourcePath.toString(), "--source-path", sourcePath.toString(),
"--module-path", modulePath.toString(), "--module-path", modulePath.toString(),
@ -419,4 +530,165 @@ public class XModuleTest extends ModuleTestBase {
} }
} }
@Test
public void testSingleModeIncremental(Path base) throws Exception {
//note: avoiding use of java.base, as that gets special handling on some places:
Path src = base.resolve("src");
tb.writeJavaFiles(src,
"package javax.lang.model.element; public interface Extra extends Element { }",
"package javax.lang.model.element; public interface Extra2 extends Extra { }");
Path classes = base.resolve("classes");
tb.createDirectories(classes);
Thread.sleep(2000); //ensure newer timestamps on classfiles:
new JavacTask(tb)
.options("--patch-module", "java.compiler=" + src.toString())
.outdir(classes)
.files(findJavaFiles(src))
.run()
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
List<String> log = new JavacTask(tb)
.options("--patch-module", "java.compiler=" + src.toString(),
"-verbose")
.outdir(classes)
.files(findJavaFiles(src.resolve("javax/lang/model/element/Extra2.java"
.replace("/", src.getFileSystem().getSeparator()))))
.run()
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT)
.stream()
.filter(l -> l.contains("parsing"))
.collect(Collectors.toList());
boolean parsesExtra2 = log.stream()
.anyMatch(l -> l.contains("Extra2.java"));
boolean parsesExtra = log.stream()
.anyMatch(l -> l.contains("Extra.java"));
if (!parsesExtra2 || parsesExtra) {
throw new AssertionError("Unexpected output: " + log);
}
}
@Test
public void testComplexMSPAndPatch(Path base) throws Exception {
//note: avoiding use of java.base, as that gets special handling on some places:
Path src1 = base.resolve("src1");
Path src1ma = src1.resolve("ma");
tb.writeJavaFiles(src1ma,
"module ma { exports ma; }",
"package ma; public class C1 { public static void method() { } }",
"package ma.impl; public class C2 { }");
Path src1mb = src1.resolve("mb");
tb.writeJavaFiles(src1mb,
"module mb { requires ma; }",
"package mb.impl; public class C2 { public static void method() { } }");
Path src1mc = src1.resolve("mc");
tb.writeJavaFiles(src1mc,
"module mc { }");
Path classes1 = base.resolve("classes1");
tb.createDirectories(classes1);
tb.cleanDirectory(classes1);
new JavacTask(tb)
.options("--module-source-path", src1.toString())
.files(findJavaFiles(src1))
.outdir(classes1)
.run()
.writeAll();
//patching:
Path src2 = base.resolve("src2");
Path src2ma = src2.resolve("ma");
tb.writeJavaFiles(src2ma,
"package ma.impl; public class C2 { public static void extra() { ma.C1.method(); } }",
"package ma.impl; public class C3 { public void test() { C2.extra(); } }");
Path src2mb = src2.resolve("mb");
tb.writeJavaFiles(src2mb,
"package mb.impl; public class C3 { public void test() { C2.method(); ma.C1.method(); ma.impl.C2.extra(); } }");
Path src2mc = src2.resolve("mc");
tb.writeJavaFiles(src2mc,
"package mc.impl; public class C2 { public static void test() { } }",
//will require --add-reads ma:
"package mc.impl; public class C3 { public static void test() { ma.impl.C2.extra(); } }");
Path src2mt = src2.resolve("mt");
tb.writeJavaFiles(src2mt,
"module mt { requires ma; requires mb; }",
"package mt.impl; public class C2 { public static void test() { mb.impl.C2.method(); ma.impl.C2.extra(); } }",
"package mt.impl; public class C3 { public static void test() { C2.test(); mc.impl.C2.test(); } }");
Path classes2 = base.resolve("classes2");
tb.createDirectories(classes2);
tb.cleanDirectory(classes2);
Thread.sleep(2000); //ensure newer timestamps on classfiles:
new JavacTask(tb)
.options("--module-path", classes1.toString(),
"--patch-module", "ma=" + src2ma.toString(),
"--patch-module", "mb=" + src2mb.toString(),
"--add-exports", "ma/ma.impl=mb",
"--patch-module", "mc=" + src2mc.toString(),
"--add-reads", "mc=ma",
"--add-exports", "ma/ma.impl=mc",
"--add-exports", "ma/ma.impl=mt",
"--add-exports", "mb/mb.impl=mt",
"--add-exports", "mc/mc.impl=mt",
"--add-reads", "mt=mc",
"--module-source-path", src2.toString())
.outdir(classes2)
.files(findJavaFiles(src2))
.run()
.writeAll();
//incremental compilation (C2 mustn't be compiled, C3 must):
tb.writeJavaFiles(src2ma,
"package ma.impl; public class C3 { public void test() { ma.C1.method(); C2.extra(); } }");
tb.writeJavaFiles(src2mt,
"package mt.impl; public class C3 { public static void test() { mc.impl.C2.test(); C2.test(); } }");
List<String> log = new JavacTask(tb)
.options("--module-path", classes1.toString(),
"--patch-module", "ma=" + src2ma.toString(),
"--patch-module", "mb=" + src2mb.toString(),
"--add-exports", "ma/ma.impl=mb",
"--patch-module", "mc=" + src2mc.toString(),
"--add-reads", "mc=ma",
"--add-exports", "ma/ma.impl=mc",
"--add-exports", "ma/ma.impl=mt",
"--add-exports", "mb/mb.impl=mt",
"--add-exports", "mc/mc.impl=mt",
"--add-reads", "mt=mc",
"--module-source-path", src2.toString(),
"--add-modules", "mc",
"-verbose")
.outdir(classes2)
.files(src2ma.resolve("ma").resolve("impl").resolve("C3.java"),
src2mt.resolve("mt").resolve("impl").resolve("C3.java"))
.run()
.writeAll()
.getOutputLines(Task.OutputKind.DIRECT)
.stream()
.filter(l -> l.contains("parsing"))
.collect(Collectors.toList());
boolean parsesC3 = log.stream()
.anyMatch(l -> l.contains("C3.java"));
boolean parsesC2 = log.stream()
.anyMatch(l -> l.contains("C2.java"));
if (!parsesC3 || parsesC2) {
throw new AssertionError("Unexpected output: " + log);
}
}
private void checkFileExists(Path dir, String path) {
Path toCheck = dir.resolve(path.replace("/", dir.getFileSystem().getSeparator()));
if (!Files.exists(toCheck)) {
throw new AssertionError(toCheck.toString() + " does not exist!");
}
}
} }

View file

@ -177,7 +177,7 @@ public class InheritRuntimeEnvironmentTest extends ModuleTestBase {
Files.createDirectories(patch); Files.createDirectories(patch);
new JavacTask(tb) new JavacTask(tb)
.options("-Xmodule:java.base") .options("--patch-module", "java.base=" + patchSrc.toString())
.outdir(patch) .outdir(patch)
.sourcepath(patchSrc) .sourcepath(patchSrc)
.files(findJavaFiles(patchSrc)) .files(findJavaFiles(patchSrc))

View file

@ -28,7 +28,7 @@
* @library /tools/lib * @library /tools/lib
* @modules * @modules
* jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.file:+open * jdk.compiler/com.sun.tools.javac.file
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
* @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
* @run main PatchModulesTest * @run main PatchModulesTest
@ -38,21 +38,26 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.lang.reflect.Field; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.AbstractMap.SimpleEntry;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import javax.tools.ToolProvider; import javax.tools.ToolProvider;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import com.sun.source.util.JavacTask; import com.sun.source.util.JavacTask;
import com.sun.tools.javac.api.JavacTool; import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.file.BaseFileManager;
import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.file.Locations;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
@ -115,21 +120,29 @@ public class PatchModulesTest extends ModuleTestBase {
void test(List<String> patches, boolean expectOK, String expect) throws Exception { void test(List<String> patches, boolean expectOK, String expect) throws Exception {
JavacTool tool = (JavacTool) ToolProvider.getSystemJavaCompiler(); JavacTool tool = (JavacTool) ToolProvider.getSystemJavaCompiler();
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
try (PrintWriter pw = new PrintWriter(sw)) { try (PrintWriter pw = new PrintWriter(sw);
JavacFileManager fm = tool.getStandardFileManager(null, null, null); JavacFileManager fm = tool.getStandardFileManager(null, null, null)) {
List<String> opts = patches.stream() List<String> opts = patches.stream()
.map(p -> "--patch-module=" + p.replace(":", PS)) .map(p -> "--patch-module=" + p.replace(":", PS))
.collect(Collectors.toList()); .collect(Collectors.toList());
Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects("C.java"); Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects("C.java");
JavacTask task = tool.getTask(pw, fm, null, opts, null, files); JavacTask task = tool.getTask(pw, fm, null, opts, null, files);
Field locationsField = BaseFileManager.class.getDeclaredField("locations"); Map<String, List<Location>> mod2Location =
locationsField.setAccessible(true); StreamSupport.stream(fm.listLocationsForModules(StandardLocation.PATCH_MODULE_PATH)
Object locations = locationsField.get(fm); .spliterator(),
false)
.flatMap(sl -> sl.stream())
.collect(Collectors.groupingBy(l -> fm.inferModuleName(l)));
Field patchMapField = Locations.class.getDeclaredField("patchMap"); Map<String, List<String>> patchMap = mod2Location.entrySet()
patchMapField.setAccessible(true); .stream()
Map<?,?> patchMap = (Map<?,?>) patchMapField.get(locations); .map(e -> new SimpleEntry<>(e.getKey(), e.getValue().get(0)))
.map(e -> new SimpleEntry<>(e.getKey(), locationPaths(fm, e.getValue())))
.collect(Collectors.toMap(Entry :: getKey,
Entry :: getValue,
(v1, v2) -> {throw new IllegalStateException();},
TreeMap::new));
String found = patchMap.toString(); String found = patchMap.toString();
if (!found.equals(expect)) { if (!found.equals(expect)) {
@ -150,5 +163,34 @@ public class PatchModulesTest extends ModuleTestBase {
} }
} }
} }
static List<String> locationPaths(StandardJavaFileManager fm, Location loc) {
return StreamSupport.stream(fm.getLocationAsPaths(loc).spliterator(), false)
.map(p -> p.toString())
.collect(Collectors.toList());
}
@Test
public void testPatchWithSource(Path base) throws Exception {
Path patch = base.resolve("patch");
tb.writeJavaFiles(patch, "package javax.lang.model.element; public interface Extra { }");
Path src = base.resolve("src");
tb.writeJavaFiles(src,
"module m { requires java.compiler; }",
"package test; public interface Test extends javax.lang.model.element.Extra { }");
Path classes = base.resolve("classes");
tb.createDirectories(classes);
new toolbox.JavacTask(tb)
.options("--patch-module", "java.compiler=" + patch.toString())
.outdir(classes)
.files(findJavaFiles(src))
.run()
.writeAll();
if (Files.exists(classes.resolve("javax"))) {
throw new AssertionError();
}
}
} }

View file

@ -92,12 +92,17 @@ public class Main
File empty = new File("empty"); File empty = new File("empty");
empty.mkdirs(); empty.mkdirs();
// files to compile are in a separate directory from test to avoid
// confusing jtreg
File src = new File(testSrc, "src");
List<String> args = new ArrayList<String>(); List<String> args = new ArrayList<String>();
args.add("-classpath"); args.add("-classpath");
args.add("empty"); args.add("empty");
if (stdBootClassPath) { if (stdBootClassPath) {
args.add("-Xmodule:java.base"); args.add("--patch-module");
args.add("java.base=" + testSrc.getAbsolutePath());
} else { } else {
args.add("--system"); args.add("--system");
args.add("none"); args.add("none");
@ -108,9 +113,6 @@ public class Main
args.add("-d"); args.add("-d");
args.add("."); args.add(".");
// files to compile are in a separate directory from test to avoid
// confusing jtreg
File src = new File(testSrc, "src");
for (String f: files) for (String f: files)
args.add(new File(src, f).getPath()); args.add(new File(src, f).getPath());

View file

@ -63,7 +63,7 @@ public class RemovedJDKInternals {
Path sunMiscSrc = Paths.get(TEST_SRC, "patches", JDK_UNSUPPORTED); Path sunMiscSrc = Paths.get(TEST_SRC, "patches", JDK_UNSUPPORTED);
Path patchDir = PATCHES_DIR.resolve(JDK_UNSUPPORTED); Path patchDir = PATCHES_DIR.resolve(JDK_UNSUPPORTED);
assertTrue(CompilerUtils.compile(sunMiscSrc, patchDir, assertTrue(CompilerUtils.compile(sunMiscSrc, patchDir,
"-Xmodule:" + JDK_UNSUPPORTED)); "--patch-module", JDK_UNSUPPORTED + "=" + sunMiscSrc.toString()));
// compile com.sun.image.codec.jpeg types // compile com.sun.image.codec.jpeg types
Path codecSrc = Paths.get(TEST_SRC, "patches", "java.desktop"); Path codecSrc = Paths.get(TEST_SRC, "patches", "java.desktop");