mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[Gradle|Exec] fix: use Gradle TAPI's built-in VM options merger
### Issues * IDEA-363359 JVM args visibility is broken in a Gradle script during sync * IDEA-344664 Overwriting gradle vm options from gradle.properties * IDEA-309978 Duplicate parameter --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED when using Gradle 7.6 version GitOrigin-RevId: 12cfb45138b09794a0d08d018ce03a14d4672c39
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5fa23f8ea3
commit
c1bd7d9629
@@ -123,6 +123,7 @@ jvm_library(
|
||||
"//platform/editor-ui-api:editor-ui",
|
||||
"//platform/external-system-api/dependency-updater",
|
||||
"//platform/observable",
|
||||
"//platform/platform-util-io:ide-util-io",
|
||||
"//plugins/gradle/java",
|
||||
"//java/openapi:java",
|
||||
"//jps/model-api:model",
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.editor.ui" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.platform.externalSystem.dependencyUpdater" />
|
||||
<orderEntry type="module" module-name="intellij.platform.ide.observable" />
|
||||
<orderEntry type="module" module-name="intellij.platform.ide.util.io" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.gradle.java" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.java" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.platform.jps.model" scope="TEST" />
|
||||
|
||||
+5
-109
@@ -17,18 +17,15 @@ import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunCo
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemTelemetryUtil;
|
||||
import com.intellij.openapi.externalSystem.util.OutputWrapper;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.util.Couple;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.platform.eel.provider.EelProviderUtil;
|
||||
import com.intellij.platform.eel.provider.LocalEelDescriptor;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.lang.JavaVersion;
|
||||
import io.opentelemetry.api.trace.Span;
|
||||
import io.opentelemetry.api.trace.StatusCode;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import org.gradle.process.internal.JvmOptions;
|
||||
import org.gradle.tooling.*;
|
||||
import org.gradle.tooling.events.OperationType;
|
||||
import org.gradle.tooling.model.build.BuildEnvironment;
|
||||
@@ -187,7 +184,7 @@ public final class GradleExecutionHelper {
|
||||
|
||||
applyIdeaParameters(settings);
|
||||
|
||||
setupJvmArguments(operation, settings, buildEnvironment);
|
||||
setupJvmArguments(operation, settings);
|
||||
|
||||
setupLogging(settings, buildEnvironment);
|
||||
|
||||
@@ -265,26 +262,12 @@ public final class GradleExecutionHelper {
|
||||
@VisibleForTesting
|
||||
public static void setupJvmArguments(
|
||||
@NotNull LongRunningOperation operation,
|
||||
@NotNull GradleExecutionSettings settings,
|
||||
@Nullable BuildEnvironment buildEnvironment
|
||||
@NotNull GradleExecutionSettings settings
|
||||
) {
|
||||
var jvmArgs = ContainerUtil.filter(settings.getJvmArguments(), it -> !StringUtil.isEmpty(it));
|
||||
|
||||
if (jvmArgs.isEmpty()) {
|
||||
return;
|
||||
if (!jvmArgs.isEmpty()) {
|
||||
operation.addJvmArguments(ArrayUtilRt.toStringArray(jvmArgs));
|
||||
}
|
||||
|
||||
var buildEnvironmentRoot = getBuildRoot(buildEnvironment);
|
||||
var buildEnvironmentJvmArgs = getJvmArgs(buildEnvironment);
|
||||
|
||||
// the BuildEnvironment jvm arguments of the main build should be used for the 'buildSrc' import
|
||||
// to avoid spawning of the second Gradle daemon
|
||||
if (buildEnvironmentRoot != null && !"buildSrc".equals(buildEnvironmentRoot.getFileName().toString())) {
|
||||
// merge gradle args e.g. defined in gradle.properties
|
||||
jvmArgs = mergeBuildJvmArguments(buildEnvironmentJvmArgs, jvmArgs);
|
||||
}
|
||||
|
||||
operation.setJvmArguments(ArrayUtilRt.toStringArray(jvmArgs));
|
||||
}
|
||||
|
||||
private static void setupJavaHome(
|
||||
@@ -423,21 +406,13 @@ public final class GradleExecutionHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public static @Nullable Path getBuildRoot(@Nullable BuildEnvironment buildEnvironment) {
|
||||
private static @Nullable Path getBuildRoot(@Nullable BuildEnvironment buildEnvironment) {
|
||||
if (buildEnvironment == null) {
|
||||
return null;
|
||||
}
|
||||
return buildEnvironment.getBuildIdentifier().getRootDir().toPath();
|
||||
}
|
||||
|
||||
private static @NotNull List<String> getJvmArgs(@Nullable BuildEnvironment buildEnvironment) {
|
||||
if (buildEnvironment == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
var jvmArgs = buildEnvironment.getJava().getJvmArguments();
|
||||
return ContainerUtil.filter(jvmArgs, it -> !StringUtil.isEmpty(it));
|
||||
}
|
||||
|
||||
private static void setupEnvironment(
|
||||
@NotNull LongRunningOperation operation,
|
||||
@NotNull GradleExecutionSettings settings
|
||||
@@ -460,85 +435,6 @@ public final class GradleExecutionHelper {
|
||||
operation.setEnvironmentVariables(effectiveEnvironment);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
@VisibleForTesting
|
||||
public static @NotNull List<String> mergeBuildJvmArguments(@NotNull List<String> jvmArgs, @NotNull List<String> jvmArgsFromIdeSettings) {
|
||||
List<String> mergedJvmArgs = mergeJvmArgs(jvmArgs, jvmArgsFromIdeSettings);
|
||||
JvmOptions jvmOptions = new JvmOptions(null);
|
||||
jvmOptions.setAllJvmArgs(mergedJvmArgs);
|
||||
return jvmOptions.getAllJvmArgs();
|
||||
}
|
||||
|
||||
private static @NotNull List<String> mergeJvmArgs(@NotNull List<String> jvmArgs, @NotNull List<String> jvmArgsFromIdeSettings) {
|
||||
List<String> mergedJvmArgs = ContainerUtil.concat(jvmArgs, jvmArgsFromIdeSettings);
|
||||
MultiMap<String, String> argumentsMap = parseJvmArgs(mergedJvmArgs);
|
||||
|
||||
Map<String, String> mergedKeys = new LinkedHashMap<>();
|
||||
Set<String> argKeySet = new LinkedHashSet<>(argumentsMap.keySet());
|
||||
for (String argKey : argKeySet) {
|
||||
Collection<String> values = argumentsMap.getModifiable(argKey);
|
||||
if (values.size() == 1 && values.iterator().next().isEmpty()) {
|
||||
Couple<String> couple = splitArg(argKey);
|
||||
mergedKeys.put(couple.first, couple.second);
|
||||
}
|
||||
else {
|
||||
mergedKeys.put(argKey, "");
|
||||
Map<String, String> mergedArgs = new LinkedHashMap<>();
|
||||
for (String jvmArg : values) {
|
||||
if (jvmArg.isEmpty()) continue;
|
||||
Couple<String> couple = splitArg(jvmArg);
|
||||
mergedArgs.put(couple.first, couple.second);
|
||||
}
|
||||
values.clear();
|
||||
mergedArgs.forEach((key, value) -> values.add(key + value));
|
||||
}
|
||||
}
|
||||
|
||||
List<String> mergedArgs = new SmartList<>();
|
||||
mergedKeys.forEach((s1, s2) -> mergedArgs.add(s1 + s2));
|
||||
argKeySet.stream().filter(argKey -> !mergedArgs.contains(argKey)).forEach(argumentsMap::remove);
|
||||
|
||||
// remove `--add-opens` options, because same options will be added by gradle producing the option duplicates.
|
||||
// And the daemon will become uncompilable with the CLI invocations.
|
||||
// see https://github.com/gradle/gradle/blob/v5.1.1/subprojects/launcher/src/main/java/org/gradle/launcher/daemon/configuration/DaemonParameters.java#L125
|
||||
argumentsMap.remove("--add-opens");
|
||||
|
||||
List<String> result = new SmartList<>();
|
||||
argumentsMap.keySet().forEach(key -> argumentsMap.get(key).forEach(val -> {
|
||||
result.add(key);
|
||||
if (StringUtil.isNotEmpty(val)) {
|
||||
result.add(val);
|
||||
}
|
||||
}));
|
||||
return result;
|
||||
}
|
||||
|
||||
private static @NotNull MultiMap<@NotNull String, @NotNull String> parseJvmArgs(@NotNull List<@NotNull String> args) {
|
||||
MultiMap<String, String> result = MultiMap.createLinkedSet();
|
||||
String lastKey = null;
|
||||
for (String jvmArg : args) {
|
||||
if (jvmArg.startsWith("-")) {
|
||||
result.putValue(jvmArg, "");
|
||||
lastKey = jvmArg;
|
||||
}
|
||||
else {
|
||||
if (lastKey != null) {
|
||||
result.putValue(lastKey, jvmArg);
|
||||
lastKey = null;
|
||||
}
|
||||
else {
|
||||
result.putValue(jvmArg, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Couple<String> splitArg(String arg) {
|
||||
int i = arg.indexOf('=');
|
||||
return i <= 0 ? Couple.of(arg, "") : Couple.of(arg.substring(0, i), arg.substring(i));
|
||||
}
|
||||
|
||||
public static @Nullable BuildEnvironment getBuildEnvironment(@NotNull ProjectConnection connection,
|
||||
@NotNull ExternalSystemTaskId taskId,
|
||||
@NotNull ExternalSystemTaskNotificationListener listener,
|
||||
|
||||
+70
-187
@@ -15,212 +15,95 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.gradle.service.execution.helper
|
||||
|
||||
import com.intellij.platform.testFramework.assertion.collectionAssertion.CollectionAssertions
|
||||
import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper
|
||||
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings
|
||||
import org.junit.jupiter.api.Disabled
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.io.path.createDirectories
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.plugins.gradle.testFramework.annotations.AllGradleVersionsSource
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import com.intellij.util.net.NetUtils
|
||||
import org.jetbrains.plugins.gradle.testFramework.util.assumeThatGradleIsAtLeast
|
||||
|
||||
class GradleExecutionHelperJvmArgumentsTest : GradleExecutionHelperJvmArgumentsTestCase() {
|
||||
|
||||
@Test
|
||||
fun `test Gradle JVM options resolution with empty environment`() {
|
||||
val workingDirectory = tempDirectory.resolve("project")
|
||||
.createDirectories()
|
||||
@ParameterizedTest
|
||||
@AllGradleVersionsSource
|
||||
fun `test Gradle JVM options resolution with custom properties`(gradleVersion: GradleVersion) {
|
||||
testEmptyProject(gradleVersion) {
|
||||
|
||||
val operation = createOperation()
|
||||
val settings = GradleExecutionSettings()
|
||||
val buildEnvironment = createBuildEnvironment(workingDirectory)
|
||||
GradleExecutionHelper.setupJvmArguments(operation, settings, buildEnvironment)
|
||||
|
||||
CollectionAssertions.assertEmpty(operation.jvmArguments)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Gradle JVM options resolution with settings`() {
|
||||
val projectRoot = tempDirectory.resolve("project")
|
||||
.createDirectories()
|
||||
|
||||
val settings = GradleExecutionSettings().apply {
|
||||
withVmOptions(
|
||||
val customVmOptions = listOf(
|
||||
"-Dname=value",
|
||||
"-Xmx10g"
|
||||
"-Xmx420m"
|
||||
)
|
||||
|
||||
val daemonOptions = executeTaskAndCollectDaemonOptions(customVmOptions)
|
||||
|
||||
Assertions.assertThat(daemonOptions)
|
||||
.contains("-Dname=value")
|
||||
.contains("-Xmx420m")
|
||||
}
|
||||
|
||||
val operation = createOperation()
|
||||
val buildEnvironment = createBuildEnvironment(projectRoot)
|
||||
GradleExecutionHelper.setupJvmArguments(operation, settings, buildEnvironment)
|
||||
|
||||
val expectedJvmArguments = listOf(
|
||||
"-Dname=value",
|
||||
"-Xmx10g"
|
||||
) + IMMUTABLE_JVM_ARGUMENTS
|
||||
CollectionAssertions.assertEqualsOrdered(expectedJvmArguments, operation.jvmArguments)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Gradle JVM options resolution with BuildEnvironment`() {
|
||||
val projectRoot = tempDirectory.resolve("project")
|
||||
.createDirectories()
|
||||
@ParameterizedTest
|
||||
@AllGradleVersionsSource
|
||||
fun `test Gradle JVM options resolution with gradle and custom properties`(gradleVersion: GradleVersion) {
|
||||
testEmptyProject(gradleVersion) {
|
||||
|
||||
val buildEnvironment = createBuildEnvironment(projectRoot).apply {
|
||||
java.jvmArguments = listOf(
|
||||
"-Dname=value",
|
||||
"-Xmx10g"
|
||||
)
|
||||
}
|
||||
writeText("gradle.properties", """
|
||||
|org.gradle.jvmargs=\
|
||||
| -Dname=value1 \
|
||||
| -Dname1=value \
|
||||
| -Xmx420m
|
||||
""".trimMargin())
|
||||
|
||||
val operation = createOperation()
|
||||
val settings = GradleExecutionSettings()
|
||||
GradleExecutionHelper.setupJvmArguments(operation, settings, buildEnvironment)
|
||||
|
||||
CollectionAssertions.assertEmpty(operation.jvmArguments)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Gradle JVM options resolution with settings and BuildEnvironment`() {
|
||||
val projectRoot = tempDirectory.resolve("project")
|
||||
.createDirectories()
|
||||
|
||||
val buildEnvironment = createBuildEnvironment(projectRoot).apply {
|
||||
java.jvmArguments = listOf(
|
||||
"-Dname=value1",
|
||||
"-Dname1=value",
|
||||
"-Xmx1g"
|
||||
)
|
||||
}
|
||||
|
||||
val settings = GradleExecutionSettings().apply {
|
||||
withVmOptions(
|
||||
val customVmOptions = listOf(
|
||||
"-Dname=value2",
|
||||
"-Dname2=value",
|
||||
"-Xmx2g"
|
||||
"-Xmx421m"
|
||||
)
|
||||
|
||||
val daemonOptions = executeTaskAndCollectDaemonOptions(customVmOptions)
|
||||
|
||||
Assertions.assertThat(daemonOptions)
|
||||
.doesNotContain("-Dname=value1")
|
||||
.contains("-Dname=value2")
|
||||
.contains("-Dname1=value")
|
||||
.contains("-Dname2=value")
|
||||
.doesNotContain("-Xmx420")
|
||||
.contains("-Xmx421m")
|
||||
}
|
||||
|
||||
val operation = createOperation()
|
||||
GradleExecutionHelper.setupJvmArguments(operation, settings, buildEnvironment)
|
||||
|
||||
val expectedJvmArguments = listOf(
|
||||
"-Dname=value2",
|
||||
"-Dname1=value",
|
||||
"-Dname2=value",
|
||||
"-Xmx2g"
|
||||
) + IMMUTABLE_JVM_ARGUMENTS
|
||||
CollectionAssertions.assertEqualsOrdered(expectedJvmArguments, operation.jvmArguments)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Gradle JVM options resolution with debug agent in BuildEnvironment`() {
|
||||
val projectRoot = tempDirectory.resolve("project")
|
||||
.createDirectories()
|
||||
@ParameterizedTest
|
||||
@AllGradleVersionsSource
|
||||
fun `test Gradle JVM options resolution with debug agent in gradle properties and custom properties`(gradleVersion: GradleVersion) {
|
||||
assumeThatGradleIsAtLeast(gradleVersion, "7.4") {
|
||||
"Gradle debugger port cannot be specified in gradle.properties"
|
||||
}
|
||||
assumeThatGradleIsAtLeast(gradleVersion, "8.13") {
|
||||
"Gradle TAPI's VM options merger cannot recognise org.gradle.debug.* sub-properties in gradle.properties"
|
||||
}
|
||||
|
||||
val buildEnvironment = createBuildEnvironment(projectRoot).apply {
|
||||
java.jvmArguments = listOf(
|
||||
"-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=*:5005"
|
||||
testEmptyProject(gradleVersion) {
|
||||
|
||||
val port = NetUtils.findAvailableSocketPort()
|
||||
|
||||
writeText("gradle.properties", """
|
||||
|org.gradle.debug=true
|
||||
|org.gradle.debug.port=$port
|
||||
|org.gradle.debug.suspend=false
|
||||
""".trimMargin())
|
||||
|
||||
val customVmOptions = listOf(
|
||||
"-Dname=value",
|
||||
)
|
||||
|
||||
val daemonOptions = executeTaskAndCollectDaemonOptions(customVmOptions)
|
||||
|
||||
Assertions.assertThat(daemonOptions)
|
||||
.contains("-Dname=value")
|
||||
.containsAnyOf(
|
||||
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$port",
|
||||
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:$port"
|
||||
)
|
||||
}
|
||||
|
||||
val settings = GradleExecutionSettings().apply {
|
||||
withVmOption(
|
||||
"-Dname=value"
|
||||
)
|
||||
}
|
||||
|
||||
val operation = createOperation()
|
||||
GradleExecutionHelper.setupJvmArguments(operation, settings, buildEnvironment)
|
||||
|
||||
val expectedJvmArguments = listOf(
|
||||
"-Dname=value",
|
||||
"-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=*:5005"
|
||||
) + IMMUTABLE_JVM_ARGUMENTS
|
||||
CollectionAssertions.assertEqualsOrdered(expectedJvmArguments, operation.jvmArguments)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Gradle JVM options resolution with --add-opens and --add-exports`() {
|
||||
val projectRoot = tempDirectory.resolve("project")
|
||||
.createDirectories()
|
||||
|
||||
val buildEnvironment = createBuildEnvironment(projectRoot).apply {
|
||||
java.jvmArguments = listOf(
|
||||
"--add-opens", "java.base/java.util=ALL-UNNAMED",
|
||||
"--add-opens", "java.base/java.lang=ALL-UNNAMED",
|
||||
"--add-opens", "java.base/java.lang.invoke=ALL-UNNAMED",
|
||||
"--add-opens", "java.prefs/java.util.prefs=ALL-UNNAMED",
|
||||
"--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
|
||||
"--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
|
||||
"--add-opens", "java.base/java.nio.charset=ALL-UNNAMED",
|
||||
"--add-opens", "java.base/java.net=ALL-UNNAMED",
|
||||
"--add-opens", "java.base/java.util.concurrent.atomic=ALL-UNNAMED",
|
||||
"-XX:MaxMetaspaceSize=384m",
|
||||
"-XX:+HeapDumpOnOutOfMemoryError",
|
||||
"-Xms256m",
|
||||
"-Xmx512m"
|
||||
) + IMMUTABLE_JVM_ARGUMENTS
|
||||
}
|
||||
|
||||
val settings = GradleExecutionSettings().apply {
|
||||
withVmOption("-Dname=value")
|
||||
}
|
||||
|
||||
val operation = createOperation()
|
||||
GradleExecutionHelper.setupJvmArguments(operation, settings, buildEnvironment)
|
||||
|
||||
val expectedJvmArguments = listOf(
|
||||
"-Dname=value",
|
||||
"--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
|
||||
"--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
|
||||
"-XX:MaxMetaspaceSize=384m",
|
||||
"-XX:+HeapDumpOnOutOfMemoryError",
|
||||
"-Xms256m",
|
||||
"-Xmx512m"
|
||||
) + IMMUTABLE_JVM_ARGUMENTS
|
||||
CollectionAssertions.assertEqualsOrdered(expectedJvmArguments, operation.jvmArguments)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("Known issues: The JVM options in long option notation cannot be correctly parsed")
|
||||
fun `test Gradle JVM options resolution with --add-opens= and --add-exports=`() {
|
||||
val projectRoot = tempDirectory.resolve("project")
|
||||
.createDirectories()
|
||||
|
||||
val buildEnvironment = createBuildEnvironment(projectRoot).apply {
|
||||
java.jvmArguments = listOf(
|
||||
"--add-opens=java.base/java.util=ALL-UNNAMED",
|
||||
"--add-opens=java.base/java.lang=ALL-UNNAMED",
|
||||
"--add-opens=java.base/java.lang.invoke=ALL-UNNAMED",
|
||||
"--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED",
|
||||
"--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
|
||||
"--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
|
||||
"--add-opens=java.base/java.nio.charset=ALL-UNNAMED",
|
||||
"--add-opens=java.base/java.net=ALL-UNNAMED",
|
||||
"--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED",
|
||||
"-XX:MaxMetaspaceSize=384m",
|
||||
"-XX:+HeapDumpOnOutOfMemoryError",
|
||||
"-Xms256m",
|
||||
"-Xmx512m"
|
||||
) + IMMUTABLE_JVM_ARGUMENTS
|
||||
}
|
||||
|
||||
val settings = GradleExecutionSettings().apply {
|
||||
withVmOption("-Dname=value")
|
||||
}
|
||||
|
||||
val operation = createOperation()
|
||||
GradleExecutionHelper.setupJvmArguments(operation, settings, buildEnvironment)
|
||||
|
||||
val expectedJvmArguments = listOf(
|
||||
"-Dname=value",
|
||||
"--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
|
||||
"--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
|
||||
"-XX:MaxMetaspaceSize=384m",
|
||||
"-XX:+HeapDumpOnOutOfMemoryError",
|
||||
"-Xms256m",
|
||||
"-Xmx512m"
|
||||
) + IMMUTABLE_JVM_ARGUMENTS
|
||||
CollectionAssertions.assertEqualsOrdered(expectedJvmArguments, operation.jvmArguments)
|
||||
}
|
||||
}
|
||||
|
||||
+71
-69
@@ -15,82 +15,84 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.gradle.service.execution.helper
|
||||
|
||||
import com.intellij.testFramework.junit5.TestApplication
|
||||
import com.intellij.testFramework.common.mock.notImplemented
|
||||
import org.gradle.process.internal.JvmOptions
|
||||
import org.gradle.tooling.LongRunningOperation
|
||||
import org.gradle.tooling.model.BuildIdentifier
|
||||
import org.gradle.tooling.model.build.BuildEnvironment
|
||||
import org.gradle.tooling.model.build.JavaEnvironment
|
||||
import org.junit.jupiter.api.io.TempDir
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
|
||||
import com.intellij.openapi.externalSystem.util.task.TaskExecutionSpec
|
||||
import com.intellij.openapi.util.UserDataHolderBase
|
||||
import com.intellij.util.execution.ParametersListUtil
|
||||
import org.intellij.lang.annotations.Language
|
||||
import org.jetbrains.plugins.gradle.service.execution.toGroovyStringLiteral
|
||||
import org.jetbrains.plugins.gradle.service.task.GradleTaskManager.INIT_SCRIPT_KEY
|
||||
import org.jetbrains.plugins.gradle.service.task.GradleTaskManager.INIT_SCRIPT_PREFIX_KEY
|
||||
import org.jetbrains.plugins.gradle.testFramework.GradleExecutionTestCase
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
import kotlin.io.path.deleteIfExists
|
||||
import kotlin.io.path.readLines
|
||||
|
||||
@TestApplication
|
||||
abstract class GradleExecutionHelperJvmArgumentsTestCase {
|
||||
abstract class GradleExecutionHelperJvmArgumentsTestCase : GradleExecutionTestCase() {
|
||||
|
||||
@TempDir
|
||||
protected lateinit var tempDirectory: Path
|
||||
|
||||
fun createBuildEnvironment(workingDirectory: Path): MockBuildEnvironment {
|
||||
val buildIdentifier = MockBuildIdentifier(workingDirectory)
|
||||
val javaEnvironment = MockJavaEnvironment()
|
||||
return MockBuildEnvironment(buildIdentifier, javaEnvironment)
|
||||
}
|
||||
|
||||
fun createOperation(): MockLongRunningOperation {
|
||||
return MockLongRunningOperation()
|
||||
}
|
||||
|
||||
private class MockBuildIdentifier(
|
||||
private val workingDirectory: Path,
|
||||
) : BuildIdentifier {
|
||||
override fun getRootDir(): File = workingDirectory.toFile()
|
||||
}
|
||||
|
||||
class MockBuildEnvironment(
|
||||
private val buildIdentifier: BuildIdentifier,
|
||||
private val javaEnvironment: MockJavaEnvironment,
|
||||
) : BuildEnvironment by notImplemented<BuildEnvironment>() {
|
||||
override fun getBuildIdentifier(): BuildIdentifier = buildIdentifier
|
||||
override fun getJava(): MockJavaEnvironment = javaEnvironment
|
||||
}
|
||||
|
||||
class MockJavaEnvironment : JavaEnvironment {
|
||||
|
||||
@get:JvmName("_jvmArguments")
|
||||
var jvmArguments: List<String> = emptyList()
|
||||
|
||||
override fun getJvmArguments(): List<String> = jvmArguments
|
||||
|
||||
override fun getJavaHome() = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
class MockLongRunningOperation : LongRunningOperation by notImplemented<LongRunningOperation>() {
|
||||
|
||||
var jvmArguments: MutableList<String> = ArrayList()
|
||||
private set
|
||||
|
||||
override fun setJvmArguments(vararg jvmArguments: String) = apply {
|
||||
this.jvmArguments = jvmArguments.toMutableList()
|
||||
fun executeTaskAndCollectDaemonOptions(customVmOptions: List<String>): List<String> {
|
||||
val jvmArgumentsPath = createFile("jvmArguments.txt").toNioPath()
|
||||
val jvmPropertiesPath = createFile("jvmProperties.txt").toNioPath()
|
||||
try {
|
||||
waitForAnyGradleTaskExecution {
|
||||
ExternalSystemUtil.runTask(
|
||||
TaskExecutionSpec.create()
|
||||
.withProject(project)
|
||||
.withSystemId(GradleConstants.SYSTEM_ID)
|
||||
.withSettings(ExternalSystemTaskExecutionSettings().also {
|
||||
it.externalSystemIdString = GradleConstants.SYSTEM_ID.id
|
||||
it.externalProjectPath = projectPath
|
||||
it.vmOptions = ParametersListUtil.join(customVmOptions)
|
||||
it.taskNames = listOf("help")
|
||||
})
|
||||
.withUserData(UserDataHolderBase().also {
|
||||
it.putUserData(INIT_SCRIPT_PREFIX_KEY, "ijJvmArgumentsCollector")
|
||||
it.putUserData(INIT_SCRIPT_KEY, INIT_SCRIPT
|
||||
.replace("JVM_ARGUMENTS_PATH", jvmArgumentsPath.toString().toGroovyStringLiteral())
|
||||
.replace("JVM_PROPERTIES_PATH", jvmPropertiesPath.toString().toGroovyStringLiteral())
|
||||
)
|
||||
})
|
||||
.build()
|
||||
)
|
||||
}
|
||||
return jvmArgumentsPath.readLines() + jvmPropertiesPath.readLines()
|
||||
}
|
||||
|
||||
override fun setJvmArguments(jvmArguments: Iterable<String>?) = apply {
|
||||
this.jvmArguments = jvmArguments?.toMutableList() ?: ArrayList()
|
||||
}
|
||||
|
||||
override fun addJvmArguments(vararg jvmArguments: String) = apply {
|
||||
this.jvmArguments.addAll(jvmArguments)
|
||||
}
|
||||
|
||||
override fun addJvmArguments(jvmArguments: Iterable<String>) = apply {
|
||||
this.jvmArguments.addAll(jvmArguments)
|
||||
finally {
|
||||
jvmArgumentsPath.deleteIfExists()
|
||||
jvmPropertiesPath.deleteIfExists()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val IMMUTABLE_JVM_ARGUMENTS: Array<String> =
|
||||
JvmOptions(null).allImmutableJvmArgs.toTypedArray()
|
||||
@Language("Groovy")
|
||||
private val INIT_SCRIPT = """
|
||||
|import java.lang.management.ManagementFactory
|
||||
|import java.lang.management.RuntimeMXBean
|
||||
|import java.nio.file.Files
|
||||
|import java.nio.file.Path
|
||||
|import java.nio.file.Paths
|
||||
|
|
||||
|interface Properties {
|
||||
| @SuppressWarnings('GroovyAssignabilityCheck')
|
||||
| public static final Path jvmArgumentsPath = Paths.get(JVM_ARGUMENTS_PATH)
|
||||
| @SuppressWarnings('GroovyAssignabilityCheck')
|
||||
| public static final Path jvmPropertiesPath = Paths.get(JVM_PROPERTIES_PATH)
|
||||
|}
|
||||
|
|
||||
|RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean()
|
||||
|StringJoiner jvmArguments = new StringJoiner("\n")
|
||||
|for (String argument : runtimeMxBean.getInputArguments()) {
|
||||
| jvmArguments.add(argument)
|
||||
|}
|
||||
|Files.write(Properties.jvmArgumentsPath, jvmArguments.toString().bytes)
|
||||
|
|
||||
|StringJoiner jvmProperties = new StringJoiner("\n")
|
||||
|for (Map.Entry<Object, Object> property: System.properties) {
|
||||
| jvmProperties.add("-D" + property.key.toString() + "=" +property.value.toString())
|
||||
|}
|
||||
|Files.write(Properties.jvmPropertiesPath, jvmProperties.toString().bytes)
|
||||
""".trimMargin()
|
||||
}
|
||||
}
|
||||
|
||||
-183
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.gradle.service.execution.helper
|
||||
|
||||
import com.intellij.platform.testFramework.assertion.collectionAssertion.CollectionAssertions
|
||||
import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class GradleExecutionHelperMergeJvmArgumentsTest : GradleExecutionHelperMergeJvmArgumentsTestCase() {
|
||||
|
||||
@Test
|
||||
fun `test Gradle JVM arguments merging with empty settings arguments`() {
|
||||
val buildEnvironmentJvmArguments = listOf(
|
||||
"-X:foo"
|
||||
)
|
||||
val settingsJvmArguments = emptyList<String>()
|
||||
|
||||
val actualJvmArguments = GradleExecutionHelper.mergeBuildJvmArguments(
|
||||
buildEnvironmentJvmArguments,
|
||||
settingsJvmArguments
|
||||
)
|
||||
|
||||
val expectedJvmArguments = listOf(
|
||||
"-X:foo"
|
||||
) + IMMUTABLE_JVM_ARGUMENTS
|
||||
|
||||
CollectionAssertions.assertEqualsOrdered(expectedJvmArguments, actualJvmArguments)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Gradle JVM arguments merging with empty build environment arguments`() {
|
||||
val buildEnvironmentJvmArguments = emptyList<String>()
|
||||
val settingsJvmArguments = listOf(
|
||||
"-X:foo"
|
||||
)
|
||||
|
||||
val actualJvmArguments = GradleExecutionHelper.mergeBuildJvmArguments(
|
||||
buildEnvironmentJvmArguments,
|
||||
settingsJvmArguments
|
||||
)
|
||||
|
||||
val expectedJvmArguments = listOf(
|
||||
"-X:foo"
|
||||
) + IMMUTABLE_JVM_ARGUMENTS
|
||||
|
||||
CollectionAssertions.assertEqualsOrdered(expectedJvmArguments, actualJvmArguments)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Gradle JVM arguments merging with empty build environment and settings arguments`() {
|
||||
val buildEnvironmentJvmArguments = emptyList<String>()
|
||||
val settingsJvmArguments = emptyList<String>()
|
||||
|
||||
val actualJvmArguments = GradleExecutionHelper.mergeBuildJvmArguments(
|
||||
buildEnvironmentJvmArguments,
|
||||
settingsJvmArguments
|
||||
)
|
||||
|
||||
val expectedJvmArguments = emptyList<String>() + IMMUTABLE_JVM_ARGUMENTS
|
||||
|
||||
CollectionAssertions.assertEqualsOrdered(expectedJvmArguments, actualJvmArguments)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Gradle JVM arguments merging with system properties`() {
|
||||
val buildEnvironmentJvmArguments = listOf(
|
||||
"-Dp=val"
|
||||
)
|
||||
val settingsJvmArguments = listOf(
|
||||
"-Dp=newVal"
|
||||
)
|
||||
|
||||
val actualJvmArguments = GradleExecutionHelper.mergeBuildJvmArguments(
|
||||
buildEnvironmentJvmArguments,
|
||||
settingsJvmArguments
|
||||
)
|
||||
|
||||
val expectedJvmArguments = listOf(
|
||||
"-Dp=newVal"
|
||||
) + IMMUTABLE_JVM_ARGUMENTS
|
||||
|
||||
CollectionAssertions.assertEqualsOrdered(expectedJvmArguments, actualJvmArguments)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Gradle JVM arguments merging with unique arguments`() {
|
||||
val buildEnvironmentJvmArguments = listOf(
|
||||
"-Dp=v"
|
||||
)
|
||||
val settingsJvmArguments = listOf(
|
||||
"-X:foo"
|
||||
)
|
||||
|
||||
val actualJvmArguments = GradleExecutionHelper.mergeBuildJvmArguments(
|
||||
buildEnvironmentJvmArguments,
|
||||
settingsJvmArguments
|
||||
)
|
||||
|
||||
val expectedJvmArguments = listOf(
|
||||
"-Dp=v",
|
||||
"-X:foo"
|
||||
) + IMMUTABLE_JVM_ARGUMENTS
|
||||
|
||||
CollectionAssertions.assertEqualsOrdered(expectedJvmArguments, actualJvmArguments)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Gradle JVM arguments merging with undefined arguments`() {
|
||||
val buildEnvironmentJvmArguments = listOf(
|
||||
"-Foo", "bar=001",
|
||||
"-Foo", "baz=002"
|
||||
)
|
||||
val settingsJvmArguments = listOf(
|
||||
"-Foo", "bar=003",
|
||||
"-Foo", "baz=002"
|
||||
)
|
||||
|
||||
val actualJvmArguments = GradleExecutionHelper.mergeBuildJvmArguments(
|
||||
buildEnvironmentJvmArguments,
|
||||
settingsJvmArguments
|
||||
)
|
||||
|
||||
val expectedJvmArguments = listOf(
|
||||
"-Foo", "bar=003",
|
||||
"-Foo", "baz=002"
|
||||
) + IMMUTABLE_JVM_ARGUMENTS
|
||||
|
||||
CollectionAssertions.assertEqualsOrdered(expectedJvmArguments, actualJvmArguments)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Gradle JVM arguments merging with -Xmx arguments`() {
|
||||
val settingsJvmArguments = listOf(
|
||||
"-Xmx512",
|
||||
)
|
||||
val buildEnvironmentJvmArguments = listOf(
|
||||
"-Xmx256",
|
||||
)
|
||||
|
||||
val actualJvmArguments = GradleExecutionHelper.mergeBuildJvmArguments(
|
||||
buildEnvironmentJvmArguments,
|
||||
settingsJvmArguments
|
||||
)
|
||||
|
||||
val expectedJvmArguments = listOf(
|
||||
"-Xmx512",
|
||||
) + IMMUTABLE_JVM_ARGUMENTS
|
||||
|
||||
CollectionAssertions.assertEqualsOrdered(expectedJvmArguments, actualJvmArguments)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test Gradle JVM arguments merging with --add-opens arguments`() {
|
||||
val settingsJvmArguments = listOf(
|
||||
"--add-opens", "java.base/java.util=ALL-UNNAMED"
|
||||
)
|
||||
val buildEnvironmentJvmArguments = listOf(
|
||||
"--add-opens", "java.base/java.lang=ALL-UNNAMED"
|
||||
)
|
||||
|
||||
val actualJvmArguments = GradleExecutionHelper.mergeBuildJvmArguments(
|
||||
buildEnvironmentJvmArguments,
|
||||
settingsJvmArguments
|
||||
)
|
||||
|
||||
val expectedJvmArguments = emptyList<String>() + IMMUTABLE_JVM_ARGUMENTS
|
||||
|
||||
CollectionAssertions.assertEqualsOrdered(expectedJvmArguments, actualJvmArguments)
|
||||
}
|
||||
}
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.gradle.service.execution.helper
|
||||
|
||||
import com.intellij.testFramework.junit5.TestApplication
|
||||
import org.gradle.process.internal.JvmOptions
|
||||
|
||||
@TestApplication
|
||||
abstract class GradleExecutionHelperMergeJvmArgumentsTestCase {
|
||||
|
||||
companion object {
|
||||
|
||||
val IMMUTABLE_JVM_ARGUMENTS: Array<String> =
|
||||
JvmOptions(null).allImmutableJvmArgs.toTypedArray()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user