Skip to content

Commit

Permalink
Merge pull request #2924 from bisq-network/revert-2773-feature/jre_fr…
Browse files Browse the repository at this point in the history
…om_jdk

Revert "Use JRE instead of JDK Desktop Binary"
  • Loading branch information
alejandrogarcia83 authored Oct 11, 2024
2 parents ebfb1d2 + 0f7be90 commit 62ea338
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 127 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ hs_err_pid*
*.wallet
*.ser
*.sh
.vscode
.DS_Store
.gradle
build
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/desktop-app-launcher/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import java.util.Properties
import java.io.File

// Function to read properties from a file - TODO find a way to reuse this code instead of copying when needed
fun readPropertiesFile(filePath: String): Properties {
Expand All @@ -11,7 +12,6 @@ plugins {
id("bisq.java-library")
id("bisq.gradle.desktop.regtest.BisqDesktopRegtestPlugin")
application
id("org.kordamp.gradle.jdeps") version "0.20.0"
id("bisq.gradle.packaging.PackagingPlugin")
alias(libs.plugins.openjfx)
}
Expand Down
137 changes: 37 additions & 100 deletions build-logic/packaging/src/main/kotlin/bisq/gradle/packaging/JLinkTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@ package bisq.gradle.packaging
import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.*
import java.io.BufferedReader
import java.io.InputStreamReader


//import java.util.regex.Pattern
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import java.util.concurrent.TimeUnit

abstract class JLinkTask : DefaultTask() {

// companion object {
// val pattern: Pattern = Pattern.compile(".*\\b(java\\..*|javax\\..*)\\b.*\$")
// }

@get:InputDirectory
abstract val jdkDirectory: DirectoryProperty

Expand All @@ -31,105 +27,46 @@ abstract class JLinkTask : DefaultTask() {

@TaskAction
fun run() {
// Ensure the output directory is clean
// jlink expects non-existent output directory
val outputDirectoryFile = outputDirectory.asFile.get()
if (outputDirectoryFile.exists() && outputDirectoryFile.listFiles()?.isNotEmpty() == true) {
// In case you want to run it manually, this will stop the plugin from running the task
logger.lifecycle("custom jre already created, skipping - see: ${jdkDirectory.get()}")
} else {
if (!outputDirectoryFile.canWrite()) {
throw IllegalStateException("Output directory is not writable: ${outputDirectoryFile.absolutePath}")
}
outputDirectoryFile.deleteRecursively()

logger.lifecycle("JDK path: ${jdkDirectory.get()}")

// Construct the jlink command
val jLinkPath = jdkDirectory.asFile.get().toPath().resolve("bin").resolve("jlink")
val processBuilder = ProcessBuilder(
outputDirectoryFile.deleteRecursively()

val jLinkPath = jdkDirectory.asFile.get().toPath().resolve("bin").resolve("jlink")
val processBuilder = ProcessBuilder(
jLinkPath.toAbsolutePath().toString(),
"--verbose",

"--add-modules", parseUsedJavaModulesFromJDepsOutput(),
"--include-locales=en,cs,de,es,it,pcm,pt-BR",

"--strip-native-commands",
"--no-header-files",
"--no-man-pages",
"--compress=2",
// "--strip-debug", // makes jlink fail in some platforms like Ubuntu linux
// "--add-reads", "java.base=ALL-UNNAMED",
"--strip-debug",

"--output", outputDirectoryFile.absolutePath
)
logger.lifecycle("Executing jlink command: ${processBuilder.command().joinToString(" ")}")

// Add module path if specified
if (javaModulesDirectory.isPresent) {
val commands = processBuilder.command()
commands.add("--module-path")
commands.add(javaModulesDirectory.asFile.get().absolutePath)
logger.lifecycle("Executing jlink command: ${commands.joinToString(" ")}")
}

logger.lifecycle("Preparing process builder..")
processBuilder.inheritIO()

logger.lifecycle("Starting process builder..")
val process = processBuilder.start()
if (System.getProperty("os.name").lowercase().contains("windows")) {
val reader =
BufferedReader(InputStreamReader(process.inputStream))
while ((reader.readLine()) != null) {
// WORKAROUND: Jlink hangs in windows (11pro) when running from this custom plugin
// This buffer reader is needed jus to get it going and won't affect the rest of the platforms
}
}
logger.lifecycle("Reading errors..")
val errorOutput = process.errorStream.bufferedReader().readText()
val exitCode = process.waitFor()

if (exitCode != 0) {
logger.error("jlink error output:\n$errorOutput")
throw IllegalStateException("jlink couldn't create custom runtime. Exit code: $exitCode")
}
)

if (javaModulesDirectory.isPresent) {
val commands = processBuilder.command()
commands.add("--module-path")
commands.add(javaModulesDirectory.asFile.get().absolutePath)
}

processBuilder.inheritIO()

val process = processBuilder.start()
process.waitFor(2, TimeUnit.MINUTES)

val isSuccess = process.exitValue() == 0
if (!isSuccess) {
throw IllegalStateException("jlink couldn't create custom runtime.")
}
}

private fun parseUsedJavaModulesFromJDepsOutput(): String {
// TODO instead of hardcoding he modules process the jdeps report and generate the below so we don't need
// to touch this code again in case of needed new jmods in the future
// readLines.filter { pattern.matcher(it).matches() }
// .flatMap { line -> line.split("->").map { it.trim() } }
// .filter { it.startsWith("java.") || it == "bisq.desktop_app_launcher" }
// .flatMap { line -> line.split(",").map { it.trim() } }
// .distinct()
// .joinToString(",")
// val readLines = jDepsOutputFile.asFile.get().readLines()
val modules = listOf(
// base
"java.base",
"java.datatransfer",
"java.desktop",
"java.logging",
"java.xml",
"java.naming",
"java.net.http",
// security
"java.se",
"java.security.jgss",
// javafx
"javafx.base",
"javafx.controls",
"javafx.fxml",
"javafx.graphics",
"javafx.media",
"javafx.swing",
// "javafx.web",
// jdk
"jdk.unsupported",
"jdk.localedata",
"jdk.crypto.cryptoki",
"jdk.crypto.ec"
).joinToString(",")
logger.lifecycle("Modules to be included: $modules")
return modules
var readLines = jDepsOutputFile.asFile.get().readLines()
if (!javaModulesDirectory.isPresent) {
readLines = readLines.filter { it.startsWith("java.") }
}
return readLines.joinToString(",")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import org.gradle.api.file.Directory
import org.gradle.api.file.RegularFile
import org.gradle.api.plugins.JavaApplication
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.*
import org.gradle.api.tasks.Sync
import org.gradle.api.tasks.TaskProvider
import org.gradle.jvm.tasks.Jar
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.jvm.toolchain.JavaToolchainService
Expand Down Expand Up @@ -42,30 +43,10 @@ class PackagingPlugin @Inject constructor(private val javaToolchainService: Java
val javaApplicationExtension = project.extensions.findByType<JavaApplication>()
checkNotNull(javaApplicationExtension) { "Can't find JavaApplication extension." }

val createCustomJre = project.tasks.register<JLinkTask>("createCustomJre") {
dependsOn(project.tasks.named("jdepsReport"))

jdkDirectory.set(getJPackageJdkDirectory(extension))
jDepsOutputFile.set(getBuildFileOf(project, "reports/jdeps/jdeps-main.txt"))
outputDirectory.set(project.layout.buildDirectory.dir("custom-jre"))

doLast {
println("JLink configuration:")
println("JDK Directory: ${jdkDirectory.get()}")
println("JDeps Output File: ${jDepsOutputFile.get()}")
println("Output Directory: ${outputDirectory.get()}")
}
}

project.tasks.register<JPackageTask>("generateInstallers") {
group = "distribution"
description = "Generate the installer or the platform the project is running"

dependsOn(createCustomJre)

// Set the runtime image to the output of JLinkTask
runtimeImageDirectory.set(createCustomJre.flatMap { it.outputDirectory })

val webcamProject = project.parent?.childProjects?.filter { e -> e.key == "webcam-app" }?.map { e -> e.value.project }?.first()
webcamProject?.let { webcam ->
val desktopProject = project.parent?.childProjects?.filter { e -> e.key == "desktop" }?.map { e -> e.value.project }?.first()
Expand Down Expand Up @@ -100,6 +81,10 @@ class PackagingPlugin @Inject constructor(private val javaToolchainService: Java
val packageResourcesDirFile = File(project.projectDir, "package")
packageResourcesDir.set(packageResourcesDirFile)

runtimeImageDirectory.set(
getJPackageJdkDirectory(extension)
)

outputDirectory.set(project.layout.buildDirectory.dir("packaging/jpackage/packages"))
}

Expand Down Expand Up @@ -142,8 +127,4 @@ class PackagingPlugin @Inject constructor(private val javaToolchainService: Java
}
return javaVersion.map { JavaLanguageVersion.of(it) }
}

private fun getBuildFileOf(project: Project, relativePath: String): RegularFile {
return project.layout.buildDirectory.file(relativePath).get()
}
}

0 comments on commit 62ea338

Please sign in to comment.