1/*
2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/**
25 * @test
26 * @modules java.xml
27 * @library /lib/testlibrary
28 * @build ValidateModulesTest JarUtils jdk.testlibrary.*
29 * @run testng ValidateModulesTest
30 * @summary Basic test for java --validate-modules
31 */
32
33import java.io.File;
34import java.io.IOException;
35import java.nio.file.Files;
36import java.nio.file.Path;
37
38import jdk.testlibrary.ProcessTools;
39import jdk.testlibrary.OutputAnalyzer;
40
41import org.testng.annotations.Test;
42import static org.testng.Assert.*;
43
44@Test
45public class ValidateModulesTest {
46
47    /**
48     * Test that the system modules validate.
49     */
50    public void testSystemModules() throws Exception {
51        run("--validate-modules")
52                .stdoutShouldContain("java.base")
53                .stdoutShouldContain("java.xml")
54                .shouldHaveExitValue(0);
55    }
56
57    /**
58     * Test an automatic module on the module path with classes in the same
59     * package as a system module.
60     */
61    public void testPackageConflict() throws Exception {
62        Path tmpdir = Files.createTempDirectory("tmp");
63
64        Path classes = Files.createDirectory(tmpdir.resolve("classes"));
65        touch(classes, "javax/xml/XMLConstants.class");
66        touch(classes, "javax/xml/parsers/SAXParser.class");
67
68        Path lib = Files.createDirectory(tmpdir.resolve("lib"));
69        JarUtils.createJarFile(lib.resolve("xml.jar"), classes);
70
71        int exitValue = run("-p", lib.toString(), "--validate-modules")
72                .shouldContain("xml automatic")
73                .shouldContain("conflicts with module java.xml")
74                .getExitValue();
75        assertTrue(exitValue != 0);
76
77    }
78
79    /**
80     * Test two modules with the same name in a directory.
81     */
82    public void testDuplicateModule() throws Exception {
83        Path tmpdir = Files.createTempDirectory("tmp");
84
85        Path classes = Files.createDirectory(tmpdir.resolve("classes"));
86        touch(classes, "org/foo/Bar.class");
87
88        Path lib = Files.createDirectory(tmpdir.resolve("lib"));
89        JarUtils.createJarFile(lib.resolve("foo-1.0.jar"), classes);
90        JarUtils.createJarFile(lib.resolve("foo-2.0.jar"), classes);
91
92        int exitValue = run("-p", lib.toString(), "--validate-modules")
93                .shouldContain("contains same module")
94                .getExitValue();
95        assertTrue(exitValue != 0);
96    }
97
98    /**
99     * Test two modules with the same name in different directories.
100     */
101    public void testShadowed() throws Exception {
102        Path tmpdir = Files.createTempDirectory("tmp");
103
104        Path classes = Files.createDirectory(tmpdir.resolve("classes"));
105        touch(classes, "org/foo/Bar.class");
106
107        Path lib1 = Files.createDirectory(tmpdir.resolve("lib1"));
108        JarUtils.createJarFile(lib1.resolve("foo-1.0.jar"), classes);
109
110        Path lib2 = Files.createDirectory(tmpdir.resolve("lib2"));
111        JarUtils.createJarFile(lib2.resolve("foo-2.0.jar"), classes);
112
113        run("-p", lib1 + File.pathSeparator + lib2, "--validate-modules")
114                .shouldContain("shadowed by")
115                .shouldHaveExitValue(0);
116    }
117
118    /**
119     * Runs the java launcher with the given arguments.
120     */
121    private OutputAnalyzer run(String... args) throws Exception {
122        return ProcessTools.executeTestJava(args)
123                .outputTo(System.out)
124                .errorTo(System.out);
125    }
126
127    /**
128     * Creates a file relative the given directory.
129     */
130    private void touch(Path dir, String relPath) throws IOException {
131        Path file = dir.resolve(relPath.replace('/', File.separatorChar));
132        Files.createDirectories(file.getParent());
133        Files.createFile(file);
134    }
135}
136