AddReadsTest.java revision 3981:8be741555fa6
114287Spst/*
214287Spst * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
314287Spst * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
414287Spst *
514287Spst * This code is free software; you can redistribute it and/or modify it
614287Spst * under the terms of the GNU General Public License version 2 only, as
714287Spst * published by the Free Software Foundation.
814287Spst *
914287Spst * This code is distributed in the hope that it will be useful, but WITHOUT
1014287Spst * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1114287Spst * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1214287Spst * version 2 for more details (a copy is included in the LICENSE file that
1314287Spst * accompanied this code).
1414287Spst *
1514287Spst * You should have received a copy of the GNU General Public License version
1614287Spst * 2 along with this work; if not, write to the Free Software Foundation,
1714287Spst * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1814287Spst *
1914287Spst * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2014287Spst * or visit www.oracle.com if you need additional information or have any
2114287Spst * questions.
2214287Spst */
2314287Spst
2414287Spst/*
2514287Spst * @test
2614287Spst * @summary Test the --add-reads option
2714287Spst * @library /tools/lib
2814287Spst * @modules jdk.compiler/com.sun.tools.javac.api
2914287Spst *          jdk.compiler/com.sun.tools.javac.main
3014287Spst *          jdk.jdeps/com.sun.tools.javap
3114287Spst *          java.desktop
3214287Spst * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.JavapTask ModuleTestBase
3314287Spst * @run main AddReadsTest
3414287Spst */
3514287Spst
3614287Spstimport java.nio.file.Files;
3714287Spstimport java.nio.file.Path;
3814287Spstimport java.util.Set;
3914287Spst
4014287Spstimport javax.annotation.processing.AbstractProcessor;
4114287Spstimport javax.annotation.processing.RoundEnvironment;
4214287Spstimport javax.annotation.processing.SupportedAnnotationTypes;
4314287Spstimport javax.lang.model.SourceVersion;
4414287Spstimport javax.lang.model.element.ModuleElement;
4514287Spstimport javax.lang.model.element.ModuleElement.RequiresDirective;
4614287Spstimport javax.lang.model.element.TypeElement;
4714287Spstimport javax.lang.model.util.ElementFilter;
4814287Spst
4914287Spstimport toolbox.JarTask;
5014287Spstimport toolbox.JavacTask;
5114287Spstimport toolbox.JavapTask;
5214287Spstimport toolbox.Task;
5314287Spst
5414287Spstpublic class AddReadsTest extends ModuleTestBase {
5514287Spst
5614287Spst    public static void main(String... args) throws Exception {
5714287Spst        new AddReadsTest().runTests();
5814287Spst    }
5914287Spst
6014287Spst    @Test
6114287Spst    public void testAddReads(Path base) throws Exception {
6214287Spst        Path src = base.resolve("src");
6314287Spst        Path src_m1 = src.resolve("m1x");
6414287Spst        tb.writeJavaFiles(src_m1,
6514287Spst                          "module m1x { exports api; }",
6614287Spst                          "package api; public class Api { }");
6714287Spst        Path src_m2 = src.resolve("m2x");
6814287Spst        tb.writeJavaFiles(src_m2,
6914287Spst                          "module m2x { }",
7014287Spst                          "package test; public class Test extends api.Api { }");
7114287Spst        Path classes = base.resolve("classes");
7214287Spst        tb.createDirectories(classes);
7314287Spst
7414287Spst        String log = new JavacTask(tb)
7514287Spst                .options("-XDrawDiagnostics",
7614287Spst                         "--module-source-path", src.toString())
7714287Spst                .outdir(classes)
7814287Spst                .files(findJavaFiles(src))
7914287Spst                .run(Task.Expect.FAIL)
8014287Spst                .writeAll()
8114287Spst                .getOutput(Task.OutputKind.DIRECT);
8214287Spst
8314287Spst        checkOutputContains(log,
8414287Spst            "Test.java:1:41: compiler.err.package.not.visible: api, (compiler.misc.not.def.access.does.not.read: m2x, api, m1x)");
8514287Spst
8614287Spst        //test add dependencies:
8714287Spst        new JavacTask(tb)
8814287Spst                .options("--add-reads", "m2x=m1x",
8914287Spst                         "--module-source-path", src.toString(),
9014287Spst                         "-processor", VerifyRequires.class.getName())
9114287Spst                .outdir(classes)
9214287Spst                .files(findJavaFiles(src))
9314287Spst                .run()
9414287Spst                .writeAll();
9514287Spst
9614287Spst        String decompiled = new JavapTask(tb)
9714287Spst                .options("-verbose",
9814287Spst                        classes.resolve("m2x").resolve("module-info.class").toString())
9914287Spst                .run()
10014287Spst                .getOutput(Task.OutputKind.DIRECT);
10114287Spst
10214287Spst        if (decompiled.contains("m1x")) {
10314287Spst            throw new Exception("Incorrectly refers to m1x module.");
104        }
105
106        //cyclic dependencies OK when created through addReads:
107        new JavacTask(tb)
108                .options("--add-reads", "m2x=m1x",
109                         "--add-reads", "m1x=m2x",
110                         "--module-source-path", src.toString())
111                .outdir(classes)
112                .files(findJavaFiles(src))
113                .run()
114                .writeAll();
115
116        tb.writeJavaFiles(src_m2,
117                          "module m2x { requires m1x; }");
118
119        new JavacTask(tb)
120                .options("--add-reads", "m1x=m2x",
121                         "--module-source-path", src.toString())
122                .outdir(classes)
123                .files(findJavaFiles(src))
124                .run()
125                .writeAll();
126    }
127
128    @SupportedAnnotationTypes("*")
129    public static final class VerifyRequires extends AbstractProcessor {
130
131        @Override
132        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
133            ModuleElement m2Module = processingEnv.getElementUtils().getModuleElement("m2x");
134            if (m2Module == null) {
135                throw new AssertionError("Cannot find the m2x module!");
136            }
137            boolean foundM1 = false;
138            for (RequiresDirective rd : ElementFilter.requiresIn(m2Module.getDirectives())) {
139                foundM1 |= rd.getDependency().getSimpleName().contentEquals("m1x");
140            }
141            if (!foundM1) {
142                throw new AssertionError("Cannot find the dependency on m1x module!");
143            }
144            return false;
145        }
146
147        @Override
148        public SourceVersion getSupportedSourceVersion() {
149            return SourceVersion.latest();
150        }
151
152    }
153
154    @Test
155    public void testAddReadsUnnamedModule(Path base) throws Exception {
156        Path jar = prepareTestJar(base);
157
158        Path moduleSrc = base.resolve("module-src");
159        Path m1 = moduleSrc.resolve("m1x");
160
161        Path classes = base.resolve("classes");
162
163        Files.createDirectories(classes);
164
165        tb.writeJavaFiles(m1,
166                          "module m1x { }",
167                          "package impl; public class Impl { api.Api api; }");
168
169        new JavacTask(tb)
170          .options("--class-path", jar.toString(),
171                   "--add-reads", "m1x=ALL-UNNAMED",
172                   "-XDrawDiagnostics")
173          .outdir(classes)
174          .files(findJavaFiles(moduleSrc))
175          .run()
176          .writeAll();
177    }
178
179    @Test
180    public void testAddReadsUnnamedModulePackageConflict(Path base) throws Exception {
181        Path jar = prepareTestJar(base);
182
183        Path moduleSrc = base.resolve("module-src");
184        Path m1 = moduleSrc.resolve("m1x");
185
186        Path classes = base.resolve("classes");
187
188        Files.createDirectories(classes);
189
190        tb.writeJavaFiles(m1,
191                          "module m1x { }",
192                          "package api; public class Api { public static void test() { } }",
193                          "package impl; public class Impl { { api.Api.test(); } }");
194
195        new JavacTask(tb)
196          .options("--class-path", jar.toString(),
197                   "--module-source-path", moduleSrc.toString(),
198                   "--add-reads", "m1x=ALL-UNNAMED",
199                   "-XDrawDiagnostics")
200          .outdir(classes)
201          .files(m1.resolve("impl").resolve("Impl.java"))
202          .run()
203          .writeAll();
204    }
205
206    @Test
207    public void testAddReadsUnnamedToJavaBase(Path base) throws Exception {
208        Path jar = prepareTestJar(base);
209        Path src = base.resolve("src");
210        Path classes = base.resolve("classes");
211
212        Files.createDirectories(classes);
213
214        tb.writeJavaFiles(src,
215                          "package impl; public class Impl { api.Api a; }");
216
217        new JavacTask(tb)
218          .options("--class-path", jar.toString(),
219                   "--add-reads", "java.base=ALL-UNNAMED",
220                   "--patch-module", "java.base=" + src)
221          .outdir(classes)
222          .files(src.resolve("impl").resolve("Impl.java"))
223          .run()
224          .writeAll();
225    }
226
227    @Test
228    public void testAddReadsToJavaBase(Path base) throws Exception {
229        Path src = base.resolve("src");
230        Path classes = base.resolve("classes");
231
232        Files.createDirectories(classes);
233
234        tb.writeJavaFiles(src,
235                          "package impl; public class Impl { javax.swing.JButton b; }");
236
237        new JavacTask(tb)
238          .options("--add-modules", "java.desktop",
239                   "--add-reads", "java.base=java.desktop",
240                   "--patch-module", "java.base=" + src)
241          .outdir(classes)
242          .files(findJavaFiles(src))
243          .run()
244          .writeAll();
245    }
246
247    private Path prepareTestJar(Path base) throws Exception {
248        Path legacySrc = base.resolve("legacy-src");
249        tb.writeJavaFiles(legacySrc,
250                          "package api; public abstract class Api {}");
251        Path legacyClasses = base.resolve("legacy-classes");
252        Files.createDirectories(legacyClasses);
253
254        String log = new JavacTask(tb)
255                .options()
256                .outdir(legacyClasses)
257                .files(findJavaFiles(legacySrc))
258                .run()
259                .writeAll()
260                .getOutput(Task.OutputKind.DIRECT);
261
262        if (!log.isEmpty()) {
263            throw new Exception("unexpected output: " + log);
264        }
265
266        Path lib = base.resolve("lib");
267
268        Files.createDirectories(lib);
269
270        Path jar = lib.resolve("test-api-1.0.jar");
271
272        new JarTask(tb, jar)
273          .baseDir(legacyClasses)
274          .files("api/Api.class")
275          .run();
276
277        return jar;
278    }
279
280    @Test
281    public void testX(Path base) throws Exception {
282        Path src = base.resolve("src");
283        Path src_m1 = src.resolve("m1x");
284        tb.writeJavaFiles(src_m1,
285                          "module m1x { provides java.lang.Runnable with impl.Impl; }",
286                          "package impl; public class Impl implements Runnable { public void run() { } }");
287        Path classes = base.resolve("classes");
288        tb.createDirectories(classes);
289
290        new JavacTask(tb)
291                .options("--module-source-path", src.toString())
292                .outdir(classes)
293                .files(findJavaFiles(src))
294                .run()
295                .writeAll();
296
297        Path unnamedSrc = base.resolve("unnamed-src");
298        Path unnamedClasses = base.resolve("unnamed-classes");
299
300        Files.createDirectories(unnamedClasses);
301
302        tb.writeJavaFiles(unnamedSrc,
303                          "package impl; public class Impl { }");
304
305        new JavacTask(tb)
306          .options("--add-reads", "m1x=ALL-UNNAMED",
307                   "--patch-module", "m1x=" + unnamedSrc,
308                   "--module-path", classes.toString())
309          .outdir(unnamedClasses)
310          .files(findJavaFiles(unnamedSrc))
311          .run()
312          .writeAll();
313    }
314
315    @Test
316    public void testAddSelf(Path base) throws Exception {
317        Path src = base.resolve("src");
318        Path src_m1 = src.resolve("m1x");
319        tb.writeJavaFiles(src_m1,
320                          "module m1x { exports p1; }",
321                          "package p1; public class C1 { }");
322        Path classes = base.resolve("classes");
323        tb.createDirectories(classes);
324
325        new JavacTask(tb)
326                .options("--module-source-path", src.toString(),
327                         "--add-reads", "m1x=m1x")
328                .outdir(classes)
329                .files(findJavaFiles(src))
330                .run()
331                .writeAll();
332    }
333
334    @Test
335    public void testEmpty(Path base) throws Exception {
336        Path src = base.resolve("src");
337        tb.writeJavaFiles(src, "class Dummy { }");
338        Path classes = base.resolve("classes");
339        tb.createDirectories(classes);
340
341        testEmpty(src, classes, "--add-reads", "");
342        testEmpty(src, classes, "--add-reads=");
343    }
344
345    private void testEmpty(Path src, Path classes, String... options) throws Exception {
346        String log = new JavacTask(tb, Task.Mode.CMDLINE)
347                .options(options)
348                .outdir(classes)
349                .files(findJavaFiles(src))
350                .run(Task.Expect.FAIL)
351                .writeAll()
352                .getOutput(Task.OutputKind.DIRECT);
353
354        checkOutputContains(log,
355            "javac: no value for --add-reads option");
356    }
357
358    @Test
359    public void testEmptyItem(Path base) throws Exception {
360        Path src = base.resolve("src");
361        Path src_m1 = src.resolve("m1x");
362        tb.writeJavaFiles(src_m1,
363                          "module m1x { exports p1; }",
364                          "package p1; public class C1 { }");
365        Path src_m2 = src.resolve("m2x");
366        tb.writeJavaFiles(src_m2,
367                          "module m2x { }",
368                          "package p2; class C2 { }");
369        Path src_m3 = src.resolve("m3x");
370        tb.writeJavaFiles(src_m3,
371                          "module m3x { }",
372                          "package p3; class C3 { p1.C1 c1; }");
373        Path classes = base.resolve("classes");
374        tb.createDirectories(classes);
375
376        testEmptyItem(src, classes, "m3x=,m1x");
377        testEmptyItem(src, classes, "m3x=m1x,,m2x");
378        testEmptyItem(src, classes, "m3x=m1x,");
379    }
380
381    private void testEmptyItem(Path src, Path classes, String option) throws Exception {
382        new JavacTask(tb)
383                .options("--module-source-path", src.toString(),
384                         "--add-reads", option)
385                .outdir(classes)
386                .files(findJavaFiles(src))
387                .run()
388                .writeAll();
389    }
390
391    @Test
392    public void testEmptyList(Path base) throws Exception {
393        Path src = base.resolve("src");
394        Path src_m1 = src.resolve("m1x");
395        tb.writeJavaFiles(src_m1,
396                          "module m1x { exports p1; }",
397                          "package p1; public class C1 { }");
398        Path src_m2 = src.resolve("m2x");
399        tb.writeJavaFiles(src_m2,
400                          "module m2x { }",
401                          "package p2; class C2 { }");
402        Path src_m3 = src.resolve("m3x");
403        tb.writeJavaFiles(src_m3,
404                          "module m3x { }",
405                          "package p3; class C3 { p1.C1 c1; }");
406        Path classes = base.resolve("classes");
407        tb.createDirectories(classes);
408
409        testEmptyList(src, classes, "m3x=");
410        testEmptyList(src, classes, "m3x=,");
411    }
412
413    private void testEmptyList(Path src, Path classes, String option) throws Exception {
414        String log = new JavacTask(tb, Task.Mode.CMDLINE)
415                .options("--module-source-path", src.toString(),
416                         "--add-reads", option)
417                .outdir(classes)
418                .files(findJavaFiles(src))
419                .run(Task.Expect.FAIL)
420                .writeAll()
421                .getOutput(Task.OutputKind.DIRECT);
422
423        checkOutputContains(log,
424            "javac: bad value for --add-reads option: '" + option + "'");
425    }
426
427    @Test
428    public void testMultipleAddReads_DifferentModules(Path base) throws Exception {
429        Path src = base.resolve("src");
430        Path src_m1 = src.resolve("m1x");
431        tb.writeJavaFiles(src_m1,
432                          "module m1x { exports p1; }",
433                          "package p1; public class C1 { }");
434        Path src_m2 = src.resolve("m2x");
435        tb.writeJavaFiles(src_m2,
436                          "module m2x { }",
437                          "package p2; class C2 { p1.C1 c1; }");
438        Path src_m3 = src.resolve("m3x");
439        tb.writeJavaFiles(src_m3,
440                          "module m3x { }",
441                          "package p3; class C3 { p1.C1 c1; }");
442        Path classes = base.resolve("classes");
443        tb.createDirectories(classes);
444
445        new JavacTask(tb)
446                .options("--module-source-path", src.toString(),
447                         "--add-reads", "m2x=m1x",
448                         "--add-reads", "m3x=m1x")
449                .outdir(classes)
450                .files(findJavaFiles(src))
451                .run()
452                .writeAll();
453    }
454
455    @Test
456    public void testMultipleAddReads_SameModule(Path base) throws Exception {
457        Path src = base.resolve("src");
458        Path src_m1 = src.resolve("m1x");
459        tb.writeJavaFiles(src_m1,
460                          "module m1x { exports p1; }",
461                          "package p1; public class C1 { }");
462        Path src_m2 = src.resolve("m2x");
463        tb.writeJavaFiles(src_m2,
464                          "module m2x { exports p2; }",
465                          "package p2; public class C2 { }");
466        Path src_m3 = src.resolve("m3x");
467        tb.writeJavaFiles(src_m3,
468                          "module m3x { }",
469                          "package p3; class C3 { p1.C1 c1; p2.C2 c2; }");
470        Path classes = base.resolve("classes");
471        tb.createDirectories(classes);
472
473        new JavacTask(tb)
474                .options("--module-source-path", src.toString(),
475                         "--add-reads", "m3x=m1x",
476                         "--add-reads", "m3x=m2x")
477                .outdir(classes)
478                .files(findJavaFiles(src))
479                .run()
480                .writeAll();
481    }
482
483    @Test
484    public void testDuplicateAddReads_SameOption(Path base) throws Exception {
485        Path src = base.resolve("src");
486        Path src_m1 = src.resolve("m1x");
487        tb.writeJavaFiles(src_m1,
488                          "module m1x { exports p1; }",
489                          "package p1; public class C1 { }");
490        Path src_m2 = src.resolve("m2x");
491        tb.writeJavaFiles(src_m2,
492                          "module m2x { exports p2; }",
493                          "package p2; class C2 { p1.C1 c1; }");
494        Path classes = base.resolve("classes");
495        tb.createDirectories(classes);
496
497        new JavacTask(tb)
498                .options("--module-source-path", src.toString(),
499                         "--add-reads", "m2x=m1x,m1x")
500                .outdir(classes)
501                .files(findJavaFiles(src))
502                .run()
503                .writeAll();
504    }
505
506    @Test
507    public void testDuplicateAddReads_MultipleOptions(Path base) throws Exception {
508        Path src = base.resolve("src");
509        Path src_m1 = src.resolve("m1x");
510        tb.writeJavaFiles(src_m1,
511                          "module m1x { exports p1; }",
512                          "package p1; public class C1 { }");
513        Path src_m2 = src.resolve("m2x");
514        tb.writeJavaFiles(src_m2,
515                          "module m2x { }",
516                          "package p2; class C2 { p1.C1 c1; }");
517        Path classes = base.resolve("classes");
518        tb.createDirectories(classes);
519
520        new JavacTask(tb)
521                .options("--module-source-path", src.toString(),
522                         "--add-reads", "m2x=m1x",
523                         "--add-reads", "m2x=m1x")
524                .outdir(classes)
525                .files(findJavaFiles(src))
526                .run()
527                .writeAll();
528    }
529
530    @Test
531    public void testRepeatedAddReads(Path base) throws Exception {
532        Path src = base.resolve("src");
533        Path src_m1 = src.resolve("m1x");
534        tb.writeJavaFiles(src_m1,
535                          "module m1x { exports p1; }",
536                          "package p1; public class C1 { }");
537        Path src_m2 = src.resolve("m2x");
538        tb.writeJavaFiles(src_m2,
539                          "module m2x { exports p2; }",
540                          "package p2; public class C2 { }");
541        Path src_m3 = src.resolve("m3x");
542        tb.writeJavaFiles(src_m3,
543                          "module m3x { }",
544                          "package p3; class C3 { p1.C1 c1; p2.C2 c2; }");
545        Path classes = base.resolve("classes");
546        tb.createDirectories(classes);
547
548        new JavacTask(tb)
549                .options("--module-source-path", src.toString(),
550                         "--add-reads", "m3x=m1x",
551                         "--add-reads", "m3x=m2x")
552                .outdir(classes)
553                .files(findJavaFiles(src))
554                .run()
555                .writeAll();
556    }
557
558    @Test
559    public void testNoEquals(Path base) throws Exception {
560        Path src = base.resolve("src");
561        tb.writeJavaFiles(src, "class Dummy { }");
562        Path classes = base.resolve("classes");
563        tb.createDirectories(classes);
564
565        String log = new JavacTask(tb, Task.Mode.CMDLINE)
566                .options("-XDrawDiagnostics",
567                         "--add-reads", "m1x:m2x")
568                .outdir(classes)
569                .files(findJavaFiles(src))
570                .run(Task.Expect.FAIL)
571                .writeAll()
572                .getOutput(Task.OutputKind.DIRECT);
573
574        checkOutputContains(log,
575            "javac: bad value for --add-reads option: 'm1x:m2x'");
576    }
577
578    @Test
579    public void testBadSourceName(Path base) throws Exception {
580        Path src = base.resolve("src");
581        tb.writeJavaFiles(src, "class Dummy { }");
582        Path classes = base.resolve("classes");
583        tb.createDirectories(classes);
584
585        String log = new JavacTask(tb)
586                .options("-XDrawDiagnostics",
587                         "--add-reads", "bad*Source=m2x")
588                .outdir(classes)
589                .files(findJavaFiles(src))
590                .run()
591                .writeAll()
592                .getOutput(Task.OutputKind.DIRECT);
593
594        checkOutputContains(log,
595            "- compiler.warn.bad.name.for.option: --add-reads, bad*Source");
596    }
597
598    @Test
599    public void testBadTargetName(Path base) throws Exception {
600        Path src = base.resolve("src");
601        Path src_m1 = src.resolve("m1x");
602        tb.writeJavaFiles(src_m1,
603                          "module m1x { }",
604                          "package p1; class C1 { }");
605        Path classes = base.resolve("classes");
606        tb.createDirectories(classes);
607
608        String log = new JavacTask(tb)
609                .options("-XDrawDiagnostics",
610                         "--add-reads", "m1x=badTarget!")
611                .outdir(classes)
612                .files(findJavaFiles(src))
613                .run()
614                .writeAll()
615                .getOutput(Task.OutputKind.DIRECT);
616
617        checkOutputContains(log,
618            "- compiler.warn.bad.name.for.option: --add-reads, badTarget!");
619    }
620
621    @Test
622    public void testSourceNameNotFound(Path base) throws Exception {
623        Path src = base.resolve("src");
624        Path src_m1 = src.resolve("m1x");
625        tb.writeJavaFiles(src_m1,
626                          "module m1x { exports p1; }",
627                          "package p1; public class C1 { }");
628        Path classes = base.resolve("classes");
629        tb.createDirectories(classes);
630
631        String log = new JavacTask(tb)
632                .options("-XDrawDiagnostics",
633                         "--add-reads", "missingSource=m")
634                .outdir(classes)
635                .files(findJavaFiles(src))
636                .run()
637                .writeAll()
638                .getOutput(Task.OutputKind.DIRECT);
639
640        checkOutputContains(log,
641            "- compiler.warn.module.for.option.not.found: --add-reads, missingSource");
642    }
643
644    @Test
645    public void testTargetNameNotFound(Path base) throws Exception {
646        Path src = base.resolve("src");
647        Path src_m1 = src.resolve("m1x");
648        tb.writeJavaFiles(src_m1,
649                          "module m1x { exports p1; }",
650                          "package p1; public class C1 { }");
651        Path classes = base.resolve("classes");
652        tb.createDirectories(classes);
653
654        String log = new JavacTask(tb)
655                .options("-XDrawDiagnostics",
656                         "--add-reads", "m1x=missingTarget")
657                .outdir(classes)
658                .files(findJavaFiles(src))
659                .run()
660                .writeAll()
661                .getOutput(Task.OutputKind.DIRECT);
662
663        checkOutputContains(log,
664            "- compiler.warn.module.for.option.not.found: --add-reads, missingTarget");
665    }
666}
667