You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

143 lines
5.7 KiB

/*
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file.
*/
package org.jetbrains.compose.desktop.application.tasks
import org.gradle.api.file.Directory
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.jetbrains.compose.desktop.application.internal.JavaRuntimeProperties
import org.jetbrains.compose.desktop.application.internal.executableName
import org.jetbrains.compose.desktop.application.internal.ioFile
import org.jetbrains.compose.desktop.application.internal.notNullProperty
import java.io.File
// __COMPOSE_NATIVE_DISTRIBUTIONS_MIN_JAVA_VERSION__
internal const val MIN_JAVA_RUNTIME_VERSION = 15
@CacheableTask
abstract class AbstractCheckNativeDistributionRuntime : AbstractComposeDesktopTask() {
@get:Input
val javaHome: Property<String> = objects.notNullProperty()
@get:OutputFile
val javaRuntimePropertiesFile: RegularFileProperty = objects.fileProperty()
@get:LocalState
val workingDir: Provider<Directory> = project.layout.buildDirectory.dir("compose/tmp/$name")
private val javaExec: File
get() = getTool("java")
private val javacExec: File
get() = getTool("javac")
private fun getTool(toolName: String): File {
val javaHomeBin = File(javaHome.get()).resolve("bin")
val tool = javaHomeBin.resolve(executableName(toolName))
check(tool.exists()) { "Could not find $tool at: ${tool.absolutePath}}" }
return tool
}
@TaskAction
fun run() {
val javaRuntimeVersion = try {
getJavaRuntimeVersionUnsafe()
} catch (e: Exception) {
throw IllegalStateException(
"Could not infer Java runtime version for Java home directory: ${javaHome.get()}", e
)
}
check((javaRuntimeVersion?.toIntOrNull() ?: -1) >= MIN_JAVA_RUNTIME_VERSION) {
"""|Packaging native distributions requires JDK runtime version >= $MIN_JAVA_RUNTIME_VERSION
|Actual version: '${javaRuntimeVersion ?: "<unknown>"}'
|Java home: ${javaHome.get()}
""".trimMargin()
}
val modules = arrayListOf<String>()
runExternalTool(
tool = javaExec,
args = listOf("--list-modules"),
forceLogToFile = true,
processStdout = { stdout ->
stdout.lineSequence().forEach { line ->
val moduleName = line.trim().substringBefore("@")
if (moduleName.isNotBlank()) {
modules.add(moduleName)
}
}
}
)
val properties = JavaRuntimeProperties(modules)
JavaRuntimeProperties.writeToFile(properties, javaRuntimePropertiesFile.ioFile)
}
private fun getJavaRuntimeVersionUnsafe(): String? {
val workingDir = workingDir.ioFile
fileOperations.delete(workingDir)
fileOperations.mkdir(workingDir)
val printJavaRuntimeClassName = "PrintJavaRuntimeVersion"
val javaVersionPrefix = "Java runtime version = '"
val javaVersionSuffix = "'"
val printJavaRuntimeJava = workingDir.resolve("java/$printJavaRuntimeClassName.java").apply {
parentFile.mkdirs()
writeText("""
import java.lang.reflect.Method;
public class $printJavaRuntimeClassName {
public static void main(String[] args) {
Class<Runtime> runtimeClass = Runtime.class;
try {
Method version = runtimeClass.getMethod("version");
Object runtimeVer = version.invoke(runtimeClass);
Class<? extends Object> runtimeVerClass = runtimeVer.getClass();
try {
int feature = (int) runtimeVerClass.getMethod("feature").invoke(runtimeVer);
printVersionAndHalt((Integer.valueOf(feature)).toString());
} catch (NoSuchMethodException e) {
int major = (int) runtimeVerClass.getMethod("major").invoke(runtimeVer);
printVersionAndHalt((Integer.valueOf(major)).toString());
}
} catch (Exception e) {
printVersionAndHalt(System.getProperty("java.version"));
}
}
private static void printVersionAndHalt(String version) {
System.out.println("$javaVersionPrefix" + version + "$javaVersionSuffix");
Runtime.getRuntime().exit(0);
}
}
""".trimIndent())
}
val classFilesDir = workingDir.resolve("out-classes")
runExternalTool(
tool = javacExec,
args = listOf(
"-source", "1.8",
"-target", "1.8",
"-d", classFilesDir.absolutePath,
printJavaRuntimeJava.absolutePath
)
)
var javaRuntimeVersion: String? = null
runExternalTool(
tool = javaExec,
args = listOf("-cp", classFilesDir.absolutePath, printJavaRuntimeClassName),
processStdout = { stdout ->
val m = "$javaVersionPrefix(.+)$javaVersionSuffix".toRegex().find(stdout)
javaRuntimeVersion = m?.groupValues?.get(1)
}
)
return javaRuntimeVersion
}
}