Move daemon jar from compiler
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.daemon.common
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
+2
-3
@@ -172,6 +172,8 @@ extra["versions.jflex"] = "1.7.0"
|
||||
extra["versions.markdown"] = "0.1.25"
|
||||
extra["versions.trove4j"] = "1.0.20181211"
|
||||
extra["versions.kotlin-native-shared"] = "1.0-dev-57"
|
||||
|
||||
// NOTE: please, also change KTOR_NAME in pathUtil.kt and all versions in corresponding jar names in daemon tests.
|
||||
extra["versions.ktor-network"] = "1.0.1"
|
||||
|
||||
if (!project.hasProperty("versions.kotlin-native")) {
|
||||
@@ -210,9 +212,6 @@ extra["compilerModules"] = arrayOf(
|
||||
":compiler:frontend.common",
|
||||
":compiler:frontend.java",
|
||||
":compiler:cli-common",
|
||||
":compiler:daemon-common",
|
||||
":compiler:daemon-common-new",
|
||||
":compiler:daemon",
|
||||
":compiler:ir.tree",
|
||||
":compiler:ir.psi2ir",
|
||||
":compiler:ir.backend.common",
|
||||
|
||||
@@ -40,6 +40,7 @@ dependencies {
|
||||
|
||||
testCompile(kotlinStdlib())
|
||||
|
||||
testCompile(project(":kotlin-daemon"))
|
||||
testCompile(commonDep("junit:junit"))
|
||||
testCompileOnly(project(":kotlin-test:kotlin-test-jvm"))
|
||||
testCompileOnly(project(":kotlin-test:kotlin-test-junit"))
|
||||
@@ -54,7 +55,7 @@ dependencies {
|
||||
testCompile(project(":kotlin-script-util"))
|
||||
testCompileOnly(projectRuntimeJar(":kotlin-daemon-client-new"))
|
||||
testCompileOnly(project(":kotlin-reflect-api"))
|
||||
testCompile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-jdk8")) { isTransitive = false }
|
||||
testCompile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false }
|
||||
testCompile(commonDep("io.ktor", "ktor-network")) {
|
||||
ktorExcludesForDaemon.forEach { (group, module) ->
|
||||
exclude(group = group, module = module)
|
||||
@@ -68,9 +69,9 @@ dependencies {
|
||||
|
||||
testRuntime(project(":kotlin-reflect"))
|
||||
testRuntime(project(":kotlin-daemon-client-new"))
|
||||
testRuntime(project(":compiler:daemon")) // +
|
||||
testRuntime(project(":compiler:daemon-common-new")) // +
|
||||
testRuntime(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-jdk8")) {
|
||||
testRuntime(project(":kotlin-daemon")) // +
|
||||
testRuntime(project(":daemon-common-new")) // +
|
||||
testRuntime(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) {
|
||||
isTransitive = false
|
||||
}
|
||||
testRuntime(commonDep("io.ktor", "ktor-network")) {
|
||||
|
||||
@@ -13,13 +13,13 @@ dependencies {
|
||||
compileOnly(project(":compiler:cli-common"))
|
||||
compileOnly(project(":kotlin-preloader"))
|
||||
compileOnly(project(":compiler:frontend.java"))
|
||||
compileOnly(project(":compiler:daemon-common"))
|
||||
compileOnly(project(":compiler:daemon-common-new"))
|
||||
compileOnly(project(":daemon-common"))
|
||||
compileOnly(project(":daemon-common-new"))
|
||||
compile(projectRuntimeJar(":kotlin-daemon-client"))
|
||||
compileOnly(project(":compiler:util"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
runtimeOnly(projectRuntimeJar(":kotlin-compiler-embeddable"))
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-jdk8")) { isTransitive = false }
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false }
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
||||
@@ -1,28 +1,36 @@
|
||||
import com.sun.javafx.scene.CameraHelper.project
|
||||
import org.gradle.internal.impldep.org.junit.experimental.categories.Categories.CategoryFilter.exclude
|
||||
import org.jetbrains.kotlin.gradle.dsl.Coroutines
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
description = "Kotlin Daemon New"
|
||||
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
jvmTarget = "1.8"
|
||||
|
||||
val ktorExcludesForDaemon : List<Pair<String, String>> by rootProject.extra
|
||||
|
||||
dependencies {
|
||||
compile(project(":compiler:cli"))
|
||||
compile(project(":compiler:cli-js"))
|
||||
compile(project(":compiler:daemon-common"))
|
||||
compile(project(":compiler:daemon-common-new"))
|
||||
compile(project(":daemon-common-new"))
|
||||
compile(project(":compiler:incremental-compilation-impl"))
|
||||
compile(project(":kotlin-build-common"))
|
||||
compile(commonDep("org.fusesource.jansi", "jansi"))
|
||||
compile(commonDep("org.jline", "jline"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compileOnly(intellijDep()) { includeIntellijCoreJarDependencies(project) }
|
||||
runtime(project(":kotlin-reflect"))
|
||||
compileOnly(project(":kotlin-reflect-api"))
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-jdk8")) { isTransitive = false }
|
||||
|
||||
embedded(project(":daemon-common")) { isTransitive = false }
|
||||
embedded(project(":daemon-common-new")) { isTransitive = false }
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) {
|
||||
isTransitive = false
|
||||
}
|
||||
compile(commonDep("io.ktor", "ktor-network")) {
|
||||
ktorExcludesForDaemon.forEach { (group, module) ->
|
||||
exclude(group = group, module = module)
|
||||
@@ -34,6 +42,17 @@ sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" {}
|
||||
}
|
||||
kotlin {
|
||||
experimental.coroutines = Coroutines.ENABLE
|
||||
}
|
||||
|
||||
publish()
|
||||
|
||||
noDefaultJar()
|
||||
|
||||
runtimeJar(task<ShadowJar>("shadowJar")) {
|
||||
from(mainSourceSet.output)
|
||||
}
|
||||
|
||||
sourcesJar()
|
||||
|
||||
javadocJar()
|
||||
|
||||
dist()
|
||||
|
||||
@@ -32,20 +32,20 @@ val ktorExcludesForDaemon : List<Pair<String, String>> by rootProject.extra
|
||||
dependencies {
|
||||
compileOnly(project(":compiler:util"))
|
||||
compileOnly(project(":compiler:cli-common"))
|
||||
compileOnly(project(":compiler:daemon-common-new"))
|
||||
compileOnly(project(":daemon-common-new"))
|
||||
compileOnly(project(":kotlin-reflect-api"))
|
||||
compileOnly(project(":kotlin-daemon-client"))
|
||||
embeddedComponents(project(":kotlin-daemon-client")) { isTransitive = false }
|
||||
embedded(project(":kotlin-daemon-client")) { isTransitive = false }
|
||||
compileOnly(project(":js:js.frontend"))
|
||||
compileOnly(commonDep("net.rubygrapefruit", "native-platform"))
|
||||
compileOnly(intellijDep()) { includeIntellijCoreJarDependencies(project) }
|
||||
|
||||
embeddedComponents(project(":compiler:daemon-common")) { isTransitive = false }
|
||||
embeddedComponents(commonDep("net.rubygrapefruit", "native-platform"))
|
||||
embedded(project(":daemon-common")) { isTransitive = false }
|
||||
embedded(commonDep("net.rubygrapefruit", "native-platform"))
|
||||
nativePlatformVariants.forEach {
|
||||
embeddedComponents(commonDep("net.rubygrapefruit", "native-platform", "-$it"))
|
||||
embedded(commonDep("net.rubygrapefruit", "native-platform", "-$it"))
|
||||
}
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-jdk8")) {
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) {
|
||||
isTransitive = false
|
||||
}
|
||||
compile(commonDep("io.ktor", "ktor-network")) {
|
||||
@@ -66,7 +66,6 @@ noDefaultJar()
|
||||
|
||||
runtimeJar(task<ShadowJar>("shadowJar")) {
|
||||
from(mainSourceSet.output)
|
||||
fromEmbeddedComponents()
|
||||
}
|
||||
|
||||
sourcesJar()
|
||||
@@ -74,5 +73,3 @@ sourcesJar()
|
||||
javadocJar()
|
||||
|
||||
dist()
|
||||
|
||||
ideaPlugin()
|
||||
|
||||
+1
-34
@@ -45,7 +45,6 @@ class KotlinCompilerClient : KotlinCompilerDaemonClient {
|
||||
val verboseReporting = System.getProperty(COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY) != null
|
||||
|
||||
private val log = Logger.getLogger("KotlinCompilerClient")
|
||||
private fun String.info(msg: String) = {}()//log.info("[$this] : $msg")
|
||||
|
||||
override fun getOrCreateClientFlagFile(daemonOptions: DaemonOptions): File =
|
||||
// for jps property is passed from IDEA to JPS in KotlinBuildProcessParametersProvider
|
||||
@@ -64,7 +63,6 @@ class KotlinCompilerClient : KotlinCompilerDaemonClient {
|
||||
autostart: Boolean,
|
||||
checkId: Boolean
|
||||
): CompileServiceAsync? {
|
||||
log.info("in connectToCompileService")
|
||||
val flagFile = getOrCreateClientFlagFile(daemonOptions)
|
||||
return connectToCompileService(
|
||||
compilerId,
|
||||
@@ -84,7 +82,6 @@ class KotlinCompilerClient : KotlinCompilerDaemonClient {
|
||||
reportingTargets: DaemonReportingTargets,
|
||||
autostart: Boolean
|
||||
): CompileServiceAsync? {
|
||||
log.info("connectToCompileService")
|
||||
return connectAndLease(
|
||||
compilerId,
|
||||
clientAliveFlagFile,
|
||||
@@ -112,14 +109,9 @@ class KotlinCompilerClient : KotlinCompilerDaemonClient {
|
||||
reportingTargets,
|
||||
autostart
|
||||
) { isLastAttempt ->
|
||||
|
||||
log.info("connectAndLease")
|
||||
|
||||
fun CompileServiceAsync.leaseImpl(): Deferred<CompileServiceSessionAsync?> =
|
||||
GlobalScope.async {
|
||||
// the newJVMOptions could be checked here for additional parameters, if needed
|
||||
log.info("trying registerClient")
|
||||
println("trying registerClient")
|
||||
try {
|
||||
registerClient(clientAliveFlagFile.absolutePath)
|
||||
} catch (e: Throwable) {
|
||||
@@ -149,7 +141,6 @@ class KotlinCompilerClient : KotlinCompilerDaemonClient {
|
||||
service.leaseImpl().await()
|
||||
} else {
|
||||
if (!isLastAttempt && autostart) {
|
||||
log.info("starting daemon...")
|
||||
if (startDaemon(compilerId, newJVMOptions, daemonOptions, reportingTargets)) {
|
||||
reportingTargets.report(DaemonReportCategory.DEBUG, "new daemon started, trying to find it")
|
||||
}
|
||||
@@ -189,7 +180,6 @@ class KotlinCompilerClient : KotlinCompilerDaemonClient {
|
||||
port: Int,
|
||||
profiler: Profiler
|
||||
): Int = profiler.withMeasure(this) {
|
||||
log.info("Compile")
|
||||
val services = BasicCompilerServicesWithResultsFacadeServerServerSide(
|
||||
messageCollector,
|
||||
outputsCollector,
|
||||
@@ -431,24 +421,13 @@ class KotlinCompilerClient : KotlinCompilerDaemonClient {
|
||||
daemonJVMOptions: DaemonJVMOptions,
|
||||
report: (DaemonReportCategory, String) -> Unit
|
||||
): Deferred<Pair<CompileServiceAsync?, DaemonJVMOptions>> = GlobalScope.async {
|
||||
log.info("tryFindSuitableDaemonOrNewOpts")
|
||||
|
||||
registryDir.mkdirs()
|
||||
val timestampMarker = createTempFile("kotlin-daemon-client-tsmarker", directory = registryDir)
|
||||
val aliveWithMetadata = try {
|
||||
log.info("walkDaemonsAsync... : ${registryDir.path}")
|
||||
walkDaemonsAsync(registryDir, compilerId, timestampMarker, report = report).also {
|
||||
log.info(
|
||||
"daemons (${it.size}): ${it.map { "daemon(params : " + it.jvmOptions.jvmParams.joinToString(", ") + ")" }.joinToString(
|
||||
", ", "[", "]"
|
||||
)}"
|
||||
)
|
||||
}
|
||||
walkDaemonsAsync(registryDir, compilerId, timestampMarker, report = report)
|
||||
} finally {
|
||||
timestampMarker.delete()
|
||||
}
|
||||
log.info("daemons : ${aliveWithMetadata.map { it.daemon::class.java.name }}")
|
||||
log.info("aliveWithMetadata: ${aliveWithMetadata.map { it.daemon::class.java.name }}")
|
||||
val comparator = compareBy<DaemonWithMetadataAsync, DaemonJVMOptions>(DaemonJVMOptionsMemoryComparator(), { it.jvmOptions })
|
||||
.thenBy {
|
||||
when (it.daemon) {
|
||||
@@ -475,17 +454,13 @@ class KotlinCompilerClient : KotlinCompilerDaemonClient {
|
||||
daemonOptions: DaemonOptions,
|
||||
reportingTargets: DaemonReportingTargets
|
||||
): Boolean {
|
||||
log.info("in startDaemon() - 0")
|
||||
val javaExecutable = File(File(System.getProperty("java.home"), "bin"), "java")
|
||||
log.info("in startDaemon() - 0.1")
|
||||
val serverHostname = System.getProperty(JAVA_RMI_SERVER_HOSTNAME) ?: error("$JAVA_RMI_SERVER_HOSTNAME is not set!")
|
||||
log.info("in startDaemon() - 0.2")
|
||||
val platformSpecificOptions = listOf(
|
||||
// hide daemon window
|
||||
"-Djava.awt.headless=true",
|
||||
"-D$JAVA_RMI_SERVER_HOSTNAME=$serverHostname"
|
||||
)
|
||||
log.info("in startDaemon() - 0.3")
|
||||
val args = listOf(
|
||||
javaExecutable.absolutePath, "-cp", compilerId.compilerClasspath.joinToString(File.pathSeparator)
|
||||
) +
|
||||
@@ -494,13 +469,10 @@ class KotlinCompilerClient : KotlinCompilerDaemonClient {
|
||||
COMPILER_DAEMON_CLASS_FQN_EXPERIMENTAL +
|
||||
daemonOptions.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) } +
|
||||
compilerId.mappers.flatMap { it.toArgs(COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX) }
|
||||
log.info("in startDaemon() - 1")
|
||||
reportingTargets.report(DaemonReportCategory.DEBUG, "starting the daemon as: " + args.joinToString(" "))
|
||||
val processBuilder = ProcessBuilder(args)
|
||||
log.info("in startDaemon() - 2")
|
||||
processBuilder.redirectErrorStream(true)
|
||||
// assuming daemon process is deaf and (mostly) silent, so do not handle streams
|
||||
log.info("daemon = launchProcessWithFallback")
|
||||
val daemon =
|
||||
launchProcessWithFallback(processBuilder, reportingTargets, "daemon client")
|
||||
|
||||
@@ -548,12 +520,9 @@ class KotlinCompilerClient : KotlinCompilerDaemonClient {
|
||||
}
|
||||
} ?: DAEMON_DEFAULT_STARTUP_TIMEOUT_MS
|
||||
if (daemonOptions.runFilesPath.isNotEmpty()) {
|
||||
log.info("daemonOptions.runFilesPath.isNotEmpty")
|
||||
val succeeded = isEchoRead.tryAcquire(daemonStartupTimeout, TimeUnit.MILLISECONDS)
|
||||
log.info("succeeded : $succeeded")
|
||||
return when {
|
||||
!isProcessAlive(daemon) -> {
|
||||
log.info("!isProcessAlive(daemon)")
|
||||
reportingTargets.report(
|
||||
DaemonReportCategory.INFO,
|
||||
"Daemon terminated unexpectedly with error code: ${daemon.exitValue()}"
|
||||
@@ -561,14 +530,12 @@ class KotlinCompilerClient : KotlinCompilerDaemonClient {
|
||||
false
|
||||
}
|
||||
!succeeded -> {
|
||||
log.info("isProcessAlive!")
|
||||
reportingTargets.report(DaemonReportCategory.INFO, "Unable to get response from daemon in $daemonStartupTimeout ms")
|
||||
false
|
||||
}
|
||||
else -> true
|
||||
}
|
||||
} else
|
||||
log.info("!daemonOptions.runFilesPath.isNotEmpty")
|
||||
// without startEcho defined waiting for max timeout
|
||||
Thread.sleep(daemonStartupTimeout)
|
||||
return true
|
||||
|
||||
@@ -23,19 +23,19 @@ val nativePlatformVariants = listOf(
|
||||
dependencies {
|
||||
compileOnly(project(":compiler:util"))
|
||||
compileOnly(project(":compiler:cli-common"))
|
||||
compileOnly(project(":compiler:daemon-common"))
|
||||
compileOnly(project(":daemon-common"))
|
||||
compileOnly(project(":kotlin-reflect-api"))
|
||||
compileOnly(project(":js:js.frontend"))
|
||||
compileOnly(commonDep("net.rubygrapefruit", "native-platform"))
|
||||
compileOnly(intellijDep()) { includeIntellijCoreJarDependencies(project) }
|
||||
|
||||
embedded(project(":compiler:daemon-common")) { isTransitive = false }
|
||||
embedded(project(":daemon-common")) { isTransitive = false }
|
||||
embedded(commonDep("net.rubygrapefruit", "native-platform"))
|
||||
nativePlatformVariants.forEach {
|
||||
embedded(commonDep("net.rubygrapefruit", "native-platform", "-$it"))
|
||||
}
|
||||
runtime(project(":kotlin-reflect"))
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-jdk8")) {
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) {
|
||||
isTransitive = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,12 +25,12 @@ dependencies {
|
||||
compile(project(":core:descriptors.jvm"))
|
||||
compile(project(":compiler:util"))
|
||||
compile(project(":compiler:cli-common"))
|
||||
compileOnly(project(":compiler:daemon-common"))
|
||||
compileOnly(project(":daemon-common"))
|
||||
compile(kotlinStdlib())
|
||||
compileOnly(project(":js:js.frontend"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compileOnly(intellijDep()) { includeIntellijCoreJarDependencies(project) }
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-jdk8")) {
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) {
|
||||
isTransitive = false
|
||||
}
|
||||
compile(commonDep("io.ktor", "ktor-network")) {
|
||||
|
||||
+3
-3
@@ -99,9 +99,9 @@ private inline fun tryConnectToDaemonByRMI(port: Int, report: (DaemonReportCateg
|
||||
val daemon = runBlocking {
|
||||
runWithTimeout(2 * DAEMON_PERIODIC_CHECK_INTERVAL_MS) {
|
||||
LocateRegistry.getRegistry(
|
||||
LoopbackNetworkInterface.loopbackInetAddressName,
|
||||
org.jetbrains.kotlin.daemon.common.LoopbackNetworkInterface.loopbackInetAddressName,
|
||||
port,
|
||||
LoopbackNetworkInterface.clientLoopbackSocketFactoryRMI
|
||||
org.jetbrains.kotlin.daemon.common.LoopbackNetworkInterface.clientLoopbackSocketFactory
|
||||
)?.lookup(COMPILER_SERVICE_RMI_NAME)
|
||||
}
|
||||
}
|
||||
@@ -134,7 +134,7 @@ private suspend fun tryConnectToDaemonBySockets(
|
||||
log.info("OK - daemon($port) connected to server!!!")
|
||||
daemon
|
||||
} catch (e: Throwable) {
|
||||
report(DaemonReportCategory.INFO, "kcannot find or connect to socket")
|
||||
report(DaemonReportCategory.INFO, "cannot find or connect to socket, exception:\n${e.javaClass.name}:${e.message}")
|
||||
daemon.close()
|
||||
null
|
||||
}
|
||||
|
||||
-1
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.daemon.common.experimental
|
||||
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalCompilerServicesFacade
|
||||
import org.jetbrains.kotlin.daemon.common.SimpleDirtyData
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.Client
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.DefaultClientRMIWrapper
|
||||
import java.io.File
|
||||
|
||||
-2
@@ -6,8 +6,6 @@
|
||||
package org.jetbrains.kotlin.daemon.common.experimental
|
||||
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalCompilerServicesFacadeAsync
|
||||
import org.jetbrains.kotlin.daemon.common.SimpleDirtyData
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.IncrementalCompilerServicesFacadeServerSide.*
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.Client
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.DefaultClient
|
||||
import java.io.File
|
||||
|
||||
-2
@@ -7,8 +7,6 @@ package org.jetbrains.kotlin.daemon.common.experimental
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalCompilerServicesFacade
|
||||
import org.jetbrains.kotlin.daemon.common.SimpleDirtyData
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
|
||||
class IncrementalCompilerServicesFacadeRMIWrapper(val clientSide: IncrementalCompilerServicesFacadeClientSide) :
|
||||
|
||||
-3
@@ -6,9 +6,6 @@
|
||||
package org.jetbrains.kotlin.daemon.common.experimental
|
||||
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalCompilerServicesFacadeAsync
|
||||
import org.jetbrains.kotlin.daemon.common.SimpleDirtyData
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.Server
|
||||
import java.io.File
|
||||
|
||||
|
||||
interface IncrementalCompilerServicesFacadeServerSide : IncrementalCompilerServicesFacadeAsync, CompilerServicesFacadeBaseServerSide
|
||||
+3
-74
@@ -18,58 +18,11 @@ import java.rmi.server.RMIServerSocketFactory
|
||||
import java.util.*
|
||||
|
||||
|
||||
// copyed from original(org.jetbrains.kotlin.daemon.common.NetworkUtils) TODO
|
||||
// unique part :
|
||||
// - AbstractClientLoopbackSocketFactory / ServerLoopbackSocketFactoryRMI / ServerLoopbackSocketFactoryKtor - Ktor-Sockets instead of java sockets
|
||||
// - findPortAndCreateSocket
|
||||
// TODO: get rid of copy-paste here
|
||||
|
||||
object LoopbackNetworkInterface {
|
||||
|
||||
const val IPV4_LOOPBACK_INET_ADDRESS = "127.0.0.1"
|
||||
const val IPV6_LOOPBACK_INET_ADDRESS = "::1"
|
||||
|
||||
// size of the requests queue for daemon services, so far seems that we don't need any big numbers here
|
||||
// but if we'll start getting "connection refused" errors, that could be the first place to try to fix it
|
||||
val SERVER_SOCKET_BACKLOG_SIZE by lazy {
|
||||
System.getProperty(DAEMON_RMI_SOCKET_BACKLOG_SIZE_PROPERTY)?.toIntOrNull() ?: DEFAULT_SERVER_SOCKET_BACKLOG_SIZE
|
||||
}
|
||||
val SOCKET_CONNECT_ATTEMPTS by lazy {
|
||||
System.getProperty(DAEMON_RMI_SOCKET_CONNECT_ATTEMPTS_PROPERTY)?.toIntOrNull() ?: DEFAULT_SOCKET_CONNECT_ATTEMPTS
|
||||
}
|
||||
val SOCKET_CONNECT_INTERVAL_MS by lazy {
|
||||
System.getProperty(DAEMON_RMI_SOCKET_CONNECT_INTERVAL_PROPERTY)?.toLongOrNull() ?: DEFAULT_SOCKET_CONNECT_INTERVAL_MS
|
||||
}
|
||||
|
||||
val serverLoopbackSocketFactoryRMI by lazy { ServerLoopbackSocketFactoryRMI() }
|
||||
val clientLoopbackSocketFactoryRMI by lazy { ClientLoopbackSocketFactoryRMI() }
|
||||
object LoopbackNetworkInterfaceKtor {
|
||||
|
||||
val serverLoopbackSocketFactoryKtor by lazy { ServerLoopbackSocketFactoryKtor() }
|
||||
val clientLoopbackSocketFactoryKtor by lazy { ClientLoopbackSocketFactoryKtor() }
|
||||
|
||||
// TODO switch to InetAddress.getLoopbackAddress on java 7+
|
||||
val loopbackInetAddressName by lazy {
|
||||
try {
|
||||
if (InetAddress.getByName(null) is Inet6Address) IPV6_LOOPBACK_INET_ADDRESS else IPV4_LOOPBACK_INET_ADDRESS
|
||||
} catch (e: IOException) {
|
||||
// getLocalHost may fail for unknown reasons in some situations, the fallback is to assume IPv4 for now
|
||||
// TODO consider some other ways to detect default to IPv6 addresses in this case
|
||||
IPV4_LOOPBACK_INET_ADDRESS
|
||||
}
|
||||
}
|
||||
|
||||
// base socket factories by default don't implement equals properly (see e.g. http://stackoverflow.com/questions/21555710/rmi-and-jmx-socket-factories)
|
||||
// so implementing it in derived classes using the fact that they are singletons
|
||||
|
||||
class ServerLoopbackSocketFactoryRMI : RMIServerSocketFactory, Serializable {
|
||||
override fun equals(other: Any?): Boolean = other === this || super.equals(other)
|
||||
override fun hashCode(): Int = super.hashCode()
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createServerSocket(port: Int): java.net.ServerSocket =
|
||||
ServerSocket(port, SERVER_SOCKET_BACKLOG_SIZE, InetAddress.getByName(null))
|
||||
}
|
||||
|
||||
val selectorMgr = ActorSelectorManager(Dispatchers.IO)
|
||||
|
||||
class ServerLoopbackSocketFactoryKtor : Serializable {
|
||||
@@ -83,31 +36,7 @@ object LoopbackNetworkInterface {
|
||||
.bind(InetSocketAddress(InetAddress.getByName(null), port)) // TODO : NO BACKLOG SIZE CHANGE =(
|
||||
}
|
||||
|
||||
abstract class AbstractClientLoopbackSocketFactory<SocketType> : Serializable {
|
||||
override fun equals(other: Any?): Boolean = other === this || super.equals(other)
|
||||
override fun hashCode(): Int = super.hashCode()
|
||||
|
||||
abstract protected fun socketCreate(host: String, port: Int): SocketType
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun createSocket(host: String, port: Int): SocketType {
|
||||
var attemptsLeft = SOCKET_CONNECT_ATTEMPTS
|
||||
while (true) {
|
||||
try {
|
||||
return socketCreate(host, port)
|
||||
} catch (e: ConnectException) {
|
||||
if (--attemptsLeft <= 0) throw e
|
||||
}
|
||||
Thread.sleep(SOCKET_CONNECT_INTERVAL_MS)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ClientLoopbackSocketFactoryRMI : AbstractClientLoopbackSocketFactory<java.net.Socket>(), RMIClientSocketFactory {
|
||||
override fun socketCreate(host: String, port: Int): Socket = Socket(InetAddress.getByName(null), port)
|
||||
}
|
||||
|
||||
class ClientLoopbackSocketFactoryKtor : AbstractClientLoopbackSocketFactory<io.ktor.network.sockets.Socket>() {
|
||||
class ClientLoopbackSocketFactoryKtor : LoopbackNetworkInterface.AbstractClientLoopbackSocketFactory<io.ktor.network.sockets.Socket>() {
|
||||
override fun socketCreate(host: String, port: Int): io.ktor.network.sockets.Socket =
|
||||
runBlocking { aSocket(selectorMgr).tcp().connect(InetSocketAddress(host, port)) }
|
||||
}
|
||||
@@ -126,7 +55,7 @@ fun findPortForSocket(attempts: Int, portRangeStart: Int, portRangeEnd: Int): Se
|
||||
try {
|
||||
return ServerSocketWrapper(
|
||||
port,
|
||||
LoopbackNetworkInterface.serverLoopbackSocketFactoryKtor.createServerSocket(port)
|
||||
LoopbackNetworkInterfaceKtor.serverLoopbackSocketFactoryKtor.createServerSocket(port)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
// assuming that the socketPort is already taken
|
||||
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.daemon.common.experimental
|
||||
|
||||
interface RemoteOutputStreamAsync {
|
||||
|
||||
/** closeStream() name is chosen since Clients are AutoClosable now
|
||||
* and Client-implementations of RemoteOutputStreamAsync have conflict of 'close' name **/
|
||||
suspend fun closeStream()
|
||||
|
||||
suspend fun write(data: ByteArray, offset: Int, length: Int)
|
||||
|
||||
suspend fun write(dataByte: Int)
|
||||
}
|
||||
|
||||
interface RemoteInputStreamAsync {
|
||||
|
||||
/** closeStream() name is chosen since Clients are AutoClosable now
|
||||
* and Client-implementations of RemoteInputStreamAsync have conflict of 'close' name **/
|
||||
suspend fun closeStream()
|
||||
|
||||
suspend fun read(length: Int): ByteArray
|
||||
|
||||
suspend fun read(): Int
|
||||
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.daemon.common.experimental
|
||||
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.Client
|
||||
|
||||
interface RemoteOutputStreamAsyncClientSide : RemoteOutputStreamAsync, Client<RemoteOutputStreamAsyncServerSide>
|
||||
|
||||
interface RemoteInputStreamClientSide : RemoteInputStreamAsync, Client<RemoteInputStreamServerSide>
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.daemon.common.experimental
|
||||
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.ByteWriteChannelWrapper
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.Server
|
||||
|
||||
|
||||
interface RemoteOutputStreamAsyncServerSide : RemoteOutputStreamAsync, Server<RemoteOutputStreamAsyncServerSide> {
|
||||
// Query messages:
|
||||
class CloseMessage : Server.Message<RemoteOutputStreamAsyncServerSide>() {
|
||||
override suspend fun processImpl(server: RemoteOutputStreamAsyncServerSide, sendReply: (Any?) -> Unit) =
|
||||
server.closeStream()
|
||||
}
|
||||
|
||||
class WriteMessage(val data: ByteArray, val offset: Int = -1, val length: Int = -1) :
|
||||
Server.Message<RemoteOutputStreamAsyncServerSide>() {
|
||||
override suspend fun processImpl(server: RemoteOutputStreamAsyncServerSide, sendReply: (Any?) -> Unit) =
|
||||
server.write(data, offset, length)
|
||||
}
|
||||
|
||||
class WriteIntMessage(val dataByte: Int) : Server.Message<RemoteOutputStreamAsyncServerSide>() {
|
||||
override suspend fun processImpl(server: RemoteOutputStreamAsyncServerSide, sendReply: (Any?) -> Unit) =
|
||||
server.write(dataByte)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface RemoteInputStreamServerSide : RemoteInputStreamAsync, Server<RemoteInputStreamServerSide> {
|
||||
// Query messages:
|
||||
class CloseMessage : Server.Message<RemoteInputStreamServerSide>() {
|
||||
override suspend fun processImpl(server: RemoteInputStreamServerSide, sendReply: (Any?) -> Unit) =
|
||||
server.closeStream()
|
||||
}
|
||||
|
||||
class ReadMessage(val length: Int = -1) : Server.Message<RemoteInputStreamServerSide>() {
|
||||
override suspend fun processImpl(server: RemoteInputStreamServerSide, sendReply: (Any?) -> Unit) =
|
||||
sendReply(if (length == -1) server.read() else server.read(length))
|
||||
}
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.daemon.common.experimental
|
||||
|
||||
import org.jetbrains.kotlin.daemon.common.RemoteInputStream
|
||||
import org.jetbrains.kotlin.daemon.common.RemoteOutputStream
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.Client
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.DefaultClientRMIWrapper
|
||||
|
||||
class RemoteOutputStreamAsyncWrapper(val rmiOutput: RemoteOutputStream) : RemoteOutputStreamAsyncClientSide,
|
||||
Client<RemoteOutputStreamAsyncServerSide> by DefaultClientRMIWrapper() {
|
||||
|
||||
override suspend fun closeStream() =
|
||||
rmiOutput.close()
|
||||
|
||||
override suspend fun write(data: ByteArray, offset: Int, length: Int) =
|
||||
rmiOutput.write(data, offset, length)
|
||||
|
||||
override suspend fun write(dataByte: Int) =
|
||||
rmiOutput.write(dataByte)
|
||||
|
||||
}
|
||||
|
||||
class RemoteInputStreamAsyncWrapper(private val rmiInput: RemoteInputStream) : RemoteInputStreamClientSide,
|
||||
Client<RemoteInputStreamServerSide> by DefaultClientRMIWrapper() {
|
||||
|
||||
override suspend fun closeStream() =
|
||||
rmiInput.close()
|
||||
|
||||
override suspend fun read() =
|
||||
rmiInput.read()
|
||||
|
||||
override suspend fun read(length: Int) =
|
||||
rmiInput.read(length)
|
||||
}
|
||||
|
||||
fun RemoteOutputStream.toClient() = RemoteOutputStreamAsyncWrapper(this)
|
||||
fun RemoteInputStream.toClient() = RemoteInputStreamAsyncWrapper(this)
|
||||
+3
-2
@@ -3,7 +3,8 @@ package org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure
|
||||
import io.ktor.network.sockets.Socket
|
||||
import kotlinx.coroutines.channels.*
|
||||
import kotlinx.coroutines.*
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.LoopbackNetworkInterface
|
||||
import org.jetbrains.kotlin.daemon.common.LoopbackNetworkInterface
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.LoopbackNetworkInterfaceKtor
|
||||
import sun.net.ConnectionResetException
|
||||
import java.beans.Transient
|
||||
import java.io.IOException
|
||||
@@ -198,7 +199,7 @@ abstract class DefaultAuthorizableClient<ServerType : ServerBase>(
|
||||
|
||||
|
||||
try {
|
||||
socket = LoopbackNetworkInterface.clientLoopbackSocketFactoryKtor.createSocket(
|
||||
socket = LoopbackNetworkInterfaceKtor.clientLoopbackSocketFactoryKtor.createSocket(
|
||||
serverHost,
|
||||
serverPort
|
||||
)
|
||||
|
||||
@@ -10,11 +10,12 @@ dependencies {
|
||||
compile(project(":core:descriptors.jvm"))
|
||||
compile(project(":compiler:util"))
|
||||
compile(project(":compiler:cli-common"))
|
||||
compile(project(":kotlin-build-common"))
|
||||
compile(kotlinStdlib())
|
||||
compileOnly(project(":js:js.frontend"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compileOnly(intellijDep()) { includeIntellijCoreJarDependencies(project) }
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-jdk8")) {
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) {
|
||||
isTransitive = false
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.daemon.common
|
||||
|
||||
import org.jetbrains.kotlin.incremental.IncrementalModuleInfo
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
import java.util.*
|
||||
|
||||
+12
-6
@@ -73,25 +73,31 @@ object LoopbackNetworkInterface {
|
||||
override fun createServerSocket(port: Int): ServerSocket = ServerSocket(port, SERVER_SOCKET_BACKLOG_SIZE, InetAddress.getByName(null))
|
||||
}
|
||||
|
||||
|
||||
class ClientLoopbackSocketFactory : RMIClientSocketFactory, Serializable {
|
||||
abstract class AbstractClientLoopbackSocketFactory<SocketType> : Serializable {
|
||||
override fun equals(other: Any?): Boolean = other === this || super.equals(other)
|
||||
override fun hashCode(): Int = super.hashCode()
|
||||
|
||||
abstract protected fun socketCreate(host: String, port: Int): SocketType
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(host: String, port: Int): Socket {
|
||||
fun createSocket(host: String, port: Int): SocketType {
|
||||
var attemptsLeft = SOCKET_CONNECT_ATTEMPTS
|
||||
while (true) {
|
||||
try {
|
||||
return Socket(InetAddress.getByName(null), port)
|
||||
}
|
||||
catch (e: ConnectException) {
|
||||
return socketCreate(host, port)
|
||||
} catch (e: ConnectException) {
|
||||
if (--attemptsLeft <= 0) throw e
|
||||
}
|
||||
Thread.sleep(SOCKET_CONNECT_INTERVAL_MS)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ClientLoopbackSocketFactory : AbstractClientLoopbackSocketFactory<java.net.Socket>(), RMIClientSocketFactory {
|
||||
override fun socketCreate(host: String, port: Int): Socket = Socket(InetAddress.getByName(null), port)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -93,22 +93,22 @@ inline fun usedMemory(withGC: Boolean): Long {
|
||||
}
|
||||
|
||||
|
||||
inline fun<R> beginWithMeasureWallTime(perfCounters: PerfCounters) = listOf(System.nanoTime())
|
||||
inline fun beginMeasureWallTime() = listOf(System.nanoTime())
|
||||
|
||||
inline fun<R> endWithMeasureWallTime(perfCounters: PerfCounters, startState: List<Long>) {
|
||||
inline fun endMeasureWallTime(perfCounters: PerfCounters, startState: List<Long>) {
|
||||
val (startTime) = startState
|
||||
perfCounters.addMeasurement(time = System.nanoTime() - startTime) // TODO: add support for time wrapping
|
||||
}
|
||||
|
||||
|
||||
inline fun beginWithMeasureWallAndThreadTimes(perfCounters: PerfCounters, threadMXBean: ThreadMXBean): List<Long> {
|
||||
inline fun beginMeasureWallAndThreadTimes(perfCounters: PerfCounters, threadMXBean: ThreadMXBean): List<Long> {
|
||||
val startTime = System.nanoTime()
|
||||
val startThreadTime = threadMXBean.threadCpuTime()
|
||||
val startThreadUserTime = threadMXBean.threadUserTime()
|
||||
return listOf(startTime, startThreadTime, startThreadUserTime)
|
||||
}
|
||||
|
||||
inline fun endWithMeasureWallAndThreadTimes(perfCounters: PerfCounters, threadMXBean: ThreadMXBean, startState: List<Long>) {
|
||||
inline fun endMeasureWallAndThreadTimes(perfCounters: PerfCounters, threadMXBean: ThreadMXBean, startState: List<Long>) {
|
||||
val (startTime, startThreadTime, startThreadUserTime) = startState
|
||||
|
||||
// TODO: add support for time wrapping
|
||||
@@ -117,12 +117,12 @@ inline fun endWithMeasureWallAndThreadTimes(perfCounters: PerfCounters, threadMX
|
||||
threadUser = threadMXBean.threadUserTime() - startThreadUserTime)
|
||||
}
|
||||
|
||||
inline fun beginWithMeasureWallAndThreadTimes(perfCounters: PerfCounters) =
|
||||
beginWithMeasureWallAndThreadTimes(perfCounters, ManagementFactory.getThreadMXBean())
|
||||
inline fun endWithMeasureWallAndThreadTimes(perfCounters: PerfCounters, startState: List<Long>) =
|
||||
endWithMeasureWallAndThreadTimes(perfCounters, ManagementFactory.getThreadMXBean(), startState)
|
||||
inline fun beginMeasureWallAndThreadTimes(perfCounters: PerfCounters) =
|
||||
beginMeasureWallAndThreadTimes(perfCounters, ManagementFactory.getThreadMXBean())
|
||||
inline fun endMeasureWallAndThreadTimes(perfCounters: PerfCounters, startState: List<Long>) =
|
||||
endMeasureWallAndThreadTimes(perfCounters, ManagementFactory.getThreadMXBean(), startState)
|
||||
|
||||
inline fun beginWithMeasureWallAndThreadTimesAndMemory(perfCounters: PerfCounters, withGC: Boolean = false, threadMXBean: ThreadMXBean): List<Long> {
|
||||
inline fun beginMeasureWallAndThreadTimesAndMemory(perfCounters: PerfCounters, withGC: Boolean = false, threadMXBean: ThreadMXBean): List<Long> {
|
||||
val startMem = usedMemory(withGC)
|
||||
val startTime = System.nanoTime()
|
||||
val startThreadTime = threadMXBean.threadCpuTime()
|
||||
@@ -131,7 +131,7 @@ inline fun beginWithMeasureWallAndThreadTimesAndMemory(perfCounters: PerfCounter
|
||||
return listOf(startMem, startTime, startThreadTime, startThreadUserTime)
|
||||
}
|
||||
|
||||
inline fun endWithMeasureWallAndThreadTimesAndMemory(perfCounters: PerfCounters, withGC: Boolean = false, threadMXBean: ThreadMXBean, startState: List<Long>){
|
||||
inline fun endMeasureWallAndThreadTimesAndMemory(perfCounters: PerfCounters, withGC: Boolean = false, threadMXBean: ThreadMXBean, startState: List<Long>){
|
||||
val (startMem, startTime, startThreadTime, startThreadUserTime) = startState
|
||||
|
||||
// TODO: add support for time wrapping
|
||||
@@ -141,11 +141,11 @@ inline fun endWithMeasureWallAndThreadTimesAndMemory(perfCounters: PerfCounters,
|
||||
memory = usedMemory(withGC) - startMem)
|
||||
}
|
||||
|
||||
inline fun<R> beginWithMeasureWallAndThreadTimesAndMemory(perfCounters: PerfCounters, withGC: Boolean) =
|
||||
beginWithMeasureWallAndThreadTimesAndMemory(perfCounters, withGC, ManagementFactory.getThreadMXBean())
|
||||
inline fun<R> beginMeasureWallAndThreadTimesAndMemory(perfCounters: PerfCounters, withGC: Boolean) =
|
||||
beginMeasureWallAndThreadTimesAndMemory(perfCounters, withGC, ManagementFactory.getThreadMXBean())
|
||||
|
||||
inline fun<R> endWithMeasureWallAndThreadTimesAndMemory(perfCounters: PerfCounters, withGC: Boolean, startState: List<Long>) =
|
||||
endWithMeasureWallAndThreadTimesAndMemory(perfCounters, withGC, ManagementFactory.getThreadMXBean(), startState)
|
||||
inline fun<R> endMeasureWallAndThreadTimesAndMemory(perfCounters: PerfCounters, withGC: Boolean, startState: List<Long>) =
|
||||
endMeasureWallAndThreadTimesAndMemory(perfCounters, withGC, ManagementFactory.getThreadMXBean(), startState)
|
||||
|
||||
|
||||
class DummyProfiler : Profiler {
|
||||
@@ -166,27 +166,27 @@ abstract class TotalProfiler : Profiler {
|
||||
|
||||
class WallTotalProfiler : TotalProfiler() {
|
||||
@Suppress("OVERRIDE_BY_INLINE")
|
||||
override inline fun beginMeasure(obj: Any?) = beginWithMeasureWallTime(total)
|
||||
override inline fun beginMeasure(obj: Any?) = beginMeasureWallTime()
|
||||
@Suppress("OVERRIDE_BY_INLINE")
|
||||
override inline fun endMeasure(obj: Any?, startState: List<Long>) = endWithMeasureWallTime(total, startState)
|
||||
override inline fun endMeasure(obj: Any?, startState: List<Long>) = endMeasureWallTime(total, startState)
|
||||
}
|
||||
|
||||
|
||||
class WallAndThreadTotalProfiler : TotalProfiler() {
|
||||
@Suppress("OVERRIDE_BY_INLINE")
|
||||
override inline fun beginMeasure(obj: Any?) = beginWithMeasureWallAndThreadTimes(total, threadMXBean)
|
||||
override inline fun beginMeasure(obj: Any?) = beginMeasureWallAndThreadTimes(total, threadMXBean)
|
||||
@Suppress("OVERRIDE_BY_INLINE")
|
||||
override inline fun endMeasure(obj: Any?, startState: List<Long>) = endWithMeasureWallAndThreadTimes(total, threadMXBean, startState)
|
||||
override inline fun endMeasure(obj: Any?, startState: List<Long>) = endMeasureWallAndThreadTimes(total, threadMXBean, startState)
|
||||
}
|
||||
|
||||
|
||||
class WallAndThreadAndMemoryTotalProfiler(val withGC: Boolean) : TotalProfiler() {
|
||||
@Suppress("OVERRIDE_BY_INLINE")
|
||||
override inline fun beginMeasure(obj: Any?) =
|
||||
beginWithMeasureWallAndThreadTimesAndMemory(total, withGC, threadMXBean)
|
||||
beginMeasureWallAndThreadTimesAndMemory(total, withGC, threadMXBean)
|
||||
@Suppress("OVERRIDE_BY_INLINE")
|
||||
override inline fun endMeasure(obj: Any?, startState: List<Long>) =
|
||||
endWithMeasureWallAndThreadTimesAndMemory(total, withGC, threadMXBean, startState)
|
||||
endMeasureWallAndThreadTimesAndMemory(total, withGC, threadMXBean, startState)
|
||||
}
|
||||
|
||||
|
||||
@@ -198,8 +198,8 @@ class WallAndThreadByClassProfiler() : TotalProfiler() {
|
||||
|
||||
@Suppress("OVERRIDE_BY_INLINE")
|
||||
override inline fun beginMeasure(obj: Any?) =
|
||||
beginWithMeasureWallAndThreadTimes(counters.getOrPut(obj?.javaClass?.name, { SimplePerfCountersWithTotal(total) }), threadMXBean)
|
||||
beginMeasureWallAndThreadTimes(counters.getOrPut(obj?.javaClass?.name, { SimplePerfCountersWithTotal(total) }), threadMXBean)
|
||||
@Suppress("OVERRIDE_BY_INLINE")
|
||||
override inline fun endMeasure(obj: Any?, startState: List<Long>) =
|
||||
endWithMeasureWallAndThreadTimes(counters.getOrPut(obj?.javaClass?.name, { SimplePerfCountersWithTotal(total) }), threadMXBean, startState)
|
||||
endMeasureWallAndThreadTimes(counters.getOrPut(obj?.javaClass?.name, { SimplePerfCountersWithTotal(total) }), threadMXBean, startState)
|
||||
}
|
||||
|
||||
@@ -41,10 +41,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.daemon.common.*
|
||||
import org.jetbrains.kotlin.daemon.report.CompileServicesFacadeMessageCollector
|
||||
import org.jetbrains.kotlin.daemon.report.DaemonMessageReporter
|
||||
import org.jetbrains.kotlin.daemon.report.DaemonMessageReporterPrintStreamAdapter
|
||||
import org.jetbrains.kotlin.daemon.report.getICReporter
|
||||
import org.jetbrains.kotlin.daemon.report.*
|
||||
import org.jetbrains.kotlin.incremental.*
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
@@ -389,7 +386,6 @@ abstract class CompileServiceImplBase(
|
||||
val exitCode = checkedCompile(daemonMessageReporter, rpcProfiler) {
|
||||
body(eventManager, rpcProfiler).code
|
||||
}
|
||||
log.fine("got exitCode")
|
||||
CompileService.CallResult.Good(exitCode)
|
||||
} finally {
|
||||
eventManager.fireCompilationFinished()
|
||||
@@ -413,7 +409,7 @@ abstract class CompileServiceImplBase(
|
||||
|
||||
val endMem = if (daemonOptions.reportPerf) usedMemory(withGC = false) else 0L
|
||||
|
||||
log.info("Done with result " + res.toString())
|
||||
log.info("Done with result $res")
|
||||
|
||||
if (daemonOptions.reportPerf) {
|
||||
val pc = profiler.getTotalCounters()
|
||||
@@ -467,10 +463,13 @@ abstract class CompileServiceImplBase(
|
||||
// )
|
||||
// }
|
||||
|
||||
fun startDaemonLife() {
|
||||
fun startDaemonElections() {
|
||||
timer.schedule(10) {
|
||||
exceptionLoggingTimerThread { initiateElections() }
|
||||
}
|
||||
}
|
||||
|
||||
fun configurePeriodicActivities() {
|
||||
timer.schedule(delay = DAEMON_PERIODIC_CHECK_INTERVAL_MS, period = DAEMON_PERIODIC_CHECK_INTERVAL_MS) {
|
||||
exceptionLoggingTimerThread { periodicAndAfterSessionCheck() }
|
||||
}
|
||||
@@ -516,21 +515,11 @@ abstract class CompileServiceImplBase(
|
||||
}
|
||||
}
|
||||
|
||||
protected inline fun <R, KotlinJvmReplServiceT> withValidReplImpl(
|
||||
sessionId: Int,
|
||||
body: KotlinJvmReplServiceT.() -> R
|
||||
): CompileService.CallResult<R> =
|
||||
withValidClientOrSessionProxy(sessionId) { session ->
|
||||
(session?.data as? KotlinJvmReplServiceT?)?.let {
|
||||
CompileService.CallResult.Good(it.body())
|
||||
} ?: CompileService.CallResult.Error("Not a REPL session $sessionId")
|
||||
}
|
||||
|
||||
protected fun execJsIncrementalCompiler(
|
||||
args: K2JSCompilerArguments,
|
||||
incrementalCompilationOptions: IncrementalCompilationOptions,
|
||||
compilerMessageCollector: MessageCollector,
|
||||
reporter: ICReporter
|
||||
reporter: RemoteICReporter
|
||||
): ExitCode {
|
||||
val allKotlinFiles = arrayListOf<File>()
|
||||
val freeArgsWithoutKotlinFiles = arrayListOf<String>()
|
||||
@@ -561,7 +550,7 @@ abstract class CompileServiceImplBase(
|
||||
return try {
|
||||
compiler.compile(allKotlinFiles, args, compilerMessageCollector, changedFiles)
|
||||
} finally {
|
||||
(reporter as RemoteICReporter).flush()
|
||||
reporter.flush()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -569,18 +558,8 @@ abstract class CompileServiceImplBase(
|
||||
k2jvmArgs: K2JVMCompilerArguments,
|
||||
incrementalCompilationOptions: IncrementalCompilationOptions,
|
||||
compilerMessageCollector: MessageCollector,
|
||||
reporter: ICReporter
|
||||
reporter: RemoteICReporter
|
||||
): ExitCode {
|
||||
val moduleFile = k2jvmArgs.buildFile?.let(::File)
|
||||
assert(moduleFile?.exists() ?: false) { "Module does not exist ${k2jvmArgs.buildFile}" }
|
||||
|
||||
// todo: pass javaSourceRoots and allKotlinFiles using IncrementalCompilationOptions
|
||||
val parsedModule = run {
|
||||
val bytesOut = ByteArrayOutputStream()
|
||||
val printStream = PrintStream(bytesOut)
|
||||
val mc = PrintingMessageCollector(printStream, MessageRenderer.PLAIN_FULL_PATHS, false)
|
||||
val parsedModule = ModuleXmlParser.parseModuleScript(k2jvmArgs.buildFile!!, mc)
|
||||
parsedModule
|
||||
val allKotlinExtensions = (DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS +
|
||||
(incrementalCompilationOptions.kotlinScriptExtensions ?: emptyArray())).distinct()
|
||||
val dotExtensions = allKotlinExtensions.map { ".$it" }
|
||||
@@ -614,27 +593,22 @@ abstract class CompileServiceImplBase(
|
||||
}
|
||||
}
|
||||
|
||||
val outputFiles = incrementalCompilationOptions.outputFiles.toMutableList()
|
||||
incrementalCompilationOptions.classpathFqNamesHistory?.let { outputFiles.add(it) }
|
||||
|
||||
val compiler = IncrementalJvmCompilerRunner(
|
||||
workingDir,
|
||||
reporter,
|
||||
buildHistoryFile = incrementalCompilationOptions.multiModuleICSettings.buildHistoryFile,
|
||||
outputFiles = outputFiles,
|
||||
outputFiles = incrementalCompilationOptions.outputFiles,
|
||||
usePreciseJavaTracking = incrementalCompilationOptions.usePreciseJavaTracking,
|
||||
modulesApiHistory = modulesApiHistory,
|
||||
kotlinSourceFilesExtensions = allKotlinExtensions,
|
||||
classpathFqNamesHistory = incrementalCompilationOptions.classpathFqNamesHistory
|
||||
kotlinSourceFilesExtensions = allKotlinExtensions
|
||||
)
|
||||
return try {
|
||||
compiler.compile(allKotlinFiles, k2jvmArgs, compilerMessageCollector, changedFiles)
|
||||
} finally {
|
||||
(reporter as RemoteICReporter).flush()
|
||||
reporter.flush()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmName("withValidReplImpl1")
|
||||
protected inline fun <R, KotlinJvmReplServiceT> withValidReplImpl(
|
||||
sessionId: Int,
|
||||
body: KotlinJvmReplServiceT.() -> CompileService.CallResult<R>
|
||||
@@ -838,7 +812,7 @@ class CompileServiceImpl(
|
||||
)
|
||||
val messageCollector = KeepFirstErrorMessageCollector(compilerMessagesStream)
|
||||
val repl = KotlinJvmReplService(
|
||||
disposable, port, templateClasspath, templateClassName,
|
||||
disposable, port, compilerId, templateClasspath, templateClassName,
|
||||
messageCollector, operationsTracer
|
||||
)
|
||||
val sessionId = state.sessions.leaseSession(ClientOrSessionProxy(aliveFlagPath, repl, disposable))
|
||||
@@ -922,7 +896,7 @@ class CompileServiceImpl(
|
||||
val disposable = Disposer.newDisposable()
|
||||
val messageCollector = CompileServicesFacadeMessageCollector(servicesFacade, compilationOptions)
|
||||
val repl = KotlinJvmReplService(
|
||||
disposable, port, templateClasspath, templateClassName,
|
||||
disposable, port, compilerId, templateClasspath, templateClassName,
|
||||
messageCollector, null
|
||||
)
|
||||
val sessionId = state.sessions.leaseSession(ClientOrSessionProxy(aliveFlagPath, repl, disposable))
|
||||
|
||||
@@ -55,22 +55,21 @@ class LogStream(name: String) : OutputStream() {
|
||||
}
|
||||
}
|
||||
|
||||
object KotlinCompileDaemon {
|
||||
|
||||
abstract class KotlinCompileDaemonBase {
|
||||
init {
|
||||
val logTime: String = SimpleDateFormat("yyyy-MM-dd.HH-mm-ss-SSS").format(Date())
|
||||
val (logPath: String, fileIsGiven: Boolean) =
|
||||
System.getProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY)?.trimQuotes()?.let { Pair(it, File(it).isFile) } ?: Pair("%t", false)
|
||||
val cfg: String =
|
||||
"handlers = java.util.logging.FileHandler\n" +
|
||||
"java.util.logging.FileHandler.level = ALL\n" +
|
||||
"java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter\n" +
|
||||
"java.util.logging.FileHandler.encoding = UTF-8\n" +
|
||||
"java.util.logging.FileHandler.limit = ${if (fileIsGiven) 0 else (1 shl 20)}\n" + // if file is provided - disabled, else - 1Mb
|
||||
"java.util.logging.FileHandler.count = ${if (fileIsGiven) 1 else 3}\n" +
|
||||
"java.util.logging.FileHandler.append = $fileIsGiven\n" +
|
||||
"java.util.logging.FileHandler.pattern = ${if (fileIsGiven) logPath else (logPath + File.separator + "$COMPILE_DAEMON_DEFAULT_FILES_PREFIX.$logTime.%u%g.log")}\n" +
|
||||
"java.util.logging.SimpleFormatter.format = %1\$tF %1\$tT.%1\$tL [%3\$s] %4\$s: %5\$s%n\n"
|
||||
"handlers = java.util.logging.FileHandler\n" +
|
||||
"java.util.logging.FileHandler.level = ALL\n" +
|
||||
"java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter\n" +
|
||||
"java.util.logging.FileHandler.encoding = UTF-8\n" +
|
||||
"java.util.logging.FileHandler.limit = ${if (fileIsGiven) 0 else (1 shl 20)}\n" + // if file is provided - disabled, else - 1Mb
|
||||
"java.util.logging.FileHandler.count = ${if (fileIsGiven) 1 else 3}\n" +
|
||||
"java.util.logging.FileHandler.append = $fileIsGiven\n" +
|
||||
"java.util.logging.FileHandler.pattern = ${if (fileIsGiven) logPath else (logPath + File.separator + "$COMPILE_DAEMON_DEFAULT_FILES_PREFIX.$logTime.%u%g.log")}\n" +
|
||||
"java.util.logging.SimpleFormatter.format = %1\$tF %1\$tT.%1\$tL [%3\$s] %4\$s: %5\$s%n\n"
|
||||
|
||||
LogManager.getLogManager().readConfiguration(cfg.byteInputStream())
|
||||
}
|
||||
@@ -78,19 +77,32 @@ object KotlinCompileDaemon {
|
||||
val log by lazy { Logger.getLogger("daemon") }
|
||||
|
||||
private fun loadVersionFromResource(): String? {
|
||||
(KotlinCompileDaemon::class.java.classLoader as? URLClassLoader)
|
||||
?.findResource("META-INF/MANIFEST.MF")
|
||||
?.let {
|
||||
try {
|
||||
return Manifest(it.openStream()).mainAttributes.getValue("Implementation-Version") ?: null
|
||||
}
|
||||
catch (e: IOException) {}
|
||||
(KotlinCompileDaemonBase::class.java.classLoader as? URLClassLoader)
|
||||
?.findResource("META-INF/MANIFEST.MF")
|
||||
?.let {
|
||||
try {
|
||||
return Manifest(it.openStream()).mainAttributes.getValue("Implementation-Version") ?: null
|
||||
}
|
||||
catch (e: IOException) {}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
protected open fun <T> runSynchronized(block: () -> T) = block()
|
||||
|
||||
protected abstract fun getCompileServiceAndPort(
|
||||
compilerSelector: CompilerSelector,
|
||||
compilerId: CompilerId,
|
||||
daemonOptions: DaemonOptions,
|
||||
daemonJVMOptions: DaemonJVMOptions,
|
||||
timer: Timer
|
||||
) : Pair<CompileServiceImplBase, Int>
|
||||
|
||||
protected open fun runCompileService(compileService: CompileServiceImplBase) : Any? = null
|
||||
|
||||
protected open fun awaitServerRun(serverRun: Any?) {}
|
||||
|
||||
protected fun mainImpl(args: Array<String>) {
|
||||
ensureServerHostnameIsSetUp()
|
||||
|
||||
val jvmArguments = ManagementFactory.getRuntimeMXBean().inputArguments
|
||||
@@ -103,84 +115,107 @@ object KotlinCompileDaemon {
|
||||
|
||||
val compilerId = CompilerId()
|
||||
val daemonOptions = DaemonOptions()
|
||||
runSynchronized {
|
||||
var serverRun: Any?
|
||||
try {
|
||||
val daemonJVMOptions = configureDaemonJVMOptions(inheritMemoryLimits = true,
|
||||
inheritOtherJvmOptions = true,
|
||||
inheritAdditionalProperties = true)
|
||||
|
||||
try {
|
||||
val daemonJVMOptions = configureDaemonJVMOptions(inheritMemoryLimits = true,
|
||||
inheritOtherJvmOptions = true,
|
||||
inheritAdditionalProperties = true)
|
||||
val filteredArgs = args.asIterable().filterExtractProps(compilerId, daemonOptions, prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX)
|
||||
|
||||
val filteredArgs = args.asIterable().filterExtractProps(compilerId, daemonOptions, prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX)
|
||||
|
||||
if (filteredArgs.any()) {
|
||||
val helpLine = "usage: <daemon> <compilerId options> <daemon options>"
|
||||
log.info(helpLine)
|
||||
println(helpLine)
|
||||
throw IllegalArgumentException("Unknown arguments: " + filteredArgs.joinToString(" "))
|
||||
}
|
||||
|
||||
log.info("starting daemon")
|
||||
|
||||
// TODO: find minimal set of permissions and restore security management
|
||||
// note: may be not needed anymore since (hopefully) server is now loopback-only
|
||||
// if (System.getSecurityManager() == null)
|
||||
// System.setSecurityManager (RMISecurityManager())
|
||||
//
|
||||
// setDaemonPermissions(daemonOptions.port)
|
||||
|
||||
val (registry, port) = findPortAndCreateRegistry(COMPILE_DAEMON_FIND_PORT_ATTEMPTS, COMPILE_DAEMON_PORTS_RANGE_START, COMPILE_DAEMON_PORTS_RANGE_END)
|
||||
|
||||
val compilerSelector = object : CompilerSelector {
|
||||
private val jvm by lazy { K2JVMCompiler() }
|
||||
private val js by lazy { K2JSCompiler() }
|
||||
private val metadata by lazy { K2MetadataCompiler() }
|
||||
override fun get(targetPlatform: CompileService.TargetPlatform): CLICompiler<*> = when (targetPlatform) {
|
||||
CompileService.TargetPlatform.JVM -> jvm
|
||||
CompileService.TargetPlatform.JS -> js
|
||||
CompileService.TargetPlatform.METADATA -> metadata
|
||||
if (filteredArgs.any()) {
|
||||
val helpLine = "usage: <daemon> <compilerId options> <daemon options>"
|
||||
log.info(helpLine)
|
||||
println(helpLine)
|
||||
throw IllegalArgumentException("Unknown arguments: " + filteredArgs.joinToString(" "))
|
||||
}
|
||||
|
||||
log.info("starting daemon")
|
||||
|
||||
// TODO: find minimal set of permissions and restore security management
|
||||
// note: may be not needed anymore since (hopefully) server is now loopback-only
|
||||
// if (System.getSecurityManager() == null)
|
||||
// System.setSecurityManager (RMISecurityManager())
|
||||
//
|
||||
// setDaemonPermissions(daemonOptions.port)
|
||||
|
||||
val compilerSelector = object : CompilerSelector {
|
||||
private val jvm by lazy { K2JVMCompiler() }
|
||||
private val js by lazy { K2JSCompiler() }
|
||||
private val metadata by lazy { K2MetadataCompiler() }
|
||||
override fun get(targetPlatform: CompileService.TargetPlatform): CLICompiler<*> = when (targetPlatform) {
|
||||
CompileService.TargetPlatform.JVM -> jvm
|
||||
CompileService.TargetPlatform.JS -> js
|
||||
CompileService.TargetPlatform.METADATA -> metadata
|
||||
}
|
||||
}
|
||||
// timer with a daemon thread, meaning it should not prevent JVM to exit normally
|
||||
val timer = Timer(true)
|
||||
val (compilerService, port) = getCompileServiceAndPort(compilerSelector, compilerId, daemonOptions, daemonJVMOptions, timer)
|
||||
compilerService.startDaemonElections()
|
||||
compilerService.configurePeriodicActivities()
|
||||
serverRun = runCompileService(compilerService)
|
||||
|
||||
println(COMPILE_DAEMON_IS_READY_MESSAGE)
|
||||
log.info("daemon is listening on port: $port")
|
||||
|
||||
// this supposed to stop redirected streams reader(s) on the client side and prevent some situations with hanging threads, but doesn't work reliably
|
||||
// TODO: implement more reliable scheme
|
||||
System.out.close()
|
||||
System.err.close()
|
||||
|
||||
System.setErr(PrintStream(LogStream("stderr")))
|
||||
System.setOut(PrintStream(LogStream("stdout")))
|
||||
}
|
||||
// timer with a daemon thread, meaning it should not prevent JVM to exit normally
|
||||
val timer = Timer(true)
|
||||
val compilerService = CompileServiceImpl(registry = registry,
|
||||
compiler = compilerSelector,
|
||||
compilerId = compilerId,
|
||||
daemonOptions = daemonOptions,
|
||||
daemonJVMOptions = daemonJVMOptions,
|
||||
port = port,
|
||||
timer = timer,
|
||||
onShutdown = {
|
||||
if (daemonOptions.forceShutdownTimeoutMilliseconds != COMPILE_DAEMON_TIMEOUT_INFINITE_MS) {
|
||||
// running a watcher thread that ensures that if the daemon is not exited normally (may be due to RMI leftovers), it's forced to exit
|
||||
timer.schedule(daemonOptions.forceShutdownTimeoutMilliseconds) {
|
||||
cancel()
|
||||
log.info("force JVM shutdown")
|
||||
exitProcess(0)
|
||||
}
|
||||
}
|
||||
else {
|
||||
timer.cancel()
|
||||
}
|
||||
})
|
||||
compilerService.startDaemonLife()
|
||||
|
||||
println(COMPILE_DAEMON_IS_READY_MESSAGE)
|
||||
log.info("daemon is listening on port: $port")
|
||||
|
||||
// this supposed to stop redirected streams reader(s) on the client side and prevent some situations with hanging threads, but doesn't work reliably
|
||||
// TODO: implement more reliable scheme
|
||||
System.out.close()
|
||||
System.err.close()
|
||||
|
||||
System.setErr(PrintStream(LogStream("stderr")))
|
||||
System.setOut(PrintStream(LogStream("stdout")))
|
||||
}
|
||||
catch (e: Exception) {
|
||||
System.err.println("Exception: " + e.message)
|
||||
e.printStackTrace(System.err)
|
||||
// repeating it to log for the cases when stderr is not redirected yet
|
||||
log.log(Level.INFO, "Exception: ", e)
|
||||
// TODO consider exiting without throwing
|
||||
throw e
|
||||
catch (e: Exception) {
|
||||
System.err.println("Exception: " + e.message)
|
||||
e.printStackTrace(System.err)
|
||||
// repeating it to log for the cases when stderr is not redirected yet
|
||||
log.log(Level.INFO, "Exception: ", e)
|
||||
// TODO consider exiting without throwing
|
||||
throw e
|
||||
}
|
||||
awaitServerRun(serverRun)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object KotlinCompileDaemon : KotlinCompileDaemonBase() {
|
||||
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
mainImpl(args)
|
||||
}
|
||||
|
||||
override fun getCompileServiceAndPort(
|
||||
compilerSelector: CompilerSelector,
|
||||
compilerId: CompilerId,
|
||||
daemonOptions: DaemonOptions,
|
||||
daemonJVMOptions: DaemonJVMOptions,
|
||||
timer: Timer
|
||||
) = run {
|
||||
val (registry, port) = findPortAndCreateRegistry(COMPILE_DAEMON_FIND_PORT_ATTEMPTS, COMPILE_DAEMON_PORTS_RANGE_START, COMPILE_DAEMON_PORTS_RANGE_END)
|
||||
val compilerService = CompileServiceImpl(registry = registry,
|
||||
compiler = compilerSelector,
|
||||
compilerId = compilerId,
|
||||
daemonOptions = daemonOptions,
|
||||
daemonJVMOptions = daemonJVMOptions,
|
||||
port = port,
|
||||
timer = timer,
|
||||
onShutdown = {
|
||||
if (daemonOptions.forceShutdownTimeoutMilliseconds != COMPILE_DAEMON_TIMEOUT_INFINITE_MS) {
|
||||
// running a watcher thread that ensures that if the daemon is not exited normally (may be due to RMI leftovers), it's forced to exit
|
||||
timer.schedule(daemonOptions.forceShutdownTimeoutMilliseconds) {
|
||||
cancel()
|
||||
log.info("force JVM shutdown")
|
||||
exitProcess(0)
|
||||
}
|
||||
}
|
||||
else {
|
||||
timer.cancel()
|
||||
}
|
||||
})
|
||||
Pair(compilerService, port)
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,8 @@ import kotlin.concurrent.write
|
||||
|
||||
abstract class KotlinJvmReplServiceBase(
|
||||
disposable: Disposable,
|
||||
val compilerId: CompilerId,templateClasspath: List<File>,
|
||||
val compilerId: CompilerId,
|
||||
templateClasspath: List<File>,
|
||||
templateClassName: String,
|
||||
protected val messageCollector: MessageCollector
|
||||
) : ReplCompileAction, ReplCheckAction, CreateReplStageStateAction {
|
||||
@@ -60,27 +61,6 @@ abstract class KotlinJvmReplServiceBase(
|
||||
configureScripting(compilerId)
|
||||
}
|
||||
|
||||
protected fun makeScriptDefinition(templateClasspath: List<File>, templateClassName: String): KotlinScriptDefinition? {
|
||||
val classloader = URLClassLoader(templateClasspath.map { it.toURI().toURL() }.toTypedArray(), this::class.java.classLoader)
|
||||
|
||||
try {
|
||||
val cls = classloader.loadClass(templateClassName)
|
||||
val def = KotlinScriptDefinitionFromAnnotatedTemplate(cls.kotlin, emptyMap())
|
||||
messageCollector.report(INFO, "New script definition $templateClassName: files pattern = \"${def.scriptFilePattern}\", " +
|
||||
"resolver = ${def.dependencyResolver.javaClass.name}")
|
||||
return def
|
||||
}
|
||||
catch (ex: ClassNotFoundException) {
|
||||
messageCollector.report(ERROR, "Cannot find script definition template class $templateClassName")
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
messageCollector.report(ERROR, "Error processing script definition template $templateClassName: ${ex.message}")
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private val scriptDef = makeScriptDefinition(templateClasspath, templateClassName)
|
||||
|
||||
protected val replCompiler: ReplCompiler? by lazy {
|
||||
try {
|
||||
val projectEnvironment =
|
||||
@@ -142,12 +122,13 @@ abstract class KotlinJvmReplServiceBase(
|
||||
open class KotlinJvmReplService(
|
||||
disposable: Disposable,
|
||||
val portForServers: Int,
|
||||
compilerId: CompilerId,
|
||||
templateClasspath: List<File>,
|
||||
templateClassName: String,
|
||||
messageCollector: MessageCollector,
|
||||
@Deprecated("drop it")
|
||||
protected val operationsTracer: RemoteOperationsTracer?
|
||||
) : KotlinJvmReplServiceBase(disposable, templateClasspath, templateClassName, messageCollector) {
|
||||
) : KotlinJvmReplServiceBase(disposable, compilerId, templateClasspath, templateClassName, messageCollector) {
|
||||
|
||||
override fun before(s: String) {
|
||||
operationsTracer?.before(s)
|
||||
|
||||
+6
-4
@@ -331,10 +331,12 @@ class CompileServiceServerSideImpl(
|
||||
compilationOptions,
|
||||
servicesFacade,
|
||||
compilationResults,
|
||||
hasIncrementalCaches = CompilerCallbackServicesFacadeClientSide::hasIncrementalCaches,
|
||||
hasIncrementalCaches = { hasIncrementalCaches() },
|
||||
createMessageCollector = ::CompileServicesFacadeMessageCollector,
|
||||
createReporter = ::DaemonMessageReporterAsync,
|
||||
createServices = this::createCompileServices,
|
||||
createServices = { facade: CompilerCallbackServicesFacadeClientSide, eventMgr, profiler ->
|
||||
createCompileServices(facade, eventMgr, profiler)
|
||||
},
|
||||
getICReporter = ::getICReporterAsync
|
||||
)
|
||||
|
||||
@@ -353,7 +355,7 @@ class CompileServiceServerSideImpl(
|
||||
val messageCollector =
|
||||
CompileServicesFacadeMessageCollector(servicesFacade, compilationOptions)
|
||||
val repl = KotlinJvmReplServiceAsync(
|
||||
disposable, serverSocketWithPort, templateClasspath, templateClassName,
|
||||
disposable, serverSocketWithPort, compilerId, templateClasspath, templateClassName,
|
||||
messageCollector
|
||||
)
|
||||
val sessionId = state.sessions.leaseSession(ClientOrSessionProxy(aliveFlagPath, repl, disposable))
|
||||
@@ -407,7 +409,7 @@ class CompileServiceServerSideImpl(
|
||||
System.setProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY, "true")
|
||||
|
||||
// TODO UNCOMMENT THIS : this.toRMIServer(daemonOptions, compilerId) // also create RMI server in order to support old clients
|
||||
rmiServer = this.toRMIServer(daemonOptions, compilerId)
|
||||
// rmiServer = this.toRMIServer(daemonOptions, compilerId)
|
||||
|
||||
KeepAliveServer.runServer()
|
||||
}
|
||||
|
||||
+43
-162
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback
|
||||
import org.jetbrains.kotlin.cli.js.K2JSCompiler
|
||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
||||
import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler
|
||||
import org.jetbrains.kotlin.daemon.CompileServiceImplBase
|
||||
import org.jetbrains.kotlin.daemon.CompilerSelector
|
||||
import org.jetbrains.kotlin.daemon.common.*
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.findPortForSocket
|
||||
@@ -29,174 +30,54 @@ import java.util.logging.Level
|
||||
import java.util.logging.LogManager
|
||||
import java.util.logging.Logger
|
||||
import kotlin.concurrent.schedule
|
||||
import org.jetbrains.kotlin.daemon.KotlinCompileDaemonBase
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.CompileServiceServerSide
|
||||
|
||||
object KotlinCompileDaemon : KotlinCompileDaemonBase() {
|
||||
override fun <T> runSynchronized(block: () -> T) = runBlocking { block() }
|
||||
|
||||
class LogStream(name: String) : OutputStream() {
|
||||
|
||||
val log by lazy { Logger.getLogger(name) }
|
||||
|
||||
val lineBuf = StringBuilder()
|
||||
|
||||
override fun write(byte: Int) {
|
||||
if (byte.toChar() == '\n') flush()
|
||||
else lineBuf.append(byte.toChar())
|
||||
}
|
||||
|
||||
override fun flush() {
|
||||
log.info(lineBuf.toString())
|
||||
lineBuf.setLength(0)
|
||||
}
|
||||
}
|
||||
|
||||
object KotlinCompileDaemon {
|
||||
|
||||
init {
|
||||
|
||||
val logTime: String = SimpleDateFormat("yyyy-MM-dd.HH-mm-ss-SSS").format(Date())
|
||||
val (logPath: String, fileIsGiven: Boolean) =
|
||||
System.getProperty(COMPILE_DAEMON_LOG_PATH_PROPERTY)?.trimQuotes()?.let { Pair(it, File(it).isFile) } ?: Pair("%t", false)
|
||||
val cfg: String =
|
||||
"handlers = java.util.logging.FileHandler\n" +
|
||||
"java.util.logging.FileHandler.level = ALL\n" +
|
||||
"java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter\n" +
|
||||
"java.util.logging.FileHandler.encoding = UTF-8\n" +
|
||||
"java.util.logging.FileHandler.limit = ${if (fileIsGiven) 0 else (1 shl 20)}\n" + // if file is provided - disabled, else - 1Mb
|
||||
"java.util.logging.FileHandler.count = ${if (fileIsGiven) 1 else 3}\n" +
|
||||
"java.util.logging.FileHandler.append = $fileIsGiven\n" +
|
||||
"java.util.logging.FileHandler.pattern = ${if (fileIsGiven) logPath else (logPath + File.separator + "$COMPILE_DAEMON_DEFAULT_FILES_PREFIX.$logTime.%u%g.log")}\n" +
|
||||
"java.util.logging.SimpleFormatter.format = %1\$tF %1\$tT.%1\$tL [%3\$s] %4\$s: %5\$s%n\n"
|
||||
|
||||
LogManager.getLogManager().readConfiguration(cfg.byteInputStream())
|
||||
}
|
||||
|
||||
val log by lazy { Logger.getLogger("daemon") }
|
||||
|
||||
private fun loadVersionFromResource(): String? {
|
||||
(KotlinCompileDaemon::class.java.classLoader as? URLClassLoader)
|
||||
?.findResource("META-INF/MANIFEST.MF")
|
||||
?.let {
|
||||
try {
|
||||
return Manifest(it.openStream()).mainAttributes.getValue("Implementation-Version") ?: null
|
||||
} catch (e: IOException) {
|
||||
override fun getCompileServiceAndPort(
|
||||
compilerSelector: CompilerSelector,
|
||||
compilerId: CompilerId,
|
||||
daemonOptions: DaemonOptions,
|
||||
daemonJVMOptions: DaemonJVMOptions,
|
||||
timer: Timer
|
||||
) = run {
|
||||
val port = findPortForSocket(
|
||||
COMPILE_DAEMON_FIND_PORT_ATTEMPTS,
|
||||
COMPILE_DAEMON_PORTS_RANGE_START,
|
||||
COMPILE_DAEMON_PORTS_RANGE_END
|
||||
)
|
||||
val compilerService = CompileServiceServerSideImpl(
|
||||
port,
|
||||
compilerSelector,
|
||||
compilerId,
|
||||
daemonOptions,
|
||||
daemonJVMOptions,
|
||||
port.port,
|
||||
timer,
|
||||
{
|
||||
if (daemonOptions.forceShutdownTimeoutMilliseconds != COMPILE_DAEMON_TIMEOUT_INFINITE_MS) {
|
||||
// running a watcher thread that ensures that if the daemon is not exited normally (may be due to RMI leftovers), it's forced to exit
|
||||
timer.schedule(daemonOptions.forceShutdownTimeoutMilliseconds) {
|
||||
cancel()
|
||||
log.info("force JVM shutdown")
|
||||
System.exit(0)
|
||||
}
|
||||
} else {
|
||||
timer.cancel()
|
||||
}
|
||||
}
|
||||
return null
|
||||
})
|
||||
Pair(compilerService, port.port)
|
||||
}
|
||||
|
||||
override fun runCompileService(compileService: CompileServiceImplBase) = (compileService as CompileServiceServerSide).runServer()
|
||||
override fun awaitServerRun(serverRun: Any?) {
|
||||
runBlocking { (serverRun as Deferred<Unit>?)?.await() }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
ensureServerHostnameIsSetUp()
|
||||
|
||||
val jvmArguments = ManagementFactory.getRuntimeMXBean().inputArguments
|
||||
|
||||
log.info("Kotlin compiler daemon version " + (loadVersionFromResource() ?: "<unknown>"))
|
||||
log.info("daemon JVM args: " + jvmArguments.joinToString(" "))
|
||||
log.info("daemon args: " + args.joinToString(" "))
|
||||
|
||||
setIdeaIoUseFallback()
|
||||
|
||||
val compilerId = CompilerId()
|
||||
val daemonOptions = DaemonOptions()
|
||||
|
||||
runBlocking {
|
||||
|
||||
var serverRun: Deferred<Unit>?
|
||||
|
||||
try {
|
||||
val daemonJVMOptions = configureDaemonJVMOptions(
|
||||
inheritMemoryLimits = true,
|
||||
inheritOtherJvmOptions = true,
|
||||
inheritAdditionalProperties = true
|
||||
)
|
||||
|
||||
val filteredArgs = args.asIterable()
|
||||
.filterExtractProps(
|
||||
compilerId,
|
||||
daemonOptions,
|
||||
prefix = COMPILE_DAEMON_CMDLINE_OPTIONS_PREFIX
|
||||
)
|
||||
|
||||
if (filteredArgs.any()) {
|
||||
val helpLine = "usage: <daemon> <compilerId options> <daemon options>"
|
||||
|
||||
log.info(helpLine)
|
||||
println(helpLine)
|
||||
throw IllegalArgumentException("Unknown arguments: " + filteredArgs.joinToString(" "))
|
||||
}
|
||||
|
||||
log.info("starting daemon")
|
||||
|
||||
// TODO: find minimal set of permissions and restore security management
|
||||
// note: may be not needed anymore since (hopefully) server is now loopback-only
|
||||
// if (System.getSecurityManager() == null)
|
||||
// System.setSecurityManager (RMISecurityManager())
|
||||
//
|
||||
// setDaemonPermissions(daemonOptions.socketPort)
|
||||
|
||||
val port = findPortForSocket(
|
||||
COMPILE_DAEMON_FIND_PORT_ATTEMPTS,
|
||||
COMPILE_DAEMON_PORTS_RANGE_START,
|
||||
COMPILE_DAEMON_PORTS_RANGE_END
|
||||
)
|
||||
|
||||
|
||||
val compilerSelector = object : CompilerSelector {
|
||||
private val jvm by lazy { K2JVMCompiler() }
|
||||
private val js by lazy { K2JSCompiler() }
|
||||
private val metadata by lazy { K2MetadataCompiler() }
|
||||
override fun get(targetPlatform: CompileService.TargetPlatform): CLICompiler<*> = when (targetPlatform) {
|
||||
CompileService.TargetPlatform.JVM -> jvm
|
||||
CompileService.TargetPlatform.JS -> js
|
||||
CompileService.TargetPlatform.METADATA -> metadata
|
||||
}
|
||||
}
|
||||
|
||||
// timer with a daemon thread, meaning it should not prevent JVM to exit normally
|
||||
val timer = Timer(true)
|
||||
val compilerService = CompileServiceServerSideImpl(
|
||||
port,
|
||||
compilerSelector,
|
||||
compilerId,
|
||||
daemonOptions,
|
||||
daemonJVMOptions,
|
||||
port.port,
|
||||
timer,
|
||||
{
|
||||
if (daemonOptions.forceShutdownTimeoutMilliseconds != COMPILE_DAEMON_TIMEOUT_INFINITE_MS) {
|
||||
// running a watcher thread that ensures that if the daemon is not exited normally (may be due to RMI leftovers), it's forced to exit
|
||||
timer.schedule(daemonOptions.forceShutdownTimeoutMilliseconds) {
|
||||
cancel()
|
||||
log.info("force JVM shutdown")
|
||||
System.exit(0)
|
||||
}
|
||||
} else {
|
||||
timer.cancel()
|
||||
}
|
||||
})
|
||||
compilerService.startDaemonLife()
|
||||
serverRun = compilerService.runServer()
|
||||
|
||||
|
||||
println(COMPILE_DAEMON_IS_READY_MESSAGE)
|
||||
log.info("daemon is listening on port: ${port.port}")
|
||||
|
||||
// this supposed to stop redirected streams reader(s) on the client side and prevent some situations with hanging threads, but doesn't work reliably
|
||||
// TODO: implement more reliable scheme
|
||||
System.out.close()
|
||||
System.err.close()
|
||||
|
||||
System.setErr(PrintStream(LogStream("stderr")))
|
||||
System.setOut(PrintStream(LogStream("stdout")))
|
||||
} catch (e: Exception) {
|
||||
log.log(Level.ALL, "Exception: " + e.message)
|
||||
e.printStackTrace(System.err)
|
||||
// repeating it to log for the cases when stderr is not redirected yet
|
||||
log.log(Level.INFO, "Exception: ", e)
|
||||
// TODO consider exiting without throwing
|
||||
throw e
|
||||
}
|
||||
serverRun.await()
|
||||
}
|
||||
mainImpl(args)
|
||||
}
|
||||
|
||||
}
|
||||
+4
-7
@@ -8,9 +8,9 @@ package org.jetbrains.kotlin.daemon.experimental
|
||||
import com.intellij.openapi.Disposable
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.repl.IReplStageState
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.GenericReplCompilerState
|
||||
import org.jetbrains.kotlin.daemon.KotlinJvmReplServiceBase
|
||||
import org.jetbrains.kotlin.daemon.common.CompileService
|
||||
import org.jetbrains.kotlin.daemon.common.CompilerId
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.ServerSocketWrapper
|
||||
import org.jetbrains.kotlin.daemon.getValidId
|
||||
import java.io.File
|
||||
@@ -21,20 +21,17 @@ import kotlin.concurrent.write
|
||||
open class KotlinJvmReplServiceAsync(
|
||||
disposable: Disposable,
|
||||
val portForServers: ServerSocketWrapper,
|
||||
compilerId: CompilerId,
|
||||
templateClasspath: List<File>,
|
||||
templateClassName: String,
|
||||
messageCollector: MessageCollector
|
||||
) : KotlinJvmReplServiceBase(disposable, templateClasspath, templateClassName, messageCollector) {
|
||||
) : KotlinJvmReplServiceBase(disposable, compilerId, templateClasspath, templateClassName, messageCollector) {
|
||||
|
||||
protected val states = WeakHashMap<RemoteReplStateFacadeServerSide, Boolean>() // used as (missing) WeakHashSet
|
||||
|
||||
suspend fun createRemoteState(port: ServerSocketWrapper = portForServers): RemoteReplStateFacadeServerSide = statesLock.write {
|
||||
val id = getValidId(stateIdCounter) { id -> states.none { it.key.getId() == id } }
|
||||
val stateFacade = RemoteReplStateFacadeServerSide(
|
||||
id,
|
||||
createState().asState(GenericReplCompilerState::class.java),
|
||||
port
|
||||
)
|
||||
val stateFacade = RemoteReplStateFacadeServerSide(id, createState(), port)
|
||||
stateFacade.runServer()
|
||||
states.put(stateFacade, true)
|
||||
stateFacade
|
||||
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.daemon.experimental
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.RemoteOutputStreamAsyncClientSide
|
||||
import org.jetbrains.kotlin.daemon.common.DummyProfiler
|
||||
import org.jetbrains.kotlin.daemon.common.Profiler
|
||||
import org.jetbrains.kotlin.daemon.common.withMeasure
|
||||
import java.io.OutputStream
|
||||
|
||||
class RemoteOutputStreamClient(val remote: RemoteOutputStreamAsyncClientSide, val profiler: Profiler = DummyProfiler()) : OutputStream() {
|
||||
override fun write(data: ByteArray) = runBlocking {
|
||||
profiler.withMeasure(this) { remote.write(data, 0, data.size) }
|
||||
}
|
||||
|
||||
override fun write(data: ByteArray, offset: Int, length: Int) = runBlocking {
|
||||
profiler.withMeasure(this) { remote.write(data, offset, length) }
|
||||
}
|
||||
|
||||
override fun write(byte: Int) = runBlocking {
|
||||
profiler.withMeasure(this) { remote.write(byte) }
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.daemon.experimental
|
||||
|
||||
import io.ktor.network.sockets.Socket
|
||||
import org.jetbrains.kotlin.cli.common.repl.ILineId
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.GenericReplCompilerState
|
||||
import org.jetbrains.kotlin.cli.common.repl.IReplStageState
|
||||
import org.jetbrains.kotlin.daemon.common.COMPILE_DAEMON_FIND_PORT_ATTEMPTS
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.*
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.*
|
||||
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.*
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class RemoteReplStateFacadeServerSide(
|
||||
val _id: Int,
|
||||
val state: GenericReplCompilerState,
|
||||
val state: IReplStageState<*>,
|
||||
override val serverSocketWithPort: ServerSocketWrapper = findPortForSocket(
|
||||
COMPILE_DAEMON_FIND_PORT_ATTEMPTS,
|
||||
REPL_SERVER_PORTS_RANGE_START,
|
||||
|
||||
@@ -14,7 +14,7 @@ dependencies {
|
||||
compile(project(":compiler:cli"))
|
||||
compile(project(":compiler:cli-js"))
|
||||
compile(project(":kotlin-build-common"))
|
||||
compile(project(":compiler:daemon-common"))
|
||||
compile(project(":daemon-common"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
|
||||
testCompile(commonDep("junit:junit"))
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.incremental.multiproject
|
||||
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalModuleEntry
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalModuleInfo
|
||||
import org.jetbrains.kotlin.incremental.IncrementalModuleEntry
|
||||
import org.jetbrains.kotlin.incremental.IncrementalModuleInfo
|
||||
import org.jetbrains.kotlin.incremental.util.Either
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.incremental.multiproject
|
||||
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalModuleEntry
|
||||
import org.jetbrains.kotlin.daemon.common.IncrementalModuleInfo
|
||||
import org.jetbrains.kotlin.incremental.IncrementalModuleEntry
|
||||
import org.jetbrains.kotlin.incremental.IncrementalModuleInfo
|
||||
import org.jetbrains.kotlin.incremental.util.Either
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
|
||||
@@ -26,8 +26,8 @@ dependencies {
|
||||
testCompile(project(":compiler:light-classes"))
|
||||
testCompile(project(":compiler:serialization"))
|
||||
testCompile(project(":kotlin-preloader"))
|
||||
testCompile(project(":compiler:daemon-common"))
|
||||
testCompile(project(":compiler:daemon-common-new"))
|
||||
testCompile(project(":daemon-common"))
|
||||
testCompile(project(":daemon-common-new"))
|
||||
testCompile(project(":js:js.serializer"))
|
||||
testCompile(project(":js:js.frontend"))
|
||||
testCompile(project(":js:js.translator"))
|
||||
|
||||
@@ -40,7 +40,9 @@ class CompilerApiTest : KotlinIntegrationTestBase() {
|
||||
private val compilerLibDir = getCompilerLib()
|
||||
|
||||
val compilerClassPath = listOf(
|
||||
File(compilerLibDir, "kotlin-compiler.jar"))
|
||||
File(compilerLibDir, "kotlin-compiler.jar"),
|
||||
File(compilerLibDir, "kotlin-daemon.jar")
|
||||
)
|
||||
val compilerId by lazy(LazyThreadSafetyMode.NONE) { CompilerId.makeCompilerId(compilerClassPath) }
|
||||
|
||||
private fun compileLocally(messageCollector: TestMessageCollector, vararg args: String): Pair<Int, Collection<OutputMessageUtil.Output>> {
|
||||
|
||||
+4
-2
@@ -36,7 +36,7 @@ private val logFiles = arrayListOf<String>()
|
||||
class CompilerApiTest : KotlinIntegrationTestBase() {
|
||||
|
||||
val kotlinCompilerClient = KotlinCompilerDaemonClient
|
||||
.instantiate(DaemonProtocolVariant.RMI) // TODO(SOCKETS)
|
||||
.instantiate(DaemonProtocolVariant.SOCKETS) // TODO(SOCKETS)
|
||||
|
||||
private val compilerLibDir = getCompilerLib()
|
||||
|
||||
@@ -72,7 +72,9 @@ class CompilerApiTest : KotlinIntegrationTestBase() {
|
||||
}
|
||||
|
||||
val compilerClassPath = listOf(
|
||||
File(compilerLibDir, "kotlin-compiler.jar")
|
||||
File(compilerLibDir, "kotlin-compiler.jar"),
|
||||
File(compilerLibDir, "kotlin-daemon.jar"),
|
||||
File(compilerLibDir, "ktor-network-1.0.1.jar")
|
||||
)
|
||||
val scriptRuntimeClassPath = listOf(
|
||||
File(compilerLibDir, "kotlin-runtime.jar"),
|
||||
|
||||
+9
-7
@@ -50,7 +50,7 @@ import kotlin.script.templates.ScriptTemplateDefinition
|
||||
import kotlin.test.fail
|
||||
import org.jetbrains.kotlin.daemon.client.experimental.*
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.*
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.LoopbackNetworkInterface
|
||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||
|
||||
val TIMEOUT_DAEMON_RUNNER_EXIT_MS = 10000L
|
||||
|
||||
@@ -84,9 +84,7 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
|
||||
|
||||
data class CompilerResults(val resultCode: Int, val out: String)
|
||||
|
||||
val compilerClassPath = listOf(
|
||||
File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-compiler.jar")
|
||||
)
|
||||
val compilerClassPath = getKotlinPaths().classPath(KotlinPaths.ClassPaths.Compiler)
|
||||
|
||||
val scriptingCompilerClassPath = listOf(
|
||||
File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-scripting-compiler.jar"),
|
||||
@@ -96,7 +94,8 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
|
||||
|
||||
val daemonClientClassPath = listOf(
|
||||
File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-daemon-client-new.jar"),
|
||||
File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-compiler.jar")
|
||||
File(KotlinIntegrationTestBase.getCompilerLib(), "kotlin-compiler.jar"),
|
||||
File(KotlinIntegrationTestBase.getCompilerLib(), "ktor-network-1.0.1.jar")
|
||||
)
|
||||
|
||||
val compilerId by lazy(LazyThreadSafetyMode.NONE) { CompilerId.makeCompilerId(compilerClassPath) }
|
||||
@@ -156,7 +155,7 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
|
||||
|
||||
private fun run(logName: String, vararg args: String): Int = runJava(getTestBaseDir(), logName, *args)
|
||||
|
||||
fun makeTestDaemonOptions(testName: String, shutdownDelay: Int = 5) =
|
||||
fun makeTestDaemonOptions(testName: String, shutdownDelay: Int = 5000) =
|
||||
DaemonOptions(
|
||||
runFilesPath = File(tmpdir, testName).absolutePath,
|
||||
shutdownDelayMilliseconds = shutdownDelay.toLong(),
|
||||
@@ -1306,7 +1305,10 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
|
||||
port = serverPort,
|
||||
timer = timer,
|
||||
onShutdown = onShutdown
|
||||
).startDaemonLife()
|
||||
).let {
|
||||
it.startDaemonElections()
|
||||
it.configurePeriodicActivities()
|
||||
}
|
||||
println("old daemon init: port = $serverPort")
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import io.ktor.network.selector.SelectorManager
|
||||
import io.ktor.network.sockets.aSocket
|
||||
import kotlinx.coroutines.*
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.CompilerServicesFacadeBaseClientSideImpl
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.LoopbackNetworkInterface.selectorMgr
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.LoopbackNetworkInterfaceKtor.selectorMgr
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.DefaultClient
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.ServerBase
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.socketInfrastructure.openIO
|
||||
|
||||
@@ -139,7 +139,8 @@ class ConnectionsTest : KotlinIntegrationTestBase() {
|
||||
onShutdown
|
||||
).let {
|
||||
log.info("service created")
|
||||
it.startDaemonLife()
|
||||
it.startDaemonElections()
|
||||
it.configurePeriodicActivities()
|
||||
it.runServer()
|
||||
}
|
||||
}
|
||||
@@ -170,7 +171,10 @@ class ConnectionsTest : KotlinIntegrationTestBase() {
|
||||
port = serverPort,
|
||||
timer = timer,
|
||||
onShutdown = onShutdown
|
||||
).startDaemonLife()
|
||||
).let {
|
||||
it.startDaemonElections()
|
||||
it.configurePeriodicActivities()
|
||||
}
|
||||
}
|
||||
|
||||
val comparator = compareByDescending<DaemonWithMetadataAsync, DaemonJVMOptions>(
|
||||
|
||||
@@ -98,11 +98,14 @@ interface KotlinPaths {
|
||||
ScriptingLib(PathUtil.KOTLIN_SCRIPTING_COMMON_NAME),
|
||||
ScriptingJvmLib(PathUtil.KOTLIN_SCRIPTING_JVM_NAME),
|
||||
CoroutinesCore(PathUtil.KOTLINX_COROUTINES_CORE_NAME),
|
||||
KotlinDaemon(PathUtil.KOTLIN_DAEMON_NAME),
|
||||
Ktor(PathUtil.KTOR_NAME),
|
||||
}
|
||||
|
||||
// TODO: Maybe we need separate classpaths for compilers with and without the daemon
|
||||
enum class ClassPaths(val contents: List<Jar> = emptyList()) {
|
||||
Empty(),
|
||||
Compiler(Jar.Compiler, Jar.StdLib, Jar.Reflect, Jar.ScriptRuntime, Jar.Trove4j),
|
||||
Compiler(Jar.Compiler, Jar.StdLib, Jar.Reflect, Jar.ScriptRuntime, Jar.Trove4j, Jar.KotlinDaemon, Jar.Ktor),
|
||||
CompilerWithScripting(Compiler, Jar.ScriptingPlugin, Jar.ScriptingImpl, Jar.ScriptingLib, Jar.ScriptingJvmLib)
|
||||
;
|
||||
|
||||
|
||||
@@ -65,6 +65,9 @@ object PathUtil {
|
||||
const val KOTLIN_SCRIPTING_COMMON_JAR = "$KOTLIN_SCRIPTING_COMMON_NAME.jar"
|
||||
const val KOTLIN_SCRIPTING_JVM_NAME = "kotlin-scripting-jvm"
|
||||
const val KOTLIN_SCRIPTING_JVM_JAR = "$KOTLIN_SCRIPTING_JVM_NAME.jar"
|
||||
const val KOTLIN_DAEMON_NAME = "kotlin-daemon"
|
||||
const val KTOR_NAME = "ktor-network-1.0.1"
|
||||
const val KOTLIN_DAEMON_JAR = "$KOTLIN_SCRIPTING_JVM_NAME.jar"
|
||||
const val KOTLIN_SCRIPTING_COMPILER_PLUGIN_NAME = "kotlin-scripting-compiler"
|
||||
const val KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR = "$KOTLIN_SCRIPTING_COMPILER_PLUGIN_NAME.jar"
|
||||
const val KOTLINX_COROUTINES_CORE_NAME = "kotlinx-coroutines-core"
|
||||
|
||||
@@ -26,8 +26,8 @@ dependencies {
|
||||
compile(project(":compiler:light-classes"))
|
||||
compile(project(":compiler:util"))
|
||||
compile(project(":kotlin-build-common"))
|
||||
compile(project(":compiler:daemon-common"))
|
||||
compile(project(":compiler:daemon-common-new"))
|
||||
compile(project(":daemon-common"))
|
||||
compile(project(":daemon-common-new"))
|
||||
compile(projectRuntimeJar(":kotlin-daemon-client"))
|
||||
compile(project(":kotlin-compiler-runner")) { isTransitive = false }
|
||||
compile(project(":compiler:plugin-api"))
|
||||
|
||||
@@ -123,8 +123,8 @@ extra["compilerModules"] = arrayOf(
|
||||
":compiler:frontend.java",
|
||||
":compiler:frontend.script",
|
||||
":compiler:cli-common",
|
||||
":compiler:daemon-common",
|
||||
":compiler:daemon",
|
||||
":daemon-common",
|
||||
":daemon",
|
||||
":compiler:ir.tree",
|
||||
":compiler:ir.psi2ir",
|
||||
":compiler:ir.backend.common",
|
||||
|
||||
@@ -10,9 +10,10 @@ dependencies {
|
||||
compile(project(":core:descriptors"))
|
||||
compile(project(":core:descriptors.jvm"))
|
||||
compile(project(":kotlin-compiler-runner"))
|
||||
compile(project(":compiler:daemon-common"))
|
||||
compile(project(":compiler:daemon-common-new"))
|
||||
compile(project(":daemon-common"))
|
||||
compile(project(":daemon-common-new"))
|
||||
compile(projectRuntimeJar(":kotlin-daemon-client"))
|
||||
compile(projectRuntimeJar(":kotlin-daemon"))
|
||||
compile(project(":compiler:frontend.java"))
|
||||
compile(project(":js:js.frontend"))
|
||||
compile(projectRuntimeJar(":kotlin-preloader"))
|
||||
|
||||
@@ -338,8 +338,9 @@ class JpsKotlinCompilerRunner {
|
||||
environment.progressReporter.progress("connecting to daemon")
|
||||
val libPath = CompilerRunnerUtil.getLibPath(environment.kotlinPaths, environment.messageCollector)
|
||||
val compilerPath = File(libPath, "kotlin-compiler.jar")
|
||||
val daemonJarPath = File(libPath, "kotlin-daemon.jar")
|
||||
val toolsJarPath = CompilerRunnerUtil.jdkToolsJar
|
||||
val compilerId = CompilerId.makeCompilerId(listOfNotNull(compilerPath, toolsJarPath))
|
||||
val compilerId = CompilerId.makeCompilerId(listOfNotNull(compilerPath, toolsJarPath, daemonJarPath))
|
||||
val daemonOptions = configureDaemonOptions()
|
||||
val additionalJvmParams = mutableListOf<String>()
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ dependencies {
|
||||
testCompile(project(":kotlin-script-runtime"))
|
||||
testCompile(project(":kotlin-script-util"))
|
||||
testCompile(projectRuntimeJar(":kotlin-daemon-client"))
|
||||
testCompile(projectRuntimeJar(":kotlin-daemon"))
|
||||
testCompile(projectRuntimeJar(":kotlin-compiler-embeddable"))
|
||||
testCompile(commonDep("junit:junit"))
|
||||
testCompile(project(":kotlin-test:kotlin-test-junit"))
|
||||
@@ -30,7 +31,7 @@ dependencies {
|
||||
compilerClasspath(commonDep("org.jetbrains.intellij.deps", "trove4j"))
|
||||
compileOnly(project(":compiler:cli-common")) // TODO: fix import (workaround for jps build)
|
||||
testCompileOnly(project(":core:util.runtime")) // TODO: fix import (workaround for jps build)
|
||||
testCompileOnly(project(":compiler:daemon-common")) // TODO: fix import (workaround for jps build)
|
||||
testCompileOnly(project(":daemon-common")) // TODO: fix import (workaround for jps build)
|
||||
}
|
||||
|
||||
projectTest {
|
||||
|
||||
@@ -22,7 +22,7 @@ dependencies {
|
||||
testRuntime(project(":kotlin-reflect"))
|
||||
compileOnly(project(":compiler:cli-common")) // TODO: fix import (workaround for jps build)
|
||||
testCompileOnly(project(":core:util.runtime")) // TODO: fix import (workaround for jps build)
|
||||
testCompileOnly(project(":compiler:daemon-common")) // TODO: fix import (workaround for jps build)
|
||||
testCompileOnly(project(":daemon-common")) // TODO: fix import (workaround for jps build)
|
||||
testRuntime(project(":kotlin-scripting-compiler-embeddable"))
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ dependencies {
|
||||
runtime(project(":kotlin-reflect"))
|
||||
testCompile(projectTests(":compiler:tests-common"))
|
||||
testCompile(commonDep("junit"))
|
||||
testCompile(project(":compiler:daemon-common")) // TODO: fix import (workaround for jps build)
|
||||
testCompile(project(":daemon-common")) // TODO: fix import (workaround for jps build)
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
||||
@@ -34,7 +34,7 @@ dependencies {
|
||||
compile(project(":kotlin-gradle-plugin-model"))
|
||||
compileOnly(project(":compiler"))
|
||||
compileOnly(project(":compiler:incremental-compilation-impl"))
|
||||
compileOnly(project(":compiler:daemon-common"))
|
||||
compileOnly(project(":daemon-common"))
|
||||
|
||||
compile(kotlinStdlib())
|
||||
compileOnly(project(":kotlin-reflect-api"))
|
||||
|
||||
+14
-2
@@ -36,6 +36,8 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.utils.newTmpFile
|
||||
import org.jetbrains.kotlin.gradle.utils.relativeToRoot
|
||||
import org.jetbrains.kotlin.incremental.IncrementalModuleInfo
|
||||
import org.jetbrains.kotlin.incremental.IncrementalModuleEntry
|
||||
import org.jetbrains.kotlin.incremental.classpathAsList
|
||||
import org.jetbrains.kotlin.incremental.destinationAsFile
|
||||
import org.jetbrains.kotlin.incremental.makeModuleFile
|
||||
@@ -183,7 +185,12 @@ internal open class GradleCompilerRunner(protected val task: Task) {
|
||||
|
||||
for (project in gradle.rootProject.allprojects) {
|
||||
project.tasks.withType(AbstractKotlinCompile::class.java).toList().forEach { task ->
|
||||
val module = IncrementalModuleEntry(project.path, task.moduleName, project.buildDir, task.buildHistoryFile)
|
||||
val module = IncrementalModuleEntry(
|
||||
project.path,
|
||||
task.moduleName,
|
||||
project.buildDir,
|
||||
task.buildHistoryFile
|
||||
)
|
||||
dirToModule[task.destinationDir] = module
|
||||
task.javaOutputDir?.let { dirToModule[it] = module }
|
||||
nameToModules.getOrPut(module.name) { HashSet() }.add(module)
|
||||
@@ -201,7 +208,12 @@ internal open class GradleCompilerRunner(protected val task: Task) {
|
||||
for (target in kotlinExt.targets) {
|
||||
val mainCompilation = target.compilations.findByName(KotlinCompilation.MAIN_COMPILATION_NAME) ?: continue
|
||||
val kotlinTask = mainCompilation.compileKotlinTask as? AbstractKotlinCompile<*> ?: continue
|
||||
val module = IncrementalModuleEntry(project.path, kotlinTask.moduleName, project.buildDir, kotlinTask.buildHistoryFile)
|
||||
val module = IncrementalModuleEntry(
|
||||
project.path,
|
||||
kotlinTask.moduleName,
|
||||
project.buildDir,
|
||||
kotlinTask.buildHistoryFile
|
||||
)
|
||||
val jarTask = project.tasks.findByName(target.artifactsTaskName) as? AbstractArchiveTask ?: continue
|
||||
jarToModule[jarTask.archivePath] = module
|
||||
}
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.gradle.tasks.clearLocalState
|
||||
import org.jetbrains.kotlin.gradle.tasks.throwGradleExceptionIfError
|
||||
import org.jetbrains.kotlin.gradle.utils.stackTraceAsString
|
||||
import org.jetbrains.kotlin.incremental.ChangedFiles
|
||||
import org.jetbrains.kotlin.incremental.IncrementalModuleInfo
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.*
|
||||
import java.net.URLClassLoader
|
||||
@@ -148,7 +149,7 @@ internal class GradleKotlinCompilerWork @Inject constructor(
|
||||
}
|
||||
|
||||
private fun compileWithDaemon(messageCollector: MessageCollector): ExitCode? {
|
||||
val isDebugEnabled = log.isDebugEnabled || System.getProperty("kotlin.daemon.debug.log")?.toBoolean() ?: false
|
||||
val isDebugEnabled = log.isDebugEnabled || System.getProperty("kotlin.daemon.debug.log")?.toBoolean() ?: true
|
||||
val enableAssertions = System.getProperty("kotlin.daemon.ea")?.toBoolean() ?: false
|
||||
val daemonMessageCollector =
|
||||
if (isDebugEnabled) messageCollector else MessageCollector.NONE
|
||||
|
||||
+9
-5
@@ -39,6 +39,7 @@ private val KOTLIN_SCRIPT_ANNOTATION_EXPECTED_CLASS = "kotlin.script.experimenta
|
||||
private val KOTLIN_JVM_SCRIPT_COMPILER_EXPECTED_CLASS = "kotlin.script.experimental.jvm.JvmScriptCompiler"
|
||||
private val KOTLIN_REFLECT_EXPECTED_CLASS = "kotlin.reflect.full.KClasses"
|
||||
private val TROVE4J_EXPECTED_CLASS = "gnu.trove.THashMap"
|
||||
private val DAEMON_EXPECTED_CLASS = "org.jetbrains.kotlin.daemon.CompileServiceImpl"
|
||||
internal const val KOTLIN_MODULE_GROUP = "org.jetbrains.kotlin"
|
||||
private val KOTLIN_GRADLE_PLUGIN = "kotlin-gradle-plugin"
|
||||
internal const val KOTLIN_COMPILER_EMBEDDABLE = "kotlin-compiler-embeddable"
|
||||
@@ -76,20 +77,23 @@ internal fun findKotlinCompilerClasspath(project: Project): List<File> {
|
||||
return findKotlinStdlibClasspath(project) +
|
||||
findKotlinScriptRuntimeClasspath(project) +
|
||||
findKotlinReflectClasspath(project) +
|
||||
listOfNotNull(findTrove4j())
|
||||
listOfNotNull(findTrove4j(), findDaemon())
|
||||
}
|
||||
|
||||
internal fun findTrove4j(): File? {
|
||||
internal fun findJarByClass(classFqName: String): File? {
|
||||
val classLoader = Thread.currentThread().contextClassLoader
|
||||
val classFromTrove4j = try {
|
||||
classLoader.loadClass(TROVE4J_EXPECTED_CLASS)
|
||||
val classFromJar = try {
|
||||
classLoader.loadClass(classFqName)
|
||||
} catch (e: ClassNotFoundException) {
|
||||
null
|
||||
} ?: return null
|
||||
|
||||
return findJarByClass(classFromTrove4j)
|
||||
return findJarByClass(classFromJar)
|
||||
}
|
||||
|
||||
internal fun findTrove4j() = findJarByClass(TROVE4J_EXPECTED_CLASS)
|
||||
internal fun findDaemon() = findJarByClass(DAEMON_EXPECTED_CLASS)
|
||||
|
||||
internal fun findKotlinStdlibClasspath(project: Project): List<File> =
|
||||
findKotlinModuleJar(project, KOTLIN_STDLIB_EXPECTED_CLASS, KOTLIN_STDLIB)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ dependencies {
|
||||
compile(project(":kotlin-scripting-jvm"))
|
||||
compile(commonDep("org.jetbrains.intellij.deps", "trove4j"))
|
||||
compileOnly(project(":compiler:cli"))
|
||||
compileOnly(project(":compiler:daemon-common"))
|
||||
compileOnly(project(":daemon-common"))
|
||||
compileOnly(project(":kotlin-scripting-compiler"))
|
||||
compile(projectRuntimeJar(":kotlin-daemon-client"))
|
||||
compileOnly("com.jcabi:jcabi-aether:1.0-SNAPSHOT")
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, Version 2, hence
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
@@ -227,7 +227,7 @@ the scope of this License.
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, Version 2,
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
|
||||
@@ -20,7 +20,7 @@ dependencies {
|
||||
compile(project(":compiler:light-classes"))
|
||||
compile(project(":compiler:util"))
|
||||
compile(project(":kotlin-build-common"))
|
||||
compile(project(":compiler:daemon-common"))
|
||||
compile(project(":daemon-common"))
|
||||
compile(projectRuntimeJar(":kotlin-daemon-client"))
|
||||
compile(project(":kotlin-compiler-runner")) { isTransitive = false }
|
||||
compile(project(":compiler:plugin-api"))
|
||||
|
||||
@@ -18,7 +18,7 @@ dependencies {
|
||||
testCompile(project(":compiler:cli"))
|
||||
testCompile(project(":compiler:cli-common"))
|
||||
testCompile(project(":compiler:frontend.java"))
|
||||
testCompile(project(":compiler:daemon-common"))
|
||||
testCompile(project(":daemon-common"))
|
||||
testCompile(projectRuntimeJar(":kotlin-daemon-client"))
|
||||
testCompile(projectTests(":compiler:tests-common"))
|
||||
testCompile(commonDep("junit:junit"))
|
||||
|
||||
@@ -15,12 +15,12 @@ val archives by configurations
|
||||
|
||||
dependencies {
|
||||
jarContents(project(":compiler:cli-common")) { isTransitive = false }
|
||||
jarContents(project(":compiler:daemon-common")) { isTransitive = false }
|
||||
jarContents(project(":compiler:daemon-common-new")) { isTransitive = false }
|
||||
jarContents(project(":daemon-common")) { isTransitive = false }
|
||||
jarContents(project(":daemon-common-new")) { isTransitive = false }
|
||||
jarContents(projectRuntimeJar(":kotlin-daemon-client"))
|
||||
testCompile(project(":compiler:cli-common"))
|
||||
testCompile(project(":compiler:daemon-common"))
|
||||
testCompile(project(":compiler:daemon-common-new"))
|
||||
testCompile(project(":daemon-common"))
|
||||
testCompile(project(":daemon-common-new"))
|
||||
testCompile(projectRuntimeJar(":kotlin-daemon-client"))
|
||||
testCompile(commonDep("junit:junit"))
|
||||
testCompile(project(":kotlin-test:kotlin-test-jvm"))
|
||||
|
||||
@@ -9,6 +9,7 @@ dependencies {
|
||||
runtime(kotlinStdlib())
|
||||
runtime(project(":kotlin-script-runtime"))
|
||||
runtime(project(":kotlin-reflect"))
|
||||
runtime(project(":kotlin-daemon-embeddable"))
|
||||
runtime(commonDep("org.jetbrains.intellij.deps", "trove4j"))
|
||||
}
|
||||
|
||||
|
||||
@@ -26,14 +26,13 @@ val libraries by configurations.creating {
|
||||
extendsFrom(compile)
|
||||
}
|
||||
val trove4jJar by configurations.creating
|
||||
val ktorNetworkJar by configurations.creating
|
||||
|
||||
val default by configurations
|
||||
default.extendsFrom(runtimeJar)
|
||||
|
||||
val compilerBaseName = name
|
||||
|
||||
val ktorExcludesForDaemon : List<Pair<String, String>> by rootProject.extra
|
||||
|
||||
val outputJar = fileFrom(buildDir, "libs", "$compilerBaseName.jar")
|
||||
|
||||
val compilerModules: Array<String> by rootProject.extra
|
||||
@@ -58,11 +57,9 @@ dependencies {
|
||||
}
|
||||
|
||||
trove4jJar(intellijDep()) { includeIntellijCoreJarDependencies(project) { it.startsWith("trove4j") } }
|
||||
ktorNetworkJar(commonDep("io.ktor", "ktor-network"))
|
||||
|
||||
fatJarContents(kotlinBuiltins())
|
||||
fatJarContents(project(":kotlin-daemon-client-new")) {
|
||||
isTransitive = false
|
||||
}
|
||||
fatJarContents(commonDep("javax.inject"))
|
||||
fatJarContents(commonDep("org.jline", "jline"))
|
||||
fatJarContents(commonDep("org.fusesource.jansi", "jansi"))
|
||||
@@ -70,11 +67,6 @@ dependencies {
|
||||
fatJarContents(commonDep("com.google.code.findbugs", "jsr305"))
|
||||
fatJarContents(commonDep("io.javaslang", "javaslang"))
|
||||
fatJarContents(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false }
|
||||
fatJarContents(commonDep("io.ktor", "ktor-network")) {
|
||||
ktorExcludesForDaemon.forEach { (group, module) ->
|
||||
exclude(group = group, module = module)
|
||||
}
|
||||
}
|
||||
|
||||
fatJarContents(intellijCoreDep()) { includeJars("intellij-core", "java-compatibility-1.0.1") }
|
||||
fatJarContents(intellijDep()) {
|
||||
@@ -142,6 +134,7 @@ val pack = if (shrink) proguard else packCompiler
|
||||
|
||||
dist(targetName = "$compilerBaseName.jar", fromTask = pack) {
|
||||
from(trove4jJar)
|
||||
from(ktorNetworkJar)
|
||||
}
|
||||
|
||||
runtimeJarArtifactBy(pack, pack.outputs.files.singleFile) {
|
||||
|
||||
@@ -26,6 +26,7 @@ val libraries by configurations.creating {
|
||||
extendsFrom(compile)
|
||||
}
|
||||
val trove4jJar by configurations.creating
|
||||
val ktorNetworkJar by configurations.creating
|
||||
|
||||
val default by configurations
|
||||
default.extendsFrom(runtimeJar)
|
||||
@@ -36,8 +37,6 @@ val outputJar = fileFrom(buildDir, "libs", "$compilerBaseName.jar")
|
||||
|
||||
val compilerModules: Array<String> by rootProject.extra
|
||||
|
||||
val ktorExcludesForDaemon : List<Pair<String, String>> by rootProject.extra
|
||||
|
||||
dependencies {
|
||||
compile(kotlinStdlib())
|
||||
compile(project(":kotlin-script-runtime"))
|
||||
@@ -58,11 +57,9 @@ dependencies {
|
||||
}
|
||||
|
||||
trove4jJar(intellijDep()) { includeIntellijCoreJarDependencies(project) { it.startsWith("trove4j") } }
|
||||
ktorNetworkJar(commonDep("io.ktor", "ktor-network"))
|
||||
|
||||
fatJarContents(kotlinBuiltins())
|
||||
fatJarContents(project(":kotlin-daemon-client-new")) {
|
||||
isTransitive = false
|
||||
}
|
||||
fatJarContents(commonDep("javax.inject"))
|
||||
fatJarContents(commonDep("org.jline", "jline"))
|
||||
fatJarContents(commonDep("org.fusesource.jansi", "jansi"))
|
||||
@@ -70,11 +67,6 @@ dependencies {
|
||||
fatJarContents(commonDep("com.google.code.findbugs", "jsr305"))
|
||||
fatJarContents(commonDep("io.javaslang", "javaslang"))
|
||||
fatJarContents(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false }
|
||||
fatJarContents(commonDep("io.ktor", "ktor-network")) {
|
||||
ktorExcludesForDaemon.forEach { (group, module) ->
|
||||
exclude(group = group, module = module)
|
||||
}
|
||||
}
|
||||
|
||||
fatJarContents(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
fatJarContents(intellijDep()) {
|
||||
@@ -142,6 +134,7 @@ val pack = if (shrink) proguard else packCompiler
|
||||
|
||||
dist(targetName = "$compilerBaseName.jar", fromTask = pack) {
|
||||
from(trove4jJar)
|
||||
from(ktorNetworkJar)
|
||||
}
|
||||
|
||||
runtimeJarArtifactBy(pack, pack.outputs.files.singleFile) {
|
||||
|
||||
@@ -26,6 +26,7 @@ val libraries by configurations.creating {
|
||||
extendsFrom(compile)
|
||||
}
|
||||
val trove4jJar by configurations.creating
|
||||
val ktorNetworkJar by configurations.creating
|
||||
|
||||
val default by configurations
|
||||
default.extendsFrom(runtimeJar)
|
||||
@@ -36,8 +37,6 @@ val outputJar = fileFrom(buildDir, "libs", "$compilerBaseName.jar")
|
||||
|
||||
val compilerModules: Array<String> by rootProject.extra
|
||||
|
||||
val ktorExcludesForDaemon : List<Pair<String, String>> by rootProject.extra
|
||||
|
||||
dependencies {
|
||||
compile(kotlinStdlib())
|
||||
compile(project(":kotlin-script-runtime"))
|
||||
@@ -58,11 +57,9 @@ dependencies {
|
||||
}
|
||||
|
||||
trove4jJar(intellijDep()) { includeIntellijCoreJarDependencies(project) { it.startsWith("trove4j") } }
|
||||
ktorNetworkJar(commonDep("io.ktor", "ktor-network"))
|
||||
|
||||
fatJarContents(kotlinBuiltins())
|
||||
fatJarContents(project(":kotlin-daemon-client-new")) {
|
||||
isTransitive = false
|
||||
}
|
||||
fatJarContents(commonDep("javax.inject"))
|
||||
fatJarContents(commonDep("org.jline", "jline"))
|
||||
fatJarContents(commonDep("org.fusesource.jansi", "jansi"))
|
||||
@@ -70,11 +67,6 @@ dependencies {
|
||||
fatJarContents(commonDep("com.google.code.findbugs", "jsr305"))
|
||||
fatJarContents(commonDep("io.javaslang", "javaslang"))
|
||||
fatJarContents(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false }
|
||||
fatJarContents(commonDep("io.ktor", "ktor-network")) {
|
||||
ktorExcludesForDaemon.forEach { (group, module) ->
|
||||
exclude(group = group, module = module)
|
||||
}
|
||||
}
|
||||
|
||||
fatJarContents(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
fatJarContents(intellijDep()) {
|
||||
@@ -142,6 +134,7 @@ val pack = if (shrink) proguard else packCompiler
|
||||
|
||||
dist(targetName = "$compilerBaseName.jar", fromTask = pack) {
|
||||
from(trove4jJar)
|
||||
from(ktorNetworkJar)
|
||||
}
|
||||
|
||||
runtimeJarArtifactBy(pack, pack.outputs.files.singleFile) {
|
||||
|
||||
@@ -21,8 +21,8 @@ val projectsToShadow by extra(listOf(
|
||||
":kotlin-build-common",
|
||||
":compiler:cli-common",
|
||||
":compiler:container",
|
||||
":compiler:daemon-common",
|
||||
":compiler:daemon-common-new",
|
||||
":daemon-common",
|
||||
":daemon-common-new",
|
||||
":core:metadata",
|
||||
":core:metadata.jvm",
|
||||
":core:descriptors",
|
||||
@@ -120,6 +120,10 @@ dependencies {
|
||||
libraries(project(":kotlin-reflect"))
|
||||
libraries(project(":kotlin-compiler-client-embeddable"))
|
||||
libraries(project(":kotlin-daemon-client"))
|
||||
libraries(project(":kotlin-daemon-client-new"))
|
||||
libraries(project(":kotlin-daemon")) {
|
||||
isTransitive = false
|
||||
}
|
||||
libraries(project(":kotlin-script-runtime"))
|
||||
libraries(project(":kotlin-script-util"))
|
||||
libraries(project(":kotlin-scripting-common"))
|
||||
|
||||
@@ -10,8 +10,8 @@ val projectsToShadow = listOf(
|
||||
":kotlin-build-common",
|
||||
":compiler:cli-common",
|
||||
":kotlin-compiler-runner",
|
||||
":compiler:daemon-common",
|
||||
":compiler:daemon-common-new",
|
||||
":daemon-common",
|
||||
":daemon-common-new",
|
||||
":core:descriptors",
|
||||
":core:descriptors.jvm",
|
||||
":idea:idea-jps-common",
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
|
||||
description = "Kotlin Daemon (for using with embeddable compiler)"
|
||||
|
||||
plugins {
|
||||
`java`
|
||||
}
|
||||
|
||||
val packedJars by configurations.creating
|
||||
|
||||
dependencies {
|
||||
packedJars(project(":kotlin-daemon")) { isTransitive = false }
|
||||
}
|
||||
|
||||
publish()
|
||||
|
||||
noDefaultJar()
|
||||
|
||||
runtimeJar(rewriteDepsToShadedCompiler(
|
||||
task<ShadowJar>("shadowJar") {
|
||||
from(packedJars)
|
||||
}
|
||||
))
|
||||
|
||||
sourcesJar()
|
||||
javadocJar()
|
||||
+8
-5
@@ -19,9 +19,9 @@ pluginManagement {
|
||||
include ":kotlin-build-common",
|
||||
":compiler",
|
||||
":compiler:util",
|
||||
":compiler:daemon-common",
|
||||
":compiler:daemon-common-new",
|
||||
":compiler:daemon",
|
||||
":daemon-common",
|
||||
":daemon-common-new",
|
||||
":kotlin-daemon",
|
||||
":kotlin-daemon-client",
|
||||
":kotlin-daemon-client-new",
|
||||
":kotlin-preloader",
|
||||
@@ -168,6 +168,7 @@ include ":kotlin-build-common",
|
||||
":kotlin-annotation-processing-runtime",
|
||||
":kotlin-annotation-processing-gradle",
|
||||
":kotlin-annotation-processing-embeddable",
|
||||
":kotlin-daemon-embeddable",
|
||||
":examples:kotlin-jsr223-local-example",
|
||||
":examples:kotlin-jsr223-daemon-local-eval-example",
|
||||
":kotlin-annotations-jvm",
|
||||
@@ -294,8 +295,9 @@ project(':kotlin-build-common').projectDir = "$rootDir/build-common" as File
|
||||
project(':compiler:cli-common').projectDir = "$rootDir/compiler/cli/cli-common" as File
|
||||
project(':compiler:cli-js').projectDir = "$rootDir/compiler/cli/cli-js" as File
|
||||
project(':kotlin-runner').projectDir = "$rootDir/compiler/cli/cli-runner" as File
|
||||
project(':compiler:daemon-common').projectDir = "$rootDir/compiler/daemon/daemon-common" as File
|
||||
project(':compiler:daemon-common-new').projectDir = "$rootDir/compiler/daemon/daemon-common-new" as File
|
||||
project(':kotlin-daemon').projectDir = "$rootDir/compiler/daemon" as File
|
||||
project(':daemon-common').projectDir = "$rootDir/compiler/daemon/daemon-common" as File
|
||||
project(':daemon-common-new').projectDir = "$rootDir/compiler/daemon/daemon-common-new" as File
|
||||
project(':kotlin-daemon-client').projectDir = "$rootDir/compiler/daemon/daemon-client" as File
|
||||
project(':kotlin-daemon-client-new').projectDir = "$rootDir/compiler/daemon/daemon-client-new" as File
|
||||
project(':kotlin-compiler-runner').projectDir = "$rootDir/compiler/compiler-runner" as File
|
||||
@@ -338,6 +340,7 @@ project(':examples:annotation-processor-example').projectDir = "$rootDir/librari
|
||||
project(':kotlin-script-util').projectDir = "$rootDir/libraries/tools/kotlin-script-util" as File
|
||||
project(':kotlin-annotation-processing-gradle').projectDir = "$rootDir/libraries/tools/kotlin-annotation-processing" as File
|
||||
project(':kotlin-annotation-processing-embeddable').projectDir = "$rootDir/prepare/kotlin-annotation-processing-embeddable" as File
|
||||
project(':kotlin-daemon-embeddable').projectDir = "$rootDir/prepare/kotlin-daemon-embeddable" as File
|
||||
project(':kotlin-annotation-processing').projectDir = "$rootDir/plugins/kapt3/kapt3-compiler" as File
|
||||
project(':kotlin-annotation-processing-cli').projectDir = "$rootDir/plugins/kapt3/kapt3-cli" as File
|
||||
project(':kotlin-annotation-processing-base').projectDir = "$rootDir/plugins/kapt3/kapt3-base" as File
|
||||
|
||||
Reference in New Issue
Block a user