Skip to content

Commit bf30cb1

Browse files
ALikhachevSpace Team
authored andcommitted
[Maven] Migrate to BTAv2
^KT-78201 Fixed
1 parent 7daa9c2 commit bf30cb1

File tree

3 files changed

+73
-56
lines changed

3 files changed

+73
-56
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
source(new File(basedir, "../../../verify-common.bsh").getAbsolutePath());
22

33
assertBuildLogHasLine("[INFO] BUILD FAILURE");
4-
assertBuildLogHasLineThatContains("Unknown JVM target version: 1.4");
4+
assertBuildLogHasLineThatContains("Unknown -jvm-target value: 1.4");

libraries/tools/kotlin-maven-plugin-test/src/it/test-plugins/verify.groovy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ State state = buildLogFile.readLines().collect { it.replaceAll("\\u001b[^m]*m",
3232
|| line.startsWith("Downloading")
3333
|| line.startsWith("[WARNING] Language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features")
3434
|| line.startsWith("[INFO] starting the daemon as")
35+
|| line.startsWith("[INFO] Options for KOTLIN DAEMON")
3536
|| line.contains("retrying connecting to the daemon") // may contain text on both sides
3637
|| line.startsWith("[INFO] PERF:")
3738
|| (line.startsWith("[WARNING]") && line.contains("is deprecated")) // ignoring deprecations

libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/K2JVMCompileMojo.java

Lines changed: 71 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,15 @@
1717
package org.jetbrains.kotlin.maven;
1818

1919
import org.apache.maven.artifact.Artifact;
20-
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
2120
import org.apache.maven.plugin.MojoExecutionException;
2221
import org.apache.maven.plugin.MojoFailureException;
2322
import org.apache.maven.plugins.annotations.*;
2423
import org.jetbrains.annotations.NotNull;
2524
import org.jetbrains.annotations.Nullable;
2625
import org.jetbrains.kotlin.build.SourcesUtilsKt;
2726
import org.jetbrains.kotlin.buildtools.api.*;
28-
import org.jetbrains.kotlin.buildtools.api.jvm.ClasspathSnapshotBasedIncrementalCompilationApproachParameters;
29-
import org.jetbrains.kotlin.buildtools.api.jvm.ClasspathSnapshotBasedIncrementalJvmCompilationConfiguration;
30-
import org.jetbrains.kotlin.buildtools.api.jvm.JvmCompilationConfiguration;
27+
import org.jetbrains.kotlin.buildtools.api.jvm.*;
28+
import org.jetbrains.kotlin.buildtools.api.jvm.operations.JvmCompilationOperation;
3129
import org.jetbrains.kotlin.cli.common.CLICompiler;
3230
import org.jetbrains.kotlin.cli.common.ExitCode;
3331
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments;
@@ -47,6 +45,7 @@
4745
import java.net.URLClassLoader;
4846
import java.nio.file.Files;
4947
import java.nio.file.Path;
48+
import java.nio.file.Paths;
5049
import java.time.Duration;
5150
import java.util.*;
5251
import java.util.function.Consumer;
@@ -123,8 +122,13 @@ public class K2JVMCompileMojo extends KotlinCompileMojoBase<K2JVMCompilerArgumen
123122
private static final String MAVEN_DAEMON_PROPERTY_NAME = "mvnd.home";
124123

125124
@NotNull
126-
private File getCachesDir() {
127-
return new File(incrementalCachesRoot, getSourceSetName());
125+
private Path getCachesDir() {
126+
return Paths.get(incrementalCachesRoot, getSourceSetName());
127+
}
128+
129+
@NotNull
130+
private Path getKotlinClassesCacheDir() {
131+
return Paths.get(incrementalCachesRoot, "classes");
128132
}
129133

130134
protected boolean isIncremental() {
@@ -249,7 +253,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
249253
@Inject
250254
private KotlinArtifactResolver kotlinArtifactResolver;
251255

252-
private CompilationService getCompilationService() throws MojoExecutionException {
256+
private KotlinToolchains getKotlinToolchains() throws MojoExecutionException {
253257
try {
254258
Set<Artifact> artifacts =
255259
Stream.concat(
@@ -266,14 +270,14 @@ private CompilationService getCompilationService() throws MojoExecutionException
266270
}
267271
}).toArray(URL[]::new);
268272
ClassLoader btaClassLoader = new URLClassLoader(urls, SharedApiClassesClassLoader.newInstance());
269-
return CompilationService.loadImplementation(btaClassLoader);
273+
return KotlinToolchains.loadImplementation(btaClassLoader);
270274
} catch (Exception e) {
271275
throw new MojoExecutionException("Failed to load Kotlin Build Tools API implementation", e);
272276
}
273277
}
274278

275-
private static String getFileExtension(File file) {
276-
String fileName = file.getName();
279+
private static String getFileExtension(Path file) {
280+
String fileName = file.getFileName().toString();
277281
int lastDotIndex = fileName.lastIndexOf('.');
278282
if (lastDotIndex == -1) {
279283
return "";
@@ -290,9 +294,8 @@ protected ExitCode execCompiler(
290294
List<File> sourceRoots
291295
) throws MojoExecutionException {
292296
try {
293-
ProjectId projectId = ProjectId.Companion.RandomProjectUUID();
294-
CompilationService compilationService = getCompilationService();
295-
CompilerExecutionStrategyConfiguration strategyConfig = compilationService.makeCompilerExecutionStrategyConfiguration();
297+
KotlinToolchains kotlinToolchains = getKotlinToolchains();
298+
ExecutionPolicy executionPolicy;
296299
if (useDaemon) {
297300
boolean inMavenDaemon = System.getProperty(MAVEN_DAEMON_PROPERTY_NAME) != null;
298301
Duration usedDaemonShutdownDelay;
@@ -305,75 +308,87 @@ protected ExitCode execCompiler(
305308
usedDaemonShutdownDelay = DEFAULT_NON_MAVEN_DAEMON_SHUTDOWN_DELAY;
306309
}
307310
getLog().debug("Using Kotlin compiler daemon with shutdown delay " + usedDaemonShutdownDelay + " ms" + (inMavenDaemon ? " (in Maven daemon)" : " (outside Maven daemon)"));
308-
strategyConfig.useDaemonStrategy(kotlinDaemonJvmArgs, usedDaemonShutdownDelay);
311+
ExecutionPolicy.WithDaemon daemonPolicy = kotlinToolchains.createDaemonExecutionPolicy();
312+
daemonPolicy.set(ExecutionPolicy.WithDaemon.JVM_ARGUMENTS, kotlinDaemonJvmArgs);
313+
daemonPolicy.set(ExecutionPolicy.WithDaemon.SHUTDOWN_DELAY_MILLIS, usedDaemonShutdownDelay.toMillis());
314+
executionPolicy = daemonPolicy;
309315
} else {
310316
getLog().debug("Using in-process Kotlin compiler");
311-
strategyConfig.useInProcessStrategy();
312-
}
313-
314-
JvmCompilationConfiguration compileConfig = compilationService.makeJvmCompilationConfiguration();
315-
316-
LegacyKotlinMavenLogger kotlinMavenLogger = new LegacyKotlinMavenLogger(messageCollector, getLog());
317-
compileConfig.useLogger(kotlinMavenLogger);
318-
319-
Set<Consumer<CompilationResult>> resultHandlers = new HashSet<>();
320-
if (isIncremental()) {
321-
resultHandlers.add(configureIncrementalCompilation(compileConfig, arguments));
317+
executionPolicy = kotlinToolchains.createInProcessExecutionPolicy();
322318
}
323319

320+
JvmPlatformToolchain jvmToolchain = JvmPlatformToolchain.get(kotlinToolchains);
324321
Set<String> kotlinExtensions = SourcesUtilsKt.getDEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS();
325322
Set<String> allExtensions = new HashSet<>(kotlinExtensions);
326323
allExtensions.add("java");
327324

328-
List<File> allSources = new ArrayList<>();
325+
List<Path> allSources = new ArrayList<>();
329326
for (File sourceRoot : sourceRoots) {
330327
try (Stream<Path> files = Files.walk(sourceRoot.toPath())) {
331328
allSources.addAll(
332329
files
333-
.map(Path::toFile)
334330
.filter(file -> allExtensions.contains(getFileExtension(file).toLowerCase(Locale.ROOT)))
335-
.filter(File::isFile)
331+
.filter(Files::isRegularFile)
336332
.collect(Collectors.toList())
337333
);
338334
}
339335
}
340336
List<String> myArguments = ArgumentUtils.convertArgumentsToStringList(arguments);
341337

342-
CompilationResult result = compilationService.compileJvm(projectId, strategyConfig, compileConfig, allSources, myArguments);
343-
compilationService.finishProjectCompilation(projectId);
344-
resultHandlers.forEach(handler -> handler.accept(result));
345-
switch (result) {
346-
case COMPILATION_SUCCESS:
347-
return ExitCode.OK;
348-
case COMPILATION_ERROR:
349-
return ExitCode.COMPILATION_ERROR;
350-
case COMPILATION_OOM_ERROR:
351-
return ExitCode.OOM_ERROR;
352-
default:
353-
return ExitCode.INTERNAL_ERROR;
338+
Set<Consumer<CompilationResult>> resultHandlers = new HashSet<>();
339+
340+
Path destination = getEffectiveDestinationDirectory(arguments);
341+
JvmCompilationOperation compilationOperation = jvmToolchain.createJvmCompilationOperation(allSources, destination);
342+
343+
if (isIncremental()) {
344+
resultHandlers.add(configureIncrementalCompilation(compilationOperation, arguments));
345+
}
346+
347+
LegacyKotlinMavenLogger kotlinMavenLogger = new LegacyKotlinMavenLogger(messageCollector, getLog());
348+
try (KotlinToolchains.BuildSession buildSession = kotlinToolchains.createBuildSession()) {
349+
compilationOperation.getCompilerArguments().applyArgumentStrings(myArguments);
350+
CompilationResult result = buildSession.executeOperation(compilationOperation, executionPolicy, kotlinMavenLogger);
351+
resultHandlers.forEach(handler -> handler.accept(result));
352+
switch (result) {
353+
case COMPILATION_SUCCESS:
354+
return ExitCode.OK;
355+
case COMPILATION_ERROR:
356+
return ExitCode.COMPILATION_ERROR;
357+
case COMPILATION_OOM_ERROR:
358+
return ExitCode.OOM_ERROR;
359+
default:
360+
return ExitCode.INTERNAL_ERROR;
361+
}
354362
}
355363
} catch (Throwable t) {
356364
getLog().error("Internal Kotlin compilation error", t);
357365
return ExitCode.INTERNAL_ERROR;
358366
}
359367
}
360368

369+
private Path getEffectiveDestinationDirectory(K2JVMCompilerArguments arguments) {
370+
if (isIncremental()) {
371+
return getKotlinClassesCacheDir();
372+
} else {
373+
String destination = Objects.requireNonNull(arguments.getDestination());
374+
return Paths.get(destination);
375+
}
376+
}
377+
361378
private Consumer<CompilationResult> configureIncrementalCompilation(
362-
JvmCompilationConfiguration compileConfig,
379+
JvmCompilationOperation compileOperation,
363380
K2JVMCompilerArguments arguments
364-
) {
381+
) throws IOException {
365382
getLog().warn("Using experimental Kotlin incremental compilation");
366-
File cachesDir = getCachesDir();
367-
//noinspection ResultOfMethodCallIgnored
368-
cachesDir.mkdirs();
383+
Path cachesDir = getCachesDir();
384+
Files.createDirectories(cachesDir);
369385
String originalDestination = arguments.getDestination();
370386
assert originalDestination != null : "output is not specified!";
371387
File classesDir = new File(originalDestination);
372-
File kotlinClassesDir = new File(cachesDir, "classes");
373-
File snapshotsFile = new File(cachesDir, "snapshots.bin");
388+
File kotlinClassesDir = getKotlinClassesCacheDir().toFile();
389+
File snapshotsFile = new File(cachesDir.toFile(), "snapshots.bin");
374390
String originalClasspath = arguments.getClasspath();
375391

376-
arguments.setDestination(kotlinClassesDir.getAbsolutePath());
377392
if (originalClasspath != null) {
378393
List<String> filteredClasspath = new ArrayList<>();
379394
for (String path : originalClasspath.split(File.pathSeparator)) {
@@ -384,18 +399,19 @@ private Consumer<CompilationResult> configureIncrementalCompilation(
384399
arguments.setClasspath(StringUtil.join(filteredClasspath, File.pathSeparator));
385400
}
386401

387-
ClasspathSnapshotBasedIncrementalJvmCompilationConfiguration icConf =
388-
compileConfig.makeClasspathSnapshotBasedIncrementalCompilationConfiguration();
389-
ClasspathSnapshotBasedIncrementalCompilationApproachParameters classpathSnapshotParams =
390-
new ClasspathSnapshotBasedIncrementalCompilationApproachParameters(Collections.EMPTY_LIST,
391-
new File(cachesDir, "shrunk-classpath-snapshot.bin"));
392-
compileConfig.useIncrementalCompilation(cachesDir, SourcesChanges.ToBeCalculated.INSTANCE, classpathSnapshotParams, icConf);
402+
JvmSnapshotBasedIncrementalCompilationOptions classpathSnapshotsOptions = compileOperation.createSnapshotBasedIcOptions();
403+
compileOperation.set(JvmCompilationOperation.INCREMENTAL_COMPILATION, new JvmSnapshotBasedIncrementalCompilationConfiguration(
404+
cachesDir,
405+
SourcesChanges.ToBeCalculated.INSTANCE,
406+
Collections.EMPTY_LIST,
407+
cachesDir.resolve("shrunk-classpath-snapshot.bin"),
408+
classpathSnapshotsOptions
409+
));
393410

394411
return compilationResult -> {
395412
if (compilationResult == CompilationResult.COMPILATION_SUCCESS) {
396413
(new FileCopier(getLog())).syncDirs(kotlinClassesDir, classesDir, snapshotsFile);
397414
}
398-
arguments.setDestination(originalDestination);
399415
arguments.setClasspath(originalClasspath);
400416
};
401417
}

0 commit comments

Comments
 (0)