jdk

Форк
0
/
APIDeps.java 
214 строк · 8.2 Кб
1
/*
2
 * Copyright (c) 2012, 2024, 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
 * @bug 8015912 8029216 8048063 8050804
27
 * @summary Test -apionly and -jdkinternals options
28
 * @library lib
29
 * @modules java.base/sun.security.x509
30
 *          java.management
31
 *          jdk.jdeps/com.sun.tools.jdeps
32
 * @run main APIDeps
33
 */
34

35
import java.io.File;
36
import java.io.IOException;
37
import java.io.PrintWriter;
38
import java.io.StringWriter;
39
import java.nio.file.*;
40
import java.util.*;
41
import java.util.regex.*;
42
import java.util.stream.Collectors;
43

44
public class APIDeps {
45
    public static void main(String... args) throws Exception {
46
        int errors = 0;
47
        errors += new APIDeps().run();
48
        if (errors > 0)
49
            throw new Exception(errors + " errors found");
50
    }
51

52
    private static final Path dest = Paths.get(System.getProperty("test.classes", "."), "tmp");
53
    private static final String[] srcDirs = new String[] {
54
            "m", "b", "c", "d", "e", "f", "g"
55
    };
56
    void setup(Path dest) throws IOException {
57
        CompilerUtils.cleanDir(dest);
58
        Files.createDirectories(dest);
59
        Path testsrc = Paths.get(System.getProperty("test.src"));
60
        List<String> options = new ArrayList<>();
61

62
        // jdk.jdeps is a service provider module so needs to be explicitly included
63
        options.add("--add-modules=jdk.jdeps");
64

65
        // add --add-exports
66
        String testModules = System.getProperty("test.modules", "");
67
        List<String> addExports = new ArrayList<>();
68
        for (String s : testModules.split("\\s+")) {
69
            if (s.isEmpty()) continue;
70
            if (s.indexOf('/') != -1)
71
                addExports.add("--add-exports=" + s.trim() + "=ALL-UNNAMED");
72
        }
73
        options.addAll(addExports);
74

75
        for (String dir : srcDirs) {
76
            Path source = testsrc.resolve(dir);
77
            boolean ok = CompilerUtils.compile(source, dest, options.toArray(new String[0]));
78
            if (!ok) {
79
                throw new RuntimeException("compilation fails");
80
            }
81
        }
82
    }
83

84
    int run() throws IOException {
85
        // compile classes in a separate directory for analysis
86
        setup(dest);
87

88
        File testDir = dest.toFile();
89
        String testDirBasename = testDir.toPath().getFileName().toString();
90
        File mDir = new File(testDir, "m");
91
        // all dependencies
92
        test(new File(mDir, "Bar.class"),
93
             new String[] {"java.lang.Object", "java.lang.String",
94
                           "java.util.Set", "java.util.HashSet",
95
                           "java.lang.management.ManagementFactory",
96
                           "java.lang.management.RuntimeMXBean",
97
                           "b.B", "c.C", "d.D", "f.F", "g.G"},
98
             new String[] {"-classpath", testDir.getPath(), "-verbose"});
99
        test(new File(mDir, "Foo.class"),
100
             new String[] {"c.I", "e.E", "f.F"},
101
             new String[] {"-classpath", testDir.getPath(), "-verbose:class"});
102
        test(new File(mDir, "Foo.class"),
103
             new String[] {"c.I", "e.E", "f.F", "m.Bar"},
104
             new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-filter:none"});
105
        test(new File(mDir, "Gee.class"),
106
             new String[] {"g.G", "sun.security.x509.X509CertInfo", "com.sun.tools.jdeps.Analyzer",
107
                           "com.sun.management.ThreadMXBean", "com.sun.source.tree.BinaryTree"},
108
             new String[] {"-classpath", testDir.getPath(), "-verbose"});
109

110
        // -jdkinternals
111
        test(new File(mDir, "Gee.class"),
112
             new String[] {"sun.security.x509.X509CertInfo", "com.sun.tools.jdeps.Analyzer"},
113
             new String[] {"-jdkinternals", "-quiet"});
114
        // -jdkinternals parses all classes on -classpath and the input arguments
115
        test(new File(mDir, "Gee.class"),
116
             new String[] {"com.sun.tools.jdeps.Analyzer",
117
                           "sun.security.x509.X509CertInfo"},
118
             // use -classpath tmp/a with no use of JDK internal API
119
             new String[] {"-classpath", dest.resolve("a").toString(), "-jdkinternals", "-quiet"});
120

121
        // parse only APIs
122
        test(mDir,
123
             new String[] {"java.lang.Object", "java.lang.String",
124
                           "java.util.Set",
125
                           "c.C", "d.D", "c.I", "e.E"},
126
             new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-apionly"});
127

128
        test(mDir,
129
             new String[] {"java.lang.Object", "java.lang.String",
130
                           "java.util.Set",
131
                           "c.C", "d.D", "c.I", "e.E", "m.Bar"},
132
             new String[] {"-classpath", testDir.getPath(), "-verbose", "--api-only"});
133
        return errors;
134
    }
135

136
    void test(File file, String[] expect) {
137
        test(file, expect, new String[0]);
138
    }
139

140
    void test(File file, String[] expect, String[] options) {
141
        List<String> args = new ArrayList<>(Arrays.asList(options));
142
        if (file != null) {
143
            args.add(file.getPath());
144
        }
145
        checkResult("api-dependencies", expect,
146
                    jdeps(args.toArray(new String[0])).keySet());
147
    }
148

149
    Map<String,String> jdeps(String... args) {
150
        StringWriter sw = new StringWriter();
151
        PrintWriter pw = new PrintWriter(sw);
152
        System.err.println("jdeps " + Arrays.stream(args)
153
            .collect(Collectors.joining(" ")));
154
        int rc = com.sun.tools.jdeps.Main.run(args, pw);
155
        pw.close();
156
        String out = sw.toString();
157
        if (!out.isEmpty())
158
            System.err.println(out);
159
        if (rc != 0)
160
            throw new Error("jdeps failed: rc=" + rc);
161
        return findDeps(out);
162
    }
163

164
    // Pattern used to parse lines
165
    private static Pattern linePattern = Pattern.compile(".*\r?\n");
166
    private static Pattern pattern = Pattern.compile("\\s+ -> (\\S+) +(.*)");
167

168
    // Use the linePattern to break the given String into lines, applying
169
    // the pattern to each line to see if we have a match
170
    private static Map<String,String> findDeps(String out) {
171
        Map<String,String> result = new HashMap<>();
172
        Matcher lm = linePattern.matcher(out);  // Line matcher
173
        Matcher pm = null;                      // Pattern matcher
174
        int lines = 0;
175
        while (lm.find()) {
176
            lines++;
177
            CharSequence cs = lm.group();       // The current line
178
            if (pm == null)
179
                pm = pattern.matcher(cs);
180
            else
181
                pm.reset(cs);
182
            if (pm.find())
183
                result.put(pm.group(1), pm.group(2).trim());
184
            if (lm.end() == out.length())
185
                break;
186
        }
187
        return result;
188
    }
189

190
    void checkResult(String label, String[] expect, Collection<String> found) {
191
        // check the dependencies
192
        if (!isEqual(expect, found)) {
193
            error("Unexpected " + label + " found: '" + found +
194
                    "', expected: '" + Arrays.toString(expect) + "'");
195
        }
196
    }
197

198
    boolean isEqual(String[] expected, Collection<String> found) {
199
        if (expected.length != found.size())
200
            return false;
201

202
        List<String> list = new ArrayList<>(found);
203
        list.removeAll(Arrays.asList(expected));
204
        return list.isEmpty();
205
    }
206

207
    void error(String msg) {
208
        System.err.println("Error: " + msg);
209
        errors++;
210
    }
211

212
    int errors;
213

214
}
215

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.