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 * @summary Verify that upgradeable modules are not hashed in java.base
27 *          whereas non-upgradeable modules are.
28 * @modules java.base/jdk.internal.module
29 * @run main UpgradeableModules
30 */
31
32import jdk.internal.module.ModuleHashes;
33import jdk.internal.module.ModuleReferenceImpl;
34
35import java.lang.module.ModuleFinder;
36import java.lang.module.ModuleReference;
37import java.lang.module.ResolvedModule;
38import java.util.HashSet;
39import java.util.List;
40import java.util.Optional;
41import java.util.Set;
42import java.util.stream.Collectors;
43
44public class UpgradeableModules {
45    private static final List<String> UPGRADEABLE_MODULES =
46        List.of("java.activation",
47                "java.compiler",
48                "java.corba",
49                "java.jnlp",
50                "java.transaction",
51                "java.xml.bind",
52                "java.xml.ws",
53                "java.xml.ws.annotation",
54                "jdk.internal.vm.compiler",
55                "jdk.deploy",
56                "jdk.javaws",
57                "jdk.plugin",
58                "jdk.plugin.dom",
59                "jdk.xml.bind",
60                "jdk.xml.ws");
61
62    public static void main(String... args) {
63        Set<String> hashedModules = hashedModules();
64        if (hashedModules.isEmpty())
65            return;
66
67        if (UPGRADEABLE_MODULES.stream().anyMatch(hashedModules::contains)) {
68            throw new RuntimeException("upgradeable modules are hashed: " +
69                UPGRADEABLE_MODULES.stream()
70                    .filter(hashedModules::contains)
71                    .collect(Collectors.joining(" ")));
72        }
73
74        Set<String> nonUpgradeableModules =
75            ModuleFinder.ofSystem().findAll().stream()
76                .map(mref -> mref.descriptor().name())
77                .filter(mn -> !UPGRADEABLE_MODULES.contains(mn))
78                .collect(Collectors.toSet());
79
80        if (nonUpgradeableModules.stream().anyMatch(mn -> !hashedModules.contains(mn))) {
81            throw new RuntimeException("non-upgradeable modules are not hashed: " +
82                nonUpgradeableModules.stream()
83                    .filter(mn -> !hashedModules.contains(mn))
84                    .collect(Collectors.joining(" ")));
85        }
86    }
87
88    private static Set<String> hashedModules() {
89        Optional<ResolvedModule> resolvedModule = ModuleLayer.boot()
90            .configuration()
91            .findModule("java.base");
92        assert resolvedModule.isPresent();
93        ModuleReference mref = resolvedModule.get().reference();
94        assert mref instanceof ModuleReferenceImpl;
95        ModuleHashes hashes = ((ModuleReferenceImpl) mref).recordedHashes();
96        if (hashes != null) {
97            Set<String> names = new HashSet<>(hashes.names());
98            names.add("java.base");
99            return names;
100        }
101
102        return Set.of();
103    }
104}
105