Code review comment: For the extension tests, I wonder if we would have to dump the full test deployment classpath as we might add some deployment extensions for testing.

Code before review:
protected void doExecute() throws MojoExecutionException, MojoFailureException {
final String lifecyclePhase = mojoExecution.getLifecyclePhase();
if (mode == null) {
if (lifecyclePhase == null) {
mode = "NORMAL";
} else {
mode = lifecyclePhase.contains("test") ? "TEST" : "NORMAL";
}
}
final LaunchMode launchMode = LaunchMode.valueOf(mode);
if (getLog().isDebugEnabled()) {
getLog().debug("Bootstrapping Quarkus application in mode " + launchMode);
}
Path compareFile;
if (this.recordedBuildConfigFile == null) {
compareFile = recordedBuildConfigDirectory.toPath()
.resolve("quarkus-" + launchMode.getDefaultProfile() + "-config-dump");
} else if (this.recordedBuildConfigFile.isAbsolute()) {
compareFile = this.recordedBuildConfigFile.toPath();
} else {
compareFile = recordedBuildConfigDirectory.toPath().resolve(this.recordedBuildConfigFile.toPath());
}
final boolean prevConfigExists = Files.exists(compareFile);
if (!prevConfigExists && !dumpCurrentWhenRecordedUnavailable && !dumpDependencies) {
getLog().info("Config dump from the previous build does not exist at " + compareFile);
return;
}
CuratedApplication curatedApplication = null;
QuarkusClassLoader deploymentClassLoader = null;
final ClassLoader originalCl = Thread.currentThread().getContextClassLoader();
final boolean clearPackageTypeSystemProperty = setPackageTypeSystemPropertyIfNativeProfileEnabled();
try {
curatedApplication = bootstrapApplication(launchMode);
if (prevConfigExists || dumpCurrentWhenRecordedUnavailable) {
final Path targetFile = getOutputFile(outputFile, launchMode.getDefaultProfile(), "-config-check");
Properties compareProps = null;
if (prevConfigExists) {
compareProps = new Properties();
try (BufferedReader reader = Files.newBufferedReader(compareFile)) {
compareProps.load(reader);
} catch (IOException e) {
throw new RuntimeException("Failed to read " + compareFile, e);
}
}
deploymentClassLoader = curatedApplication.createDeploymentClassLoader();
Thread.currentThread().setContextClassLoader(deploymentClassLoader);
final Class<?> codeGenerator = deploymentClassLoader.loadClass("io.quarkus.deployment.CodeGenerator");
final Method dumpConfig = codeGenerator.getMethod("dumpCurrentConfigValues", ApplicationModel.class,
String.class,
Properties.class, QuarkusClassLoader.class, Properties.class, Path.class);
dumpConfig.invoke(null, curatedApplication.getApplicationModel(),
launchMode.name(), getBuildSystemProperties(true),
deploymentClassLoader, compareProps, targetFile);
}
if (dumpDependencies) {
final List<String> deps = new ArrayList<>();
for (var d : curatedApplication.getApplicationModel().getDependencies(DependencyFlags.DEPLOYMENT_CP)) {
var adler32 = new Adler32();
updateChecksum(adler32, d.getResolvedPaths());
deps.add(d.toGACTVString() + " " + adler32.getValue());
}
Collections.sort(deps);
final Path targetFile = getOutputFile(dependenciesFile, launchMode.getDefaultProfile(),
"-dependency-checksums.txt");
Files.createDirectories(targetFile.getParent());
try (BufferedWriter writer = Files.newBufferedWriter(targetFile)) {
for (var s : deps) {
writer.write(s);
writer.newLine();
}
}
}
} catch (Exception any) {
throw new MojoExecutionException("Failed to bootstrap Quarkus application", any);
} finally {
if (clearPackageTypeSystemProperty) {
System.clearProperty(PACKAGE_TYPE_PROP);
}
Thread.currentThread().setContextClassLoader(originalCl);
if (deploymentClassLoader != null) {
deploymentClassLoader.close();
}
}
}

Line under review: final List<String> deps = new ArrayList<>();

Code after addressing the review:
protected void doExecute() throws MojoExecutionException, MojoFailureException {
final String lifecyclePhase = mojoExecution.getLifecyclePhase();
if (mode == null) {
if (lifecyclePhase == null) {
mode = "NORMAL";
} else {
mode = lifecyclePhase.contains("test") ? "TEST" : "NORMAL";
}
}
final LaunchMode launchMode = LaunchMode.valueOf(mode);
if (getLog().isDebugEnabled()) {
getLog().debug("Bootstrapping Quarkus application in mode " + launchMode);
}
Path compareFile;
if (this.recordedBuildConfigFile == null) {
compareFile = recordedBuildConfigDirectory.toPath()
.resolve("quarkus-" + launchMode.getDefaultProfile() + "-config-dump");
} else if (this.recordedBuildConfigFile.isAbsolute()) {
compareFile = this.recordedBuildConfigFile.toPath();
} else {
compareFile = recordedBuildConfigDirectory.toPath().resolve(this.recordedBuildConfigFile.toPath());
}
final boolean prevConfigExists = Files.exists(compareFile);
if (!prevConfigExists && !dumpCurrentWhenRecordedUnavailable && !dumpDependencies) {
getLog().info("Config dump from the previous build does not exist at " + compareFile);
return;
}
CuratedApplication curatedApplication = null;
QuarkusClassLoader deploymentClassLoader = null;
final ClassLoader originalCl = Thread.currentThread().getContextClassLoader();
final boolean clearPackageTypeSystemProperty = setPackageTypeSystemPropertyIfNativeProfileEnabled();
try {
curatedApplication = bootstrapApplication(launchMode);
if (prevConfigExists || dumpCurrentWhenRecordedUnavailable) {
final Path targetFile = getOutputFile(outputFile, launchMode.getDefaultProfile(), "-config-check");
Properties compareProps = new Properties();
if (prevConfigExists) {
try (BufferedReader reader = Files.newBufferedReader(compareFile)) {
compareProps.load(reader);
} catch (IOException e) {
throw new RuntimeException("Failed to read " + compareFile, e);
}
}
deploymentClassLoader = curatedApplication.createDeploymentClassLoader();
Thread.currentThread().setContextClassLoader(deploymentClassLoader);
final Class<?> codeGenerator = deploymentClassLoader.loadClass("io.quarkus.deployment.CodeGenerator");
final Method dumpConfig = codeGenerator.getMethod("dumpCurrentConfigValues", ApplicationModel.class,
String.class,
Properties.class, QuarkusClassLoader.class, Properties.class, Path.class);
dumpConfig.invoke(null, curatedApplication.getApplicationModel(),
launchMode.name(), getBuildSystemProperties(true),
deploymentClassLoader, compareProps, targetFile);
}
if (dumpDependencies) {
final List<String> deps = new ArrayList<>();
for (var d : curatedApplication.getApplicationModel().getDependencies(DependencyFlags.DEPLOYMENT_CP)) {
StringBuilder entry = new StringBuilder(d.toGACTVString());
if (d.isSnapshot()) {
var adler32 = new Adler32();
updateChecksum(adler32, d.getResolvedPaths());
entry.append(" ").append(adler32.getValue());
}
deps.add(entry.toString());
}
Collections.sort(deps);
final Path targetFile = getOutputFile(dependenciesFile, launchMode.getDefaultProfile(),
"-dependency-checksums.txt");
Files.createDirectories(targetFile.getParent());
try (BufferedWriter writer = Files.newBufferedWriter(targetFile)) {
for (var s : deps) {
writer.write(s);
writer.newLine();
}
}
}
} catch (Exception any) {
throw new MojoExecutionException("Failed to bootstrap Quarkus application", any);
} finally {
if (clearPackageTypeSystemProperty) {
System.clearProperty(PACKAGE_TYPE_PROP);
}
Thread.currentThread().setContextClassLoader(originalCl);
if (deploymentClassLoader != null) {
deploymentClassLoader.close();
}
}
}