[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:
Sergei Vorobyov
2025-05-27 18:45:23 +00:00
committed by intellij-monorepo-bot
parent 5fa23f8ea3
commit c1bd7d9629
7 changed files with 148 additions and 577 deletions
+1
View File
@@ -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",
+1
View File
@@ -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" />
@@ -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,
@@ -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)
}
}
@@ -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()
}
}
@@ -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)
}
}
@@ -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()
}
}