1.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java Fri Apr 07 15:46:31 2017 +0100
1.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java Mon Apr 10 11:08:59 2017 +0200
1.3 @@ -118,6 +118,7 @@
1.4 if (source.compareTo(Source.JDK1_9) >= 0) {
1.5 values.add(LintCategory.DEP_ANN);
1.6 }
1.7 + values.add(LintCategory.REQUIRES_TRANSITIVE_AUTOMATIC);
1.8 values.add(LintCategory.OPENS);
1.9 values.add(LintCategory.MODULE);
1.10 values.add(LintCategory.REMOVAL);
1.11 @@ -254,6 +255,16 @@
1.12 REMOVAL("removal"),
1.13
1.14 /**
1.15 + * Warn about use of automatic modules in the requires clauses.
1.16 + */
1.17 + REQUIRES_AUTOMATIC("requires-automatic"),
1.18 +
1.19 + /**
1.20 + * Warn about automatic modules in requires transitive.
1.21 + */
1.22 + REQUIRES_TRANSITIVE_AUTOMATIC("requires-transitive-automatic"),
1.23 +
1.24 + /**
1.25 * Warn about Serializable classes that do not provide a serial version ID.
1.26 */
1.27 SERIAL("serial"),
2.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Fri Apr 07 15:46:31 2017 +0100
2.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Mon Apr 10 11:08:59 2017 +0200
2.3 @@ -3908,4 +3908,16 @@
2.4 }
2.5 }
2.6
2.7 + void checkModuleRequires(final DiagnosticPosition pos, final RequiresDirective rd) {
2.8 + if ((rd.module.flags() & Flags.AUTOMATIC_MODULE) != 0) {
2.9 + deferredLintHandler.report(() -> {
2.10 + if (rd.isTransitive() && lint.isEnabled(LintCategory.REQUIRES_TRANSITIVE_AUTOMATIC)) {
2.11 + log.warning(pos, Warnings.RequiresTransitiveAutomatic);
2.12 + } else if (lint.isEnabled(LintCategory.REQUIRES_AUTOMATIC)) {
2.13 + log.warning(pos, Warnings.RequiresAutomatic);
2.14 + }
2.15 + });
2.16 + }
2.17 + }
2.18 +
2.19 }
3.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Fri Apr 07 15:46:31 2017 +0100
3.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Mon Apr 10 11:08:59 2017 +0200
3.3 @@ -1084,6 +1084,7 @@
3.4 public void visitRequires(JCRequires tree) {
3.5 if (tree.directive != null && allModules().contains(tree.directive.module)) {
3.6 chk.checkDeprecated(tree.moduleName.pos(), msym, tree.directive.module);
3.7 + chk.checkModuleRequires(tree.moduleName.pos(), tree.directive);
3.8 msym.directives = msym.directives.prepend(tree.directive);
3.9 }
3.10 }
4.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Apr 07 15:46:31 2017 +0100
4.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Apr 10 11:08:59 2017 +0200
4.3 @@ -1664,6 +1664,12 @@
4.4 compiler.warn.future.attr=\
4.5 {0} attribute introduced in version {1}.{2} class files is ignored in version {3}.{4} class files
4.6
4.7 +compiler.warn.requires.automatic=\
4.8 + requires directive for an automatic module
4.9 +
4.10 +compiler.warn.requires.transitive.automatic=\
4.11 + requires transitive directive for an automatic module
4.12 +
4.13 # Warnings related to annotation processing
4.14 # 0: string
4.15 compiler.warn.proc.package.does.not.exist=\
5.1 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties Fri Apr 07 15:46:31 2017 +0100
5.2 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties Mon Apr 10 11:08:59 2017 +0200
5.3 @@ -230,6 +230,12 @@
5.4 javac.opt.Xlint.desc.removal=\
5.5 Warn about use of API that has been marked for removal.
5.6
5.7 +javac.opt.Xlint.desc.requires-automatic=\
5.8 + Warn about use of automatic modules in the requires clauses.
5.9 +
5.10 +javac.opt.Xlint.desc.requires-transitive-automatic=\
5.11 + Warn about automatic modules in requires transitive.
5.12 +
5.13 javac.opt.Xlint.desc.serial=\
5.14 Warn about Serializable classes that do not provide a serial version ID. \n\
5.15 \ Also warn about access to non-public members from a serializable element.
6.1 --- a/test/tools/javac/diags/Example.java Fri Apr 07 15:46:31 2017 +0100
6.2 +++ b/test/tools/javac/diags/Example.java Mon Apr 10 11:08:59 2017 +0200
6.3 @@ -24,8 +24,18 @@
6.4 import java.io.*;
6.5 import java.net.URL;
6.6 import java.net.URLClassLoader;
6.7 +import java.nio.file.Files;
6.8 +import java.nio.file.Path;
6.9 import java.util.*;
6.10 +import java.util.Map.Entry;
6.11 +import java.util.jar.JarFile;
6.12 +import java.util.jar.JarOutputStream;
6.13 +import java.util.logging.Level;
6.14 +import java.util.logging.Logger;
6.15 import java.util.regex.*;
6.16 +import java.util.stream.Collectors;
6.17 +import java.util.zip.ZipEntry;
6.18 +
6.19 import javax.annotation.processing.Processor;
6.20 import javax.tools.Diagnostic;
6.21 import javax.tools.DiagnosticCollector;
6.22 @@ -210,9 +220,53 @@
6.23 File modulepathDir = new File(tempDir, "modulepath");
6.24 modulepathDir.mkdirs();
6.25 clean(modulepathDir);
6.26 - List<String> sOpts = Arrays.asList("-d", modulepathDir.getPath(),
6.27 - "--module-source-path", new File(file, "modulepath").getAbsolutePath());
6.28 - new Jsr199Compiler(verbose).run(null, null, false, sOpts, modulePathFiles);
6.29 + boolean hasModuleInfo =
6.30 + modulePathFiles.stream()
6.31 + .anyMatch(f -> f.getName().equalsIgnoreCase("module-info.java"));
6.32 + Path modulePath = new File(file, "modulepath").toPath().toAbsolutePath();
6.33 + if (hasModuleInfo) {
6.34 + //ordinary modules
6.35 + List<String> sOpts =
6.36 + Arrays.asList("-d", modulepathDir.getPath(),
6.37 + "--module-source-path", modulePath.toString());
6.38 + new Jsr199Compiler(verbose).run(null, null, false, sOpts, modulePathFiles);
6.39 + } else {
6.40 + //automatic modules:
6.41 + Map<String, List<Path>> module2Files =
6.42 + modulePathFiles.stream()
6.43 + .map(f -> f.toPath())
6.44 + .collect(Collectors.groupingBy(p -> modulePath.relativize(p)
6.45 + .getName(0)
6.46 + .toString()));
6.47 + for (Entry<String, List<Path>> e : module2Files.entrySet()) {
6.48 + File scratchDir = new File(tempDir, "scratch");
6.49 + scratchDir.mkdirs();
6.50 + clean(scratchDir);
6.51 + List<String> sOpts =
6.52 + Arrays.asList("-d", scratchDir.getPath());
6.53 + new Jsr199Compiler(verbose).run(null,
6.54 + null,
6.55 + false,
6.56 + sOpts,
6.57 + e.getValue().stream()
6.58 + .map(p -> p.toFile())
6.59 + .collect(Collectors.toList()));
6.60 + try (JarOutputStream jarOut =
6.61 + new JarOutputStream(new FileOutputStream(new File(modulepathDir, e.getKey() + ".jar")))) {
6.62 + Files.find(scratchDir.toPath(), Integer.MAX_VALUE, (p, attr) -> attr.isRegularFile())
6.63 + .forEach(p -> {
6.64 + try (InputStream in = Files.newInputStream(p)) {
6.65 + jarOut.putNextEntry(new ZipEntry(scratchDir.toPath()
6.66 + .relativize(p)
6.67 + .toString()));
6.68 + jarOut.write(in.readAllBytes());
6.69 + } catch (IOException ex) {
6.70 + throw new IllegalStateException(ex);
6.71 + }
6.72 + });
6.73 + }
6.74 + }
6.75 + }
6.76 opts.add("--module-path");
6.77 opts.add(modulepathDir.getAbsolutePath());
6.78 }
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/test/tools/javac/diags/examples/RequiresAutomatic/module-info.java Mon Apr 10 11:08:59 2017 +0200
7.3 @@ -0,0 +1,28 @@
7.4 +/*
7.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7.7 + *
7.8 + * This code is free software; you can redistribute it and/or modify it
7.9 + * under the terms of the GNU General Public License version 2 only, as
7.10 + * published by the Free Software Foundation.
7.11 + *
7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7.15 + * version 2 for more details (a copy is included in the LICENSE file that
7.16 + * accompanied this code).
7.17 + *
7.18 + * You should have received a copy of the GNU General Public License version
7.19 + * 2 along with this work; if not, write to the Free Software Foundation,
7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7.21 + *
7.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
7.23 + * or visit www.oracle.com if you need additional information or have any
7.24 + * questions.
7.25 + */
7.26 +
7.27 +//options: -Xlint:requires-automatic
7.28 +//key: compiler.warn.requires.automatic
7.29 +module RequiresAutomatic {
7.30 + requires a;
7.31 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/test/tools/javac/diags/examples/RequiresAutomatic/modulepath/a/A.java Mon Apr 10 11:08:59 2017 +0200
8.3 @@ -0,0 +1,24 @@
8.4 +/*
8.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8.7 + *
8.8 + * This code is free software; you can redistribute it and/or modify it
8.9 + * under the terms of the GNU General Public License version 2 only, as
8.10 + * published by the Free Software Foundation.
8.11 + *
8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
8.15 + * version 2 for more details (a copy is included in the LICENSE file that
8.16 + * accompanied this code).
8.17 + *
8.18 + * You should have received a copy of the GNU General Public License version
8.19 + * 2 along with this work; if not, write to the Free Software Foundation,
8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
8.21 + *
8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
8.23 + * or visit www.oracle.com if you need additional information or have any
8.24 + * questions.
8.25 + */
8.26 +
8.27 +public class A {}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/test/tools/javac/diags/examples/RequiresTransitiveAutomatic/module-info.java Mon Apr 10 11:08:59 2017 +0200
9.3 @@ -0,0 +1,27 @@
9.4 +/*
9.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9.7 + *
9.8 + * This code is free software; you can redistribute it and/or modify it
9.9 + * under the terms of the GNU General Public License version 2 only, as
9.10 + * published by the Free Software Foundation.
9.11 + *
9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9.15 + * version 2 for more details (a copy is included in the LICENSE file that
9.16 + * accompanied this code).
9.17 + *
9.18 + * You should have received a copy of the GNU General Public License version
9.19 + * 2 along with this work; if not, write to the Free Software Foundation,
9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
9.21 + *
9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
9.23 + * or visit www.oracle.com if you need additional information or have any
9.24 + * questions.
9.25 + */
9.26 +
9.27 +//key: compiler.warn.requires.transitive.automatic
9.28 +module RequiresTransitiveAutomatic {
9.29 + requires transitive a;
9.30 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/test/tools/javac/diags/examples/RequiresTransitiveAutomatic/modulepath/a/A.java Mon Apr 10 11:08:59 2017 +0200
10.3 @@ -0,0 +1,24 @@
10.4 +/*
10.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10.7 + *
10.8 + * This code is free software; you can redistribute it and/or modify it
10.9 + * under the terms of the GNU General Public License version 2 only, as
10.10 + * published by the Free Software Foundation.
10.11 + *
10.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
10.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10.15 + * version 2 for more details (a copy is included in the LICENSE file that
10.16 + * accompanied this code).
10.17 + *
10.18 + * You should have received a copy of the GNU General Public License version
10.19 + * 2 along with this work; if not, write to the Free Software Foundation,
10.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
10.21 + *
10.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
10.23 + * or visit www.oracle.com if you need additional information or have any
10.24 + * questions.
10.25 + */
10.26 +
10.27 +public class A {}
11.1 --- a/test/tools/javac/modules/AutomaticModules.java Fri Apr 07 15:46:31 2017 +0100
11.2 +++ b/test/tools/javac/modules/AutomaticModules.java Mon Apr 10 11:08:59 2017 +0200
11.3 @@ -23,7 +23,7 @@
11.4
11.5 /**
11.6 * @test
11.7 - * @bug 8155026
11.8 + * @bug 8155026 8178011
11.9 * @summary Test automatic modules
11.10 * @library /tools/lib
11.11 * @modules
11.12 @@ -423,4 +423,195 @@
11.13 .run()
11.14 .writeAll();
11.15 }
11.16 +
11.17 + @Test
11.18 + public void testLintRequireAutomatic(Path base) throws Exception {
11.19 + Path modulePath = base.resolve("module-path");
11.20 +
11.21 + Files.createDirectories(modulePath);
11.22 +
11.23 + for (char c : new char[] {'A', 'B'}) {
11.24 + Path automaticSrc = base.resolve("automaticSrc" + c);
11.25 + tb.writeJavaFiles(automaticSrc, "package api" + c + "; public class Api {}");
11.26 + Path automaticClasses = base.resolve("automaticClasses" + c);
11.27 + tb.createDirectories(automaticClasses);
11.28 +
11.29 + String automaticLog = new JavacTask(tb)
11.30 + .outdir(automaticClasses)
11.31 + .files(findJavaFiles(automaticSrc))
11.32 + .run()
11.33 + .writeAll()
11.34 + .getOutput(Task.OutputKind.DIRECT);
11.35 +
11.36 + if (!automaticLog.isEmpty())
11.37 + throw new Exception("expected output not found: " + automaticLog);
11.38 +
11.39 + Path automaticJar = modulePath.resolve("automatic" + c + "-1.0.jar");
11.40 +
11.41 + new JarTask(tb, automaticJar)
11.42 + .baseDir(automaticClasses)
11.43 + .files("api" + c + "/Api.class")
11.44 + .run();
11.45 + }
11.46 +
11.47 + Path src = base.resolve("src");
11.48 +
11.49 + tb.writeJavaFiles(src,
11.50 + "module m1x {\n" +
11.51 + " requires transitive automaticA;\n" +
11.52 + " requires automaticB;\n" +
11.53 + "}");
11.54 +
11.55 + Path classes = base.resolve("classes");
11.56 +
11.57 + Files.createDirectories(classes);
11.58 +
11.59 + List<String> expected;
11.60 + List<String> log;
11.61 +
11.62 + log = new JavacTask(tb)
11.63 + .options("--source-path", src.toString(),
11.64 + "--module-path", modulePath.toString(),
11.65 + "-XDrawDiagnostics",
11.66 + "-Werror")
11.67 + .outdir(classes)
11.68 + .files(findJavaFiles(src))
11.69 + .run(Task.Expect.FAIL)
11.70 + .writeAll()
11.71 + .getOutputLines(Task.OutputKind.DIRECT);
11.72 +
11.73 + expected = Arrays.asList("module-info.java:2:25: compiler.warn.requires.transitive.automatic",
11.74 + "- compiler.err.warnings.and.werror",
11.75 + "1 error",
11.76 + "1 warning");
11.77 +
11.78 + if (!expected.equals(log)) {
11.79 + throw new Exception("expected output not found: " + log);
11.80 + }
11.81 +
11.82 + log = new JavacTask(tb)
11.83 + .options("--source-path", src.toString(),
11.84 + "--module-path", modulePath.toString(),
11.85 + "-Xlint:requires-automatic",
11.86 + "-XDrawDiagnostics",
11.87 + "-Werror")
11.88 + .outdir(classes)
11.89 + .files(findJavaFiles(src))
11.90 + .run(Task.Expect.FAIL)
11.91 + .writeAll()
11.92 + .getOutputLines(Task.OutputKind.DIRECT);
11.93 +
11.94 + expected = Arrays.asList("module-info.java:2:25: compiler.warn.requires.transitive.automatic",
11.95 + "module-info.java:3:14: compiler.warn.requires.automatic",
11.96 + "- compiler.err.warnings.and.werror",
11.97 + "1 error",
11.98 + "2 warnings");
11.99 +
11.100 + if (!expected.equals(log)) {
11.101 + throw new Exception("expected output not found: " + log);
11.102 + }
11.103 +
11.104 + log = new JavacTask(tb)
11.105 + .options("--source-path", src.toString(),
11.106 + "--module-path", modulePath.toString(),
11.107 + "-Xlint:-requires-transitive-automatic,requires-automatic",
11.108 + "-XDrawDiagnostics",
11.109 + "-Werror")
11.110 + .outdir(classes)
11.111 + .files(findJavaFiles(src))
11.112 + .run(Task.Expect.FAIL)
11.113 + .writeAll()
11.114 + .getOutputLines(Task.OutputKind.DIRECT);
11.115 +
11.116 + expected = Arrays.asList("module-info.java:2:25: compiler.warn.requires.automatic",
11.117 + "module-info.java:3:14: compiler.warn.requires.automatic",
11.118 + "- compiler.err.warnings.and.werror",
11.119 + "1 error",
11.120 + "2 warnings");
11.121 +
11.122 + if (!expected.equals(log)) {
11.123 + throw new Exception("expected output not found: " + log);
11.124 + }
11.125 +
11.126 + new JavacTask(tb)
11.127 + .options("--source-path", src.toString(),
11.128 + "--module-path", modulePath.toString(),
11.129 + "-Xlint:-requires-transitive-automatic",
11.130 + "-XDrawDiagnostics",
11.131 + "-Werror")
11.132 + .outdir(classes)
11.133 + .files(findJavaFiles(src))
11.134 + .run(Task.Expect.SUCCESS)
11.135 + .writeAll()
11.136 + .getOutputLines(Task.OutputKind.DIRECT);
11.137 +
11.138 + tb.writeJavaFiles(src,
11.139 + "@SuppressWarnings(\"requires-transitive-automatic\")\n" +
11.140 + "module m1x {\n" +
11.141 + " requires transitive automaticA;\n" +
11.142 + " requires automaticB;\n" +
11.143 + "}");
11.144 +
11.145 + new JavacTask(tb)
11.146 + .options("--source-path", src.toString(),
11.147 + "--module-path", modulePath.toString(),
11.148 + "-XDrawDiagnostics",
11.149 + "-Werror")
11.150 + .outdir(classes)
11.151 + .files(findJavaFiles(src))
11.152 + .run(Task.Expect.SUCCESS)
11.153 + .writeAll()
11.154 + .getOutputLines(Task.OutputKind.DIRECT);
11.155 +
11.156 + log = new JavacTask(tb)
11.157 + .options("--source-path", src.toString(),
11.158 + "--module-path", modulePath.toString(),
11.159 + "-Xlint:requires-automatic",
11.160 + "-XDrawDiagnostics",
11.161 + "-Werror")
11.162 + .outdir(classes)
11.163 + .files(findJavaFiles(src))
11.164 + .run(Task.Expect.FAIL)
11.165 + .writeAll()
11.166 + .getOutputLines(Task.OutputKind.DIRECT);
11.167 +
11.168 + expected = Arrays.asList("module-info.java:3:25: compiler.warn.requires.automatic",
11.169 + "module-info.java:4:14: compiler.warn.requires.automatic",
11.170 + "- compiler.err.warnings.and.werror",
11.171 + "1 error",
11.172 + "2 warnings");
11.173 +
11.174 + if (!expected.equals(log)) {
11.175 + throw new Exception("expected output not found: " + log);
11.176 + }
11.177 +
11.178 + tb.writeJavaFiles(src,
11.179 + "@SuppressWarnings(\"requires-automatic\")\n" +
11.180 + "module m1x {\n" +
11.181 + " requires transitive automaticA;\n" +
11.182 + " requires automaticB;\n" +
11.183 + "}");
11.184 +
11.185 + log = new JavacTask(tb)
11.186 + .options("--source-path", src.toString(),
11.187 + "--module-path", modulePath.toString(),
11.188 + "-Xlint:requires-automatic",
11.189 + "-XDrawDiagnostics",
11.190 + "-Werror")
11.191 + .outdir(classes)
11.192 + .files(findJavaFiles(src))
11.193 + .run(Task.Expect.FAIL)
11.194 + .writeAll()
11.195 + .getOutputLines(Task.OutputKind.DIRECT);
11.196 +
11.197 + expected = Arrays.asList("module-info.java:3:25: compiler.warn.requires.transitive.automatic",
11.198 + "- compiler.err.warnings.and.werror",
11.199 + "1 error",
11.200 + "1 warning");
11.201 +
11.202 + if (!expected.equals(log)) {
11.203 + throw new Exception("expected output not found: " + log);
11.204 + }
11.205 + }
11.206 +
11.207 }