Skip to content

Commit

Permalink
Incubating model resover: Do not load the workspace when the original…
Browse files Browse the repository at this point in the history
… resolver is not aware of it
  • Loading branch information
Alexey Loubyansky committed Nov 18, 2024
1 parent 6e4206e commit d1025fd
Showing 1 changed file with 115 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -141,21 +141,45 @@ public static IncubatingApplicationModelResolver newInstance() {
private List<Dependency> collectCompileOnly;
private boolean runtimeModelOnly;

/**
* Maven artifact resolver that should be used to resolve application dependencies
*
* @param resolver Maven artifact resolver
* @return self
*/
public IncubatingApplicationModelResolver setArtifactResolver(MavenArtifactResolver resolver) {
this.resolver = resolver;
return this;
}

/**
* Application model builder to add the resolved dependencies to.
*
* @param appBuilder application model builder
* @return self
*/
public IncubatingApplicationModelResolver setApplicationModelBuilder(ApplicationModelBuilder appBuilder) {
this.appBuilder = appBuilder;
return this;
}

/**
* Whether to indicate which resolved dependencies are reloadable.
*
* @param collectReloadableModules whether indicate which resolved dependencies are reloadable
* @return self
*/
public IncubatingApplicationModelResolver setCollectReloadableModules(boolean collectReloadableModules) {
this.collectReloadableModules = collectReloadableModules;
return this;
}

/**
* Dependency logging configuration. For example to log the resolved dependency tree.
*
* @param depLogging dependency logging configuration
* @return self
*/
public IncubatingApplicationModelResolver setDependencyLogging(DependencyLoggingConfig depLogging) {
this.depLogging = depLogging;
return this;
Expand All @@ -173,11 +197,23 @@ public IncubatingApplicationModelResolver setCollectCompileOnly(List<Dependency>
return this;
}

/**
* Whether to include only the runtime dependencies in the resulting model.
*
* @param runtimeModelOnly whether to include only the runtime dependencies in the resulting model
* @return self
*/
public IncubatingApplicationModelResolver setRuntimeModelOnly(boolean runtimeModelOnly) {
this.runtimeModelOnly = runtimeModelOnly;
return this;
}

/**
* Resolves application dependencies and adds the to the application model builder.
*
* @param collectRtDepsRequest request to collect runtime dependencies
* @throws AppModelResolverException in case of a failure
*/
public void resolve(CollectRequest collectRtDepsRequest) throws AppModelResolverException {
this.managedDeps = collectRtDepsRequest.getManagedDependencies();
// managed dependencies will be a bit augmented with every added extension, so let's load the properties early
Expand Down Expand Up @@ -243,9 +279,7 @@ private List<ConditionalDependency> activateConditionalDeps() {

private void populateModelBuilder(DependencyNode root) {
var app = new AppDep(root);
final ModelResolutionTaskRunner taskRunner = new ModelResolutionTaskRunner();
app.scheduleChildVisits(taskRunner, AppDep::scheduleDeploymentVisit);
taskRunner.waitForCompletion();
initMissingDependencies(app);
appBuilder.getApplicationArtifact().addDependencies(app.allDeps);
for (var d : app.children) {
d.addToModel();
Expand All @@ -255,6 +289,12 @@ private void populateModelBuilder(DependencyNode root) {
}
}

private void initMissingDependencies(AppDep app) {
final ModelResolutionTaskRunner taskRunner = new ModelResolutionTaskRunner();
app.scheduleChildVisits(taskRunner, AppDep::initMissingDependencies);
taskRunner.waitForCompletion();
}

private void injectDeployment(List<ConditionalDependency> activatedConditionalDeps) {
final ConcurrentLinkedDeque<Runnable> injectQueue = new ConcurrentLinkedDeque<>();
// non-conditional deployment branches should be added before the activated conditional ones to have consistent
Expand Down Expand Up @@ -287,17 +327,18 @@ private void collectDeploymentDeps(ConcurrentLinkedDeque<Runnable> injectQueue)

private void injectDeploymentDep(ModelResolutionTaskRunner taskRunner, ExtensionDependency extDep,
ConcurrentLinkedDeque<Runnable> injectQueue, boolean conditionalDep) {
taskRunner.run(() -> {
var resolvedDep = appBuilder.getDependency(getKey(extDep.info.deploymentArtifact));
if (resolvedDep == null) {
var resolvedDep = appBuilder.getDependency(getKey(extDep.info.deploymentArtifact));
if (resolvedDep == null) {
taskRunner.run(() -> {
extDep.collectDeploymentDeps();
injectQueue.add(() -> extDep.injectDeploymentNode(conditionalDep ? extDep.getParentDeploymentNode() : null));
} else {
// if resolvedDep isn't null, it means the deployment artifact is on the runtime classpath
// in which case we also clear the reloadable flag on it, in case it's coming from the workspace
resolvedDep.clearFlag(DependencyFlags.RELOADABLE);
}
});
injectQueue
.add(() -> extDep.injectDeploymentNode(conditionalDep ? extDep.getParentDeploymentNode() : null));
});
} else {
// if resolvedDep isn't null, it means the deployment artifact is on the runtime classpath
// in which case we also clear its reloadable flag, in case it's coming from the workspace
resolvedDep.clearFlag(DependencyFlags.RELOADABLE);
}
}

/**
Expand Down Expand Up @@ -372,6 +413,12 @@ private void collectCompileOnly(CollectRequest collectRtDepsRequest, DependencyN
}
}

/**
* Collects platform release information and platform build properties by looking for platform properties
* artifacts among the dependency version constraints of the project (it's not a direct dependency).
*
* @throws AppModelResolverException in case a properties artifact could not be resolved
*/
private void collectPlatformProperties() throws AppModelResolverException {
final PlatformImportsImpl platformReleases = new PlatformImportsImpl();
for (Dependency d : managedDeps) {
Expand Down Expand Up @@ -419,6 +466,14 @@ private DependencyNode normalize(RepositorySystemSession session, DependencyNode
}
}

/**
* Resolves a project's runtime dependencies. This is the first step in the Quarkus application model resolution.
* These dependencies do not include Quarkus conditional dependencies.
*
* @param request collect dependencies request
* @return the root of the resolved dependency tree
* @throws AppModelResolverException in case dependencies could not be resolved
*/
private DependencyNode resolveRuntimeDeps(CollectRequest request)
throws AppModelResolverException {
boolean verbose = true; //Boolean.getBoolean("quarkus.bootstrap.verbose-model-resolver");
Expand All @@ -435,7 +490,8 @@ private DependencyNode resolveRuntimeDeps(CollectRequest request)
.setRemoteRepositories(resolver.getRepositories())
.setRemoteRepositoryManager(resolver.getRemoteRepositoryManager())
.setCurrentProject(resolver.getMavenContext().getCurrentProject())
.setWorkspaceDiscovery(collectReloadableModules));
// no need to discover the workspace in case the current project isn't available
.setWorkspaceDiscovery(resolver.getMavenContext().getCurrentProject() != null));
resolver = new MavenArtifactResolver(ctx);
}
try {
Expand All @@ -453,14 +509,11 @@ private boolean isRuntimeArtifact(ArtifactKey key) {

private void processRuntimeDeps(DependencyNode root) {
final AppDep appRoot = new AppDep(root);
appRoot.walkingFlags = COLLECT_TOP_EXTENSION_RUNTIME_NODES | COLLECT_DIRECT_DEPS;
if (collectReloadableModules) {
appRoot.walkingFlags |= COLLECT_RELOADABLE_MODULES;
}

visitRuntimeDeps(appRoot);
appBuilder.getApplicationArtifact().addDependencies(appRoot.allDeps);
appRoot.setChildFlags();
appRoot.setChildFlags(
(byte) (COLLECT_TOP_EXTENSION_RUNTIME_NODES | COLLECT_DIRECT_DEPS |
(collectReloadableModules ? COLLECT_RELOADABLE_MODULES : 0)));
}

private void visitRuntimeDeps(AppDep appRoot) {
Expand All @@ -473,7 +526,6 @@ private class AppDep {
final AppDep parent;
final DependencyNode node;
ExtensionDependency ext;
byte walkingFlags;
ResolvedDependencyBuilder resolvedDep;
final List<AppDep> children;
final List<ArtifactCoords> allDeps;
Expand Down Expand Up @@ -503,18 +555,18 @@ void addToModel() {
}
}

void scheduleDeploymentVisit(ModelResolutionTaskRunner taskRunner) {
taskRunner.run(this::visitDeploymentDependency);
scheduleChildVisits(taskRunner, AppDep::scheduleDeploymentVisit);
void initMissingDependencies(ModelResolutionTaskRunner taskRunner) {
if (!appBuilder.hasDependency(getKey(node.getArtifact()))) {
taskRunner.run(this::initDependencyBuilder);
}
scheduleChildVisits(taskRunner, AppDep::initMissingDependencies);
}

void visitDeploymentDependency() {
if (!appBuilder.hasDependency(getKey(node.getArtifact()))) {
try {
resolvedDep = newDependencyBuilder(node, resolver);
} catch (BootstrapMavenException e) {
throw new RuntimeException(e);
}
void initDependencyBuilder() {
try {
resolvedDep = newDependencyBuilder(node, resolver);
} catch (BootstrapMavenException e) {
throw new RuntimeException(e);
}
}

Expand Down Expand Up @@ -592,7 +644,7 @@ void scheduleChildVisits(ModelResolutionTaskRunner taskRunner,
}
}

void setChildFlags() {
void setChildFlags(byte walkingFlags) {
for (var c : children) {
c.setFlags(walkingFlags);
}
Expand Down Expand Up @@ -622,25 +674,24 @@ void setFlags(byte walkingFlags) {
} else if (existingDep != resolvedDep) {
throw new IllegalStateException(node.getArtifact() + " is already in the model");
}
this.walkingFlags = walkingFlags;

resolvedDep.setDirect(isWalkingFlagOn(COLLECT_DIRECT_DEPS));
if (ext != null && isWalkingFlagOn(COLLECT_TOP_EXTENSION_RUNTIME_NODES)) {
resolvedDep.setDirect(isFlagOn(walkingFlags, COLLECT_DIRECT_DEPS));
if (ext != null && isFlagOn(walkingFlags, COLLECT_TOP_EXTENSION_RUNTIME_NODES)) {
resolvedDep.setFlags(DependencyFlags.TOP_LEVEL_RUNTIME_EXTENSION_ARTIFACT);
clearWalkingFlag(COLLECT_TOP_EXTENSION_RUNTIME_NODES);
walkingFlags = clearFlag(walkingFlags, COLLECT_TOP_EXTENSION_RUNTIME_NODES);
topExtensionDeps.add(ext);
}
if (isWalkingFlagOn(COLLECT_RELOADABLE_MODULES)) {
if (isFlagOn(walkingFlags, COLLECT_RELOADABLE_MODULES)) {
if (resolvedDep.getWorkspaceModule() != null
&& !resolvedDep.isFlagSet(DependencyFlags.RUNTIME_EXTENSION_ARTIFACT)) {
resolvedDep.setReloadable();
} else {
clearWalkingFlag(COLLECT_RELOADABLE_MODULES);
walkingFlags = clearFlag(walkingFlags, COLLECT_RELOADABLE_MODULES);
}
}

clearWalkingFlag(COLLECT_DIRECT_DEPS);
setChildFlags();
walkingFlags = clearFlag(walkingFlags, COLLECT_DIRECT_DEPS);
setChildFlags(walkingFlags);
}

private ExtensionDependency getExtensionDependencyOrNull()
Expand Down Expand Up @@ -692,16 +743,6 @@ Artifact getResolvedArtifact() {
return result;
}

private boolean isWalkingFlagOn(byte flag) {
return (walkingFlags & flag) > 0;
}

private void clearWalkingFlag(byte flag) {
if ((walkingFlags & flag) > 0) {
walkingFlags ^= flag;
}
}

private void collectConditionalDependencies()
throws BootstrapDependencyProcessingException {
if (ext.info.conditionalDeps.length == 0 || ext.conditionalDepsQueued) {
Expand Down Expand Up @@ -732,6 +773,14 @@ private void collectConditionalDependencies()
}
}

private static byte clearFlag(byte flags, byte flag) {
return (flags & flag) > 0 ? (byte) (flags ^ flag) : flags;
}

private static boolean isFlagOn(byte flags, byte flag) {
return (flags & flag) > 0;
}

private ExtensionInfo getExtensionInfoOrNull(Artifact artifact, List<RemoteRepository> repos)
throws BootstrapDependencyProcessingException {
if (!artifact.getExtension().equals(ArtifactCoords.TYPE_JAR)) {
Expand Down Expand Up @@ -1047,6 +1096,18 @@ void activate() {
return;
}
activated = true;
final DefaultDependencyNode rtNode = addRuntimeDependency();
visitRuntimeDeps();
conditionalDep.setFlags(collectReloadableModules ? COLLECT_RELOADABLE_MODULES : 0);
if (conditionalDep.parent.resolvedDep == null) {
conditionalDep.parent.allDeps.add(conditionalDep.resolvedDep.getArtifactCoords());
} else {
conditionalDep.parent.resolvedDep.addDependency(conditionalDep.resolvedDep.getArtifactCoords());
}
conditionalDep.parent.ext.runtimeNode.getChildren().add(rtNode);
}

private DefaultDependencyNode addRuntimeDependency() {
final ExtensionDependency extDep = getExtensionDependency();
final DependencyNode originalNode = collectDependencies(conditionalDep.ext.info.runtimeArtifact, extDep.exclusions,
extDep.runtimeNode.getRepositories());
Expand All @@ -1060,19 +1121,13 @@ void activate() {
} else {
currentChildren.addAll(originalNode.getChildren());
}
if (collectReloadableModules) {
conditionalDep.walkingFlags |= COLLECT_RELOADABLE_MODULES;
}
return rtNode;
}

private void visitRuntimeDeps() {
var taskRunner = new ModelResolutionTaskRunner();
conditionalDep.scheduleRuntimeVisit(taskRunner);
taskRunner.waitForCompletion();
conditionalDep.setFlags(conditionalDep.walkingFlags);
if (conditionalDep.parent.resolvedDep == null) {
conditionalDep.parent.allDeps.add(conditionalDep.resolvedDep.getArtifactCoords());
} else {
conditionalDep.parent.resolvedDep.addDependency(conditionalDep.resolvedDep.getArtifactCoords());
}
conditionalDep.parent.ext.runtimeNode.getChildren().add(rtNode);
}

boolean isSatisfied() {
Expand Down

0 comments on commit d1025fd

Please sign in to comment.