< prev index next >
src/jdk.jartool/share/classes/sun/tools/jar/Main.java
Print this page
@@ -45,11 +45,10 @@
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.function.Consumer;
-import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.*;
@@ -58,19 +57,19 @@
import java.util.jar.Manifest;
import java.text.MessageFormat;
import jdk.internal.module.Checks;
import jdk.internal.module.ModuleHashes;
+import jdk.internal.module.ModuleHashesBuilder;
import jdk.internal.module.ModuleInfo;
import jdk.internal.module.ModuleInfoExtender;
import jdk.internal.module.ModuleResolution;
import jdk.internal.util.jar.JarIndex;
import static jdk.internal.util.jar.JarIndex.INDEX_NAME;
import static java.util.jar.JarFile.MANIFEST_NAME;
import static java.util.stream.Collectors.joining;
-import static java.util.stream.Collectors.toSet;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
/**
* This class implements a simple utility for creating files in the JAR
* (Java Archive) file format. The JAR format is based on the ZIP file
@@ -1928,12 +1927,11 @@
Hasher hasher = new Hasher(md, fname);
ModuleHashes moduleHashes = hasher.computeHashes(mn);
if (moduleHashes != null) {
extender.hashes(moduleHashes);
} else {
- // should it issue warning or silent?
- System.out.println("warning: no module is recorded in hash in " + mn);
+ warn("warning: no module is recorded in hash in " + mn);
}
}
if (moduleResolution.value() != 0) {
extender.moduleResolution(moduleResolution);
@@ -1945,14 +1943,13 @@
/**
* Compute and record hashes
*/
private class Hasher {
+ final ModuleHashesBuilder hashesBuilder;
final ModuleFinder finder;
- final Map<String, Path> moduleNameToPath;
final Set<String> modules;
- final Configuration configuration;
Hasher(ModuleDescriptor descriptor, String fname) throws IOException {
// Create a module finder that finds the modular JAR
// being created/updated
URI uri = Paths.get(fname).toUri();
ModuleReference mref = new ModuleReference(descriptor, uri) {
@@ -1978,121 +1975,48 @@
public Set<ModuleReference> findAll() {
return Collections.singleton(mref);
}
});
- // Determine the modules that matches the modulesToHash pattern
- this.modules = moduleFinder.findAll().stream()
- .map(moduleReference -> moduleReference.descriptor().name())
+ // Determine the modules that matches the pattern {@code modulesToHash}
+ Set<String> roots = finder.findAll().stream()
+ .map(ref -> ref.descriptor().name())
.filter(mn -> modulesToHash.matcher(mn).find())
.collect(Collectors.toSet());
- // a map from a module name to Path of the modular JAR
- this.moduleNameToPath = moduleFinder.findAll().stream()
- .map(ModuleReference::descriptor)
- .map(ModuleDescriptor::name)
- .collect(Collectors.toMap(Function.identity(), mn -> moduleToPath(mn)));
+ // use system module path unless it creates a modular JAR for
+ // a module that is present in the system image e.g. upgradeable
+ // module
+ ModuleFinder system;
+ String name = descriptor.name();
+ if (name != null && ModuleFinder.ofSystem().find(name).isPresent()) {
+ system = ModuleFinder.of();
+ } else {
+ system = ModuleFinder.ofSystem();
+ }
+ // get a resolved module graph
+ Configuration config =
+ Configuration.empty().resolveRequires(system, finder, roots);
+
+ // filter modules resolved from the system module finder
+ this.modules = config.modules().stream()
+ .map(ResolvedModule::name)
+ .filter(mn -> roots.contains(mn) && !system.find(mn).isPresent())
+ .collect(Collectors.toSet());
- Configuration config = null;
- try {
- config = Configuration.empty()
- .resolveRequires(ModuleFinder.ofSystem(), finder, modules);
- } catch (ResolutionException e) {
- // should it throw an error? or emit a warning
- System.out.println("warning: " + e.getMessage());
- }
- this.configuration = config;
+ this.hashesBuilder = new ModuleHashesBuilder(config, modules);
}
/**
- * Compute hashes of the modules that depend upon the specified
+ * Compute hashes of the specified module.
+ *
+ * It records the hashing modules that depend upon the specified
* module directly or indirectly.
*/
ModuleHashes computeHashes(String name) {
- // the transposed graph includes all modules in the resolved graph
- Map<String, Set<String>> graph = transpose();
-
- // find the modules that transitively depend upon the specified name
- Deque<String> deque = new ArrayDeque<>();
- deque.add(name);
- Set<String> mods = visitNodes(graph, deque);
-
- // filter modules matching the pattern specified in --hash-modules,
- // as well as the modular jar file that is being created / updated
- Map<String, Path> modulesForHash = mods.stream()
- .filter(mn -> !mn.equals(name) && modules.contains(mn))
- .collect(Collectors.toMap(Function.identity(), moduleNameToPath::get));
-
- if (modulesForHash.isEmpty())
+ if (hashesBuilder == null)
return null;
- return ModuleHashes.generate(modulesForHash, "SHA-256");
- }
-
- /**
- * Returns all nodes traversed from the given roots.
- */
- private Set<String> visitNodes(Map<String, Set<String>> graph,
- Deque<String> roots) {
- Set<String> visited = new HashSet<>();
- while (!roots.isEmpty()) {
- String mn = roots.pop();
- if (!visited.contains(mn)) {
- visited.add(mn);
-
- // the given roots may not be part of the graph
- if (graph.containsKey(mn)) {
- for (String dm : graph.get(mn)) {
- if (!visited.contains(dm))
- roots.push(dm);
- }
- }
- }
- }
- return visited;
- }
-
- /**
- * Returns a transposed graph from the resolved module graph.
- */
- private Map<String, Set<String>> transpose() {
- Map<String, Set<String>> transposedGraph = new HashMap<>();
- Deque<String> deque = new ArrayDeque<>(modules);
-
- Set<String> visited = new HashSet<>();
- while (!deque.isEmpty()) {
- String mn = deque.pop();
- if (!visited.contains(mn)) {
- visited.add(mn);
-
- // add an empty set
- transposedGraph.computeIfAbsent(mn, _k -> new HashSet<>());
-
- ResolvedModule resolvedModule = configuration.findModule(mn).get();
- for (ResolvedModule dm : resolvedModule.reads()) {
- String name = dm.name();
- if (!visited.contains(name)) {
- deque.push(name);
- }
- // reverse edge
- transposedGraph.computeIfAbsent(name, _k -> new HashSet<>())
- .add(mn);
- }
- }
- }
- return transposedGraph;
- }
-
- private Path moduleToPath(String name) {
- ModuleReference mref = moduleFinder.find(name).orElseThrow(
- () -> new InternalError(formatMsg2("error.hash.dep",name , name)));
-
- URI uri = mref.location().get();
- Path path = Paths.get(uri);
- String fn = path.getFileName().toString();
- if (!fn.endsWith(".jar")) {
- throw new UnsupportedOperationException(path + " is not a modular JAR");
- }
- return path;
+ return hashesBuilder.computeHashes(Set.of(name)).get(name);
}
}
}
< prev index next >