mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8233922: Service binding augments module graph with observable incubator modules
Reviewed-by: mchung
This commit is contained in:
parent
ec51784c0d
commit
745feb207c
11 changed files with 380 additions and 20 deletions
|
@ -312,7 +312,7 @@ public final class Configuration {
|
|||
{
|
||||
List<Configuration> parents = List.of(empty());
|
||||
Resolver resolver = new Resolver(finder, parents, ModuleFinder.of(), traceOutput);
|
||||
resolver.resolve(roots).bind();
|
||||
resolver.resolve(roots).bind(/*bindIncubatorModules*/false);
|
||||
return new Configuration(parents, resolver);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ package java.lang.module;
|
|||
import java.io.PrintStream;
|
||||
import java.lang.module.ModuleDescriptor.Provides;
|
||||
import java.lang.module.ModuleDescriptor.Requires.Modifier;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -45,6 +44,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import jdk.internal.module.ModuleHashes;
|
||||
import jdk.internal.module.ModuleReferenceImpl;
|
||||
import jdk.internal.module.ModuleResolution;
|
||||
import jdk.internal.module.ModuleTarget;
|
||||
|
||||
/**
|
||||
|
@ -215,15 +215,32 @@ final class Resolver {
|
|||
* service-use relation.
|
||||
*/
|
||||
Resolver bind() {
|
||||
return bind(/*bindIncubatorModules*/true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Augments the set of resolved modules with modules induced by the
|
||||
* service-use relation.
|
||||
*
|
||||
* @param bindIncubatorModules true if incubator modules are candidates to
|
||||
* add to the module graph
|
||||
*/
|
||||
Resolver bind(boolean bindIncubatorModules) {
|
||||
// Scan the finders for all available service provider modules. As
|
||||
// java.base uses services then the module finders will be scanned
|
||||
// anyway.
|
||||
Map<String, Set<ModuleReference>> availableProviders = new HashMap<>();
|
||||
for (ModuleReference mref : findAll()) {
|
||||
ModuleDescriptor descriptor = mref.descriptor();
|
||||
if (!descriptor.provides().isEmpty()) {
|
||||
|
||||
boolean candidate;
|
||||
if (!bindIncubatorModules && (mref instanceof ModuleReferenceImpl)) {
|
||||
ModuleResolution mres = ((ModuleReferenceImpl) mref).moduleResolution();
|
||||
candidate = (mres == null) || (mres.hasIncubatingWarning() == false);
|
||||
} else {
|
||||
candidate = true;
|
||||
}
|
||||
if (candidate && !descriptor.provides().isEmpty()) {
|
||||
for (Provides provides : descriptor.provides()) {
|
||||
String sn = provides.service();
|
||||
|
||||
|
|
|
@ -352,7 +352,7 @@ public final class ModuleBootstrap {
|
|||
|
||||
Configuration cf;
|
||||
if (needResolution) {
|
||||
cf = JLMA.resolveAndBind(finder, roots, traceOutput);
|
||||
cf = Modules.newBootLayerConfiguration(finder, roots, traceOutput);
|
||||
} else {
|
||||
if (archivedModuleGraph != null) {
|
||||
cf = archivedModuleGraph.configuration();
|
||||
|
|
|
@ -34,6 +34,7 @@ import java.util.stream.Stream;
|
|||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||
import jdk.internal.org.objectweb.asm.ModuleVisitor;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
import jdk.internal.org.objectweb.asm.commons.ModuleResolutionAttribute;
|
||||
import jdk.internal.org.objectweb.asm.commons.ModuleTargetAttribute;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
|
@ -78,7 +79,9 @@ public final class ModuleInfoWriter {
|
|||
* Writes the given module descriptor to a module-info.class file,
|
||||
* returning it in a byte array.
|
||||
*/
|
||||
private static byte[] toModuleInfo(ModuleDescriptor md, ModuleTarget target) {
|
||||
private static byte[] toModuleInfo(ModuleDescriptor md,
|
||||
ModuleResolution mres,
|
||||
ModuleTarget target) {
|
||||
ClassWriter cw = new ClassWriter(0);
|
||||
cw.visit(Opcodes.V10, ACC_MODULE, "module-info", null, null, null);
|
||||
|
||||
|
@ -147,6 +150,11 @@ public final class ModuleInfoWriter {
|
|||
|
||||
mv.visitEnd();
|
||||
|
||||
// write ModuleResolution attribute if specified
|
||||
if (mres != null) {
|
||||
cw.visitAttribute(new ModuleResolutionAttribute(mres.value()));
|
||||
}
|
||||
|
||||
// write ModuleTarget attribute if there is a target platform
|
||||
if (target != null && target.targetPlatform().length() > 0) {
|
||||
cw.visitAttribute(new ModuleTargetAttribute(target.targetPlatform()));
|
||||
|
@ -161,14 +169,39 @@ public final class ModuleInfoWriter {
|
|||
* module-info.class.
|
||||
*/
|
||||
public static void write(ModuleDescriptor descriptor,
|
||||
ModuleResolution mres,
|
||||
ModuleTarget target,
|
||||
OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
byte[] bytes = toModuleInfo(descriptor, target);
|
||||
byte[] bytes = toModuleInfo(descriptor, mres, target);
|
||||
out.write(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a module descriptor to the given output stream as a
|
||||
* module-info.class.
|
||||
*/
|
||||
public static void write(ModuleDescriptor descriptor,
|
||||
ModuleResolution mres,
|
||||
OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
write(descriptor, mres, null, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a module descriptor to the given output stream as a
|
||||
* module-info.class.
|
||||
*/
|
||||
public static void write(ModuleDescriptor descriptor,
|
||||
ModuleTarget target,
|
||||
OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
write(descriptor, null, target, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a module descriptor to the given output stream as a
|
||||
* module-info.class.
|
||||
|
@ -176,7 +209,7 @@ public final class ModuleInfoWriter {
|
|||
public static void write(ModuleDescriptor descriptor, OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
write(descriptor, null, out);
|
||||
write(descriptor, null, null, out);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,7 +217,7 @@ public final class ModuleInfoWriter {
|
|||
* in module-info.class format.
|
||||
*/
|
||||
public static ByteBuffer toByteBuffer(ModuleDescriptor descriptor) {
|
||||
byte[] bytes = toModuleInfo(descriptor, null);
|
||||
byte[] bytes = toModuleInfo(descriptor, null, null);
|
||||
return ByteBuffer.wrap(bytes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -25,6 +25,7 @@
|
|||
|
||||
package jdk.internal.module;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.lang.module.Configuration;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
|
@ -33,6 +34,7 @@ import java.lang.module.ResolvedModule;
|
|||
import java.net.URI;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
@ -40,6 +42,7 @@ import java.util.Set;
|
|||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jdk.internal.access.JavaLangModuleAccess;
|
||||
import jdk.internal.loader.BootLoader;
|
||||
import jdk.internal.loader.BuiltinClassLoader;
|
||||
import jdk.internal.loader.ClassLoaders;
|
||||
|
@ -61,6 +64,7 @@ public class Modules {
|
|||
private Modules() { }
|
||||
|
||||
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
|
||||
private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess();
|
||||
|
||||
/**
|
||||
* Creates a new Module. The module has the given ModuleDescriptor and
|
||||
|
@ -158,6 +162,20 @@ public class Modules {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a collection of root modules, with service binding and the empty
|
||||
* Configuration as the parent to create a Configuration for the boot layer.
|
||||
*
|
||||
* This method is intended to be used to create the Configuration for the
|
||||
* boot layer during startup or at a link-time.
|
||||
*/
|
||||
public static Configuration newBootLayerConfiguration(ModuleFinder finder,
|
||||
Collection<String> roots,
|
||||
PrintStream traceOutput)
|
||||
{
|
||||
return JLMA.resolveAndBind(finder, roots, traceOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the VM when code in the given Module has been transformed by
|
||||
* an agent and so may have been instrumented to call into supporting
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue