diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt new file mode 100644 index 00000000000..558be3a86ee --- /dev/null +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * 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.kotlin.cli.common + +public val KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY = "kotlin.environment.keepalive" diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index ed0a7ecec26..30b474fbe55 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -54,6 +54,7 @@ import org.jetbrains.kotlin.asJava.KtLightClassForFacade import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.CliModuleVisibilityManagerImpl +import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR @@ -237,9 +238,12 @@ public class KotlinCoreEnvironment private constructor( public fun createForProduction( parentDisposable: Disposable, configuration: CompilerConfiguration, configFilePaths: List ): KotlinCoreEnvironment { - // JPS may run many instances of the compiler in parallel (there's an option for compiling independent modules in parallel in IntelliJ) - // All projects share the same ApplicationEnvironment, and when the last project is disposed, the ApplicationEnvironment is disposed as well - if (System.getProperty("kotlin.environment.keepalive") == null) { + val appEnv = getOrCreateApplicationEnvironmentForProduction(configuration, configFilePaths) + // Disposing of the environment is unsafe in production then parallel builds are enabled, but turning it off universally + // breaks a lot of tests, therefore it is disabled for production and enabled for tests + if (System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY) == null || appEnv.application.isUnitTestMode) { + // JPS may run many instances of the compiler in parallel (there's an option for compiling independent modules in parallel in IntelliJ) + // All projects share the same ApplicationEnvironment, and when the last project is disposed, the ApplicationEnvironment is disposed as well Disposer.register(parentDisposable, object : Disposable { override fun dispose() { synchronized (APPLICATION_LOCK) { @@ -250,7 +254,7 @@ public class KotlinCoreEnvironment private constructor( } }) } - val environment = KotlinCoreEnvironment(parentDisposable, getOrCreateApplicationEnvironmentForProduction(configuration, configFilePaths), configuration) + val environment = KotlinCoreEnvironment(parentDisposable, appEnv, configuration) synchronized (APPLICATION_LOCK) { ourProjectCount++ diff --git a/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/DaemonParams.kt b/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/DaemonParams.kt index 7884e0eca60..a36be54542d 100644 --- a/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/DaemonParams.kt +++ b/compiler/rmi/rmi-interface/src/org/jetbrains/kotlin/rmi/DaemonParams.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.rmi +import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY import java.io.File import java.io.Serializable import java.lang.management.ManagementFactory @@ -139,14 +140,14 @@ fun Iterable.filterExtractProps(propMappers: List>, when { propMapper != null -> { - val optionLength = prefix.length() + matchingOption!!.length() + val optionLength = prefix.length + matchingOption!!.length when { propMapper is BoolPropMapper<*, *> -> { - if (param.length() > optionLength) + if (param.length > optionLength) throw IllegalArgumentException("Invalid switch option '$param', expecting $prefix$matchingOption without arguments") propMapper.apply("") } - param.length() > optionLength -> + param.length > optionLength -> if (param[optionLength] != '=') { if (propMapper.mergeDelimiter == null) throw IllegalArgumentException("Invalid option syntax '$param', expecting $prefix$matchingOption[= ]") @@ -265,7 +266,7 @@ public fun configureDaemonJVMOptions(opts: DaemonJVMOptions, inheritMemoryLimits System.getProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY)?.let { opts.jvmParams.add("D$COMPILE_DAEMON_LOG_PATH_PROPERTY=\"$it\"" ) } opts.jvmParams.addAll(additionalParams) - System.getProperty("kotlin.environment.keepalive")?.let { opts.jvmParams.add("Dkotlin.environment.keepalive=true") } + System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY)?.let { opts.jvmParams.add("D$KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY") } return opts } diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerRunnerUtil.java b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerRunnerUtil.java index cc97d0376f3..6f93cb03680 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerRunnerUtil.java +++ b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/CompilerRunnerUtil.java @@ -70,7 +70,7 @@ public class CompilerRunnerUtil { } @Nullable - public synchronized static Object invokeExecMethod( + public static Object invokeExecMethod( @NotNull String compilerClassName, @NotNull String[] arguments, @NotNull CompilerEnvironment environment, diff --git a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt index 19897e05a6c..314e780b65b 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.compilerRunner import com.intellij.util.xmlb.XmlSerializerUtil import org.jetbrains.kotlin.cli.common.ExitCode +import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments @@ -111,6 +112,9 @@ public object KotlinCompilerRunner { val stream = ByteArrayOutputStream() val out = PrintStream(stream) + if (System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY) == null) + System.setProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY, "") + val rc = CompilerRunnerUtil.invokeExecMethod(compilerClassName, argsArray, environment, messageCollector, out) // exec() returns an ExitCode object, class of which is loaded with a different class loader, @@ -139,7 +143,7 @@ public object KotlinCompilerRunner { // the property should be set by default for daemon builds to avoid parallel building problems // but it cannot be currently set by default globally, because it seems breaks many tests // TODO: find out how to get rid of the property and make it the default behavior - daemonJVMOptions.jvmParams.add("Dkotlin.environment.keepalive") + daemonJVMOptions.jvmParams.add("D$KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY") val daemonReportMessages = ArrayList()