diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml index f35538c0961..e070c554866 100644 --- a/.github/workflows/pr-build.yml +++ b/.github/workflows/pr-build.yml @@ -10,7 +10,7 @@ on: workflow_dispatch: inputs: job: - description: 'Job to run: all / macos / ubuntu / rockylinux / debian11' + description: 'Job to run: all / macos / ubuntu / ubuntu-jdk21 / rockylinux / debian11' required: false default: 'all' @@ -29,7 +29,7 @@ jobs: fail-fast: false matrix: include: - - java: '17' + - java: '21' runner: macos-26 arch: aarch64 @@ -102,8 +102,61 @@ jobs: java -jar "$JAR" db archive -h java -jar "$JAR" keystore --help + build-ubuntu-jdk21: + name: Build ubuntu24 (JDK 21 / ${{ matrix.arch }}) + if: ${{ github.event_name == 'pull_request' || inputs.job == 'all' || inputs.job == 'ubuntu-jdk21' }} + runs-on: ${{ matrix.runner }} + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + include: + - runner: ubuntu-latest + arch: x86_64 + - runner: ubuntu-24.04-arm + arch: aarch64 + + steps: + - uses: actions/checkout@v5 + + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'temurin' + + - name: Check Java version + run: java -version + + - name: Cache Gradle packages + uses: actions/cache@v5 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ubuntu24-jdk21-${{ matrix.arch }}-gradle-${{ hashFiles('**/*.gradle', '**/gradle-wrapper.properties') }} + restore-keys: ubuntu24-jdk21-${{ matrix.arch }}-gradle- + + - name: Build + run: ./gradlew clean build --no-daemon + + - name: Toolkit jar smoke test + run: | + set -e + JAR=plugins/build/libs/Toolkit.jar + java -jar "$JAR" help + java -jar "$JAR" db --help + java -jar "$JAR" db archive -h + java -jar "$JAR" keystore --help + + # ARM64 already runs the suite on RocksDB; x86_64 defaults to LevelDB, so + # cover the x86 RocksDB pin (5.15.10) on JDK 21 explicitly. + - name: Test with RocksDB engine + if: ${{ matrix.arch == 'x86_64' }} + run: ./gradlew :framework:testWithRocksDb --no-daemon + docker-build-rockylinux: - name: Build rockylinux (JDK 8 / x86_64) + name: Build rockylinux (JDK 17 / x86_64) if: ${{ github.event_name == 'pull_request' || inputs.job == 'all' || inputs.job == 'rockylinux' }} runs-on: ubuntu-latest timeout-minutes: 60 @@ -117,17 +170,40 @@ jobs: LC_ALL: en_US.UTF-8 steps: - - name: Install dependencies (Rocky 8 + JDK8) + - name: Install dependencies (Rocky 8 + JDK17) run: | set -euxo pipefail - dnf -y install java-1.8.0-openjdk-devel git wget unzip which jq bc curl glibc-langpack-en + dnf -y install java-17-openjdk-devel git wget unzip which jq bc curl glibc-langpack-en dnf -y groupinstall "Development Tools" + # "Development Tools" drags in java-1.8.0-openjdk-headless, and RHEL's + # alternatives priorities prefer the 1.8 family, so `java` would point + # at a JRE without javac. Pin JDK 17 explicitly. + - name: Force JDK 17 as default java + run: | + set -euxo pipefail + JAVA17_HOME="$(readlink -f /etc/alternatives/java_sdk_17)" + echo "JAVA_HOME=${JAVA17_HOME}" >> "$GITHUB_ENV" + echo "${JAVA17_HOME}/bin" >> "$GITHUB_PATH" + - name: Checkout code uses: actions/checkout@v5 - - name: Check Java version - run: java -version + - name: Verify JDK 17 + run: | + set -euxo pipefail + printf 'JAVA_HOME=%s\n' "${JAVA_HOME}" + command -v java + command -v javac + test -x "${JAVA_HOME}/bin/java" + test -x "${JAVA_HOME}/bin/javac" + + java_version="$(java -version 2>&1)" + javac_version="$(javac -version 2>&1)" + printf '%s\n' "${java_version}" + printf '%s\n' "${javac_version}" + printf '%s\n' "${java_version}" | grep -Eq 'version "17([.]|")' + printf '%s\n' "${javac_version}" | grep -Eq '^javac 17([.]|$)' - name: Cache Gradle uses: actions/cache@v5 diff --git a/.gitignore b/.gitignore index 3917bb44679..13f90b43675 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,6 @@ ringstate.* shareddata.* # protobuf generated classes -src/main/gen src/main/java/org/tron/core/bftconsensus src/test/java/org/tron/consensus2 src/main/java/META-INF/ diff --git a/README.md b/README.md index be84b44150b..1321c19f474 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ TRON is building the foundational infrastructure for the decentralized internet Before building java-tron, make sure you have: - Hardware with at least 4 CPU cores, 16 GB RAM, 10 GB free disk space for a smooth compilation process. - Operating system: `Linux` or `macOS` (`Windows` is not supported). -- Git and correct JDK (version `8` or `17`) installed based on your CPU architecture. +- Git and a supported JDK: version `8` or newer on x86_64, or version `17` or newer on ARM64. The build output remains compatible with Java 8. There are two ways to install the required dependencies: @@ -49,7 +49,7 @@ There are two ways to install the required dependencies: chmod +x install_dependencies.sh ./install_dependencies.sh ``` - > **Note**: For production-grade stability with JDK 8 on x86_64 architecture, Oracle JDK 8 is strongly recommended (the script installs OpenJDK 8). + > **Note**: Existing compatible JDK installations are preserved. If Java is missing or too old, the script installs OpenJDK 8 on x86_64 or OpenJDK 17 on ARM64. - **Option 2: Manual installation** diff --git a/actuator/build.gradle b/actuator/build.gradle index 1143dc83618..38f94b4ecb1 100644 --- a/actuator/build.gradle +++ b/actuator/build.gradle @@ -33,8 +33,8 @@ test { jacocoTestReport { reports { - xml.enabled = true - html.enabled = true + xml.required = true + html.required = true } getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec")) afterEvaluate { diff --git a/build.gradle b/build.gradle index 65e72c0fb73..31f314a7fc0 100644 --- a/build.gradle +++ b/build.gradle @@ -47,11 +47,15 @@ ext.archInfo = [ // https://github.com/grpc/grpc-java/pull/11371 , 1.64.x is not supported CentOS 7. ProtocGenVersion: isArm64 || isMac ? rootProject.grpcVersion : '1.60.0' ], - VMOptions: isArm64 ? "${rootDir}/gradle/jdk17/java-tron.vmoptions" : "${rootDir}/gradle/java-tron.vmoptions" + VMOptions: javaVersion.isCompatibleWith(JavaVersion.VERSION_17) + ? "${rootDir}/gradle/jdk17/java-tron.vmoptions" + : "${rootDir}/gradle/java-tron.vmoptions" ] -if (!archInfo.java.is(archInfo.requires.JavaVersion)) { - throw new GradleException("Java ${archInfo.requires.JavaVersion} is required for ${archInfo.name}. Detected version ${archInfo.java}") +if (!archInfo.java.isCompatibleWith(archInfo.requires.JavaVersion)) { + throw new GradleException( + "Java ${archInfo.requires.JavaVersion} or newer is required for ${archInfo.name}. " + + "Detected version ${archInfo.java}") } println "Building for architecture: ${archInfo.name}, Java version: ${archInfo.java}" @@ -61,24 +65,35 @@ subprojects { apply plugin: "jacoco" apply plugin: "maven-publish" - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.current() + java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } - [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' + tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' + if (project.name != 'errorprone' && javaVersion.isJava9Compatible()) { + options.release.set(8) + } + } jacoco { - toolVersion = "0.8.12" // see https://www.jacoco.org/jacoco/trunk/doc/changes.html + toolVersion = "0.8.15" // see https://www.jacoco.org/jacoco/trunk/doc/changes.html } + // jacocoTestReport reads this project's class and resource output; declare + // the edge explicitly so Gradle 8 task validation holds even when 'test' + // is excluded from the graph (e.g. ./gradlew build -x test). + jacocoTestReport.dependsOn(classes) buildscript { repositories { mavenCentral() - maven { url 'https://jitpack.io' } + maven { url = 'https://jitpack.io' } maven { - url "https://plugins.gradle.org/m2/" + url = "https://plugins.gradle.org/m2/" } } dependencies { - classpath 'com.google.protobuf:protobuf-gradle-plugin:0.9.1' + classpath 'com.google.protobuf:protobuf-gradle-plugin:0.9.6' classpath "gradle.plugin.com.github.johnrengelman:shadow:7.1.2" } } @@ -86,8 +101,8 @@ subprojects { repositories { mavenLocal() mavenCentral() - maven { url 'https://repo.spring.io/plugins-release' } - maven { url 'https://jitpack.io' } + maven { url = 'https://repo.spring.io/plugins-release' } + maven { url = 'https://jitpack.io' } } dependencies { @@ -103,10 +118,10 @@ subprojects { implementation group: 'joda-time', name: 'joda-time', version: '2.3' implementation group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: '1.84' - compileOnly 'org.projectlombok:lombok:1.18.34' - annotationProcessor 'org.projectlombok:lombok:1.18.34' - testCompileOnly 'org.projectlombok:lombok:1.18.34' - testAnnotationProcessor 'org.projectlombok:lombok:1.18.34' + compileOnly 'org.projectlombok:lombok:1.18.46' + annotationProcessor 'org.projectlombok:lombok:1.18.46' + testCompileOnly 'org.projectlombok:lombok:1.18.46' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.46' // https://www.oracle.com/java/technologies/javase/11-relnote-issues.html#JDK-8190378 implementation group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2' @@ -115,11 +130,20 @@ subprojects { annotationProcessor group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2' testImplementation group: 'junit', name: 'junit', version: '4.13.2' - testImplementation "org.mockito:mockito-core:4.11.0" - testImplementation "org.mockito:mockito-inline:4.11.0" + // mockito 4.11 pulls byte-buddy 1.12.19, which cannot instrument + // class-file version 65; exclude it and declare a JDK 21-capable + // version directly. + testImplementation("org.mockito:mockito-core:4.11.0") { + exclude group: 'net.bytebuddy' + } + testImplementation("org.mockito:mockito-inline:4.11.0") { + exclude group: 'net.bytebuddy' + } + testImplementation "net.bytebuddy:byte-buddy:1.17.7" + testImplementation "net.bytebuddy:byte-buddy-agent:1.17.7" } if (project.name != 'protocol' && project.name != 'errorprone' - && javaVersion.isJava11Compatible()) { + && javaVersion.isCompatibleWith(JavaVersion.VERSION_17)) { apply plugin: 'net.ltgt.errorprone' dependencies { errorprone "com.google.errorprone:error_prone_core:${errorproneVersion}" @@ -140,7 +164,7 @@ subprojects { } task sourcesJar(type: Jar, dependsOn: classes) { - classifier = "sources" + archiveClassifier = "sources" from sourceSets.main.allSource duplicatesStrategy = DuplicatesStrategy.INCLUDE // allow duplicates } diff --git a/chainbase/build.gradle b/chainbase/build.gradle index 1a07ff95fa5..1cb4924f74f 100644 --- a/chainbase/build.gradle +++ b/chainbase/build.gradle @@ -42,8 +42,8 @@ test { jacocoTestReport { dependsOn(processResources) // explicit_dependency reports { - xml.enabled = true - html.enabled = true + xml.required = true + html.required = true } getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec")) afterEvaluate { diff --git a/common/build.gradle b/common/build.gradle index 14d3eb4e637..893552a83eb 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -2,9 +2,11 @@ plugins { id 'java' } -version '1.0.0' +version = '1.0.0' -sourceCompatibility = 1.8 +java { + sourceCompatibility = JavaVersion.VERSION_1_8 +} dependencies { @@ -18,9 +20,9 @@ dependencies { api group: 'io.prometheus', name: 'simpleclient_hotspot', version: '0.15.0' // https://openjdk.org/jeps/396, JEP 396: Strongly Encapsulate JDK Internals by Default // https://eclipse.dev/aspectj/doc/latest/release/JavaVersionCompatibility.html - api 'org.aspectj:aspectjrt:1.9.8' - api 'org.aspectj:aspectjweaver:1.9.8' - api 'org.aspectj:aspectjtools:1.9.8' + api 'org.aspectj:aspectjrt:1.9.25' + api 'org.aspectj:aspectjweaver:1.9.25' + // aspectjtools 1.9.25 requires JDK 17 and is not used by java-tron. api group: 'io.github.tronprotocol', name: 'libp2p', version: '2.2.9',{ exclude group: 'io.grpc', module: 'grpc-context' exclude group: 'io.grpc', module: 'grpc-core' @@ -44,8 +46,8 @@ dependencies { jacocoTestReport { reports { - xml.enabled = true - html.enabled = true + xml.required = true + html.required = true } getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec")) afterEvaluate { diff --git a/common/src/main/java/org/tron/core/exception/TronError.java b/common/src/main/java/org/tron/core/exception/TronError.java index 4ee7cdae916..681d5706425 100644 --- a/common/src/main/java/org/tron/core/exception/TronError.java +++ b/common/src/main/java/org/tron/core/exception/TronError.java @@ -49,8 +49,7 @@ public enum ErrCode { RATE_LIMITER_INIT(1), SOLID_NODE_INIT(0), PARAMETER_INIT(1), - ACTUATOR_REGISTER(1), - JDK_VERSION(1); + ACTUATOR_REGISTER(1); private final int code; diff --git a/consensus/build.gradle b/consensus/build.gradle index 04cc24be5fd..f17c25c30ff 100644 --- a/consensus/build.gradle +++ b/consensus/build.gradle @@ -32,8 +32,8 @@ test { jacocoTestReport { reports { - xml.enabled = true - html.enabled = true + xml.required = true + html.required = true } getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec")) afterEvaluate { diff --git a/crypto/build.gradle b/crypto/build.gradle index 82814af49e6..f8611757b11 100644 --- a/crypto/build.gradle +++ b/crypto/build.gradle @@ -2,9 +2,11 @@ plugins { id 'java' } -version '1.0.0' +version = '1.0.0' -sourceCompatibility = 1.8 +java { + sourceCompatibility = JavaVersion.VERSION_1_8 +} repositories { mavenCentral() @@ -16,8 +18,8 @@ dependencies { jacocoTestReport { reports { - xml.enabled = true - html.enabled = true + xml.required = true + html.required = true } getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec")) afterEvaluate { diff --git a/docs/implement-a-customized-actuator-en.md b/docs/implement-a-customized-actuator-en.md index 912a49c5d63..d2ff8b18395 100644 --- a/docs/implement-a-customized-actuator-en.md +++ b/docs/implement-a-customized-actuator-en.md @@ -56,19 +56,21 @@ service Wallet { ... }; ``` -At last, recompile the modified proto files. Compiling the java-tron project directly will compile the proto files as well, `protoc` command is also supported. +At last, recompile the modified proto files. Compiling the java-tron project directly recompiles the proto files automatically via the Gradle protobuf plugin. ```shell # recommended — also recompiles proto files automatically ./gradlew build -x test -# or build via protoc (ensure the protoc version matches the one declared in build.gradle) -protoc -I=src/main/protos -I=src/main/protos/core --java_out=src/main/java Tron.proto -protoc -I=src/main/protos/core/contract --java_out=src/main/java math_contract.proto -protoc -I=src/main/protos/api -I=src/main/protos/core -I=src/main/protos --java_out=src/main/java api.proto +# or regenerate the protobuf/gRPC sources only +./gradlew :protocol:generateProto ``` -After compilation, the corresponding .class under the java_out directory will be updated. +Running `generateProto` writes the generated sources to +`protocol/build/generated/sources/proto/main/java`. The `compileJava` task compiles them +afterwards, including during a normal build. Do not generate java files into +`protocol/src/main/java`: that directory is excluded from compilation and is removed by +`clean` or when protobuf code generation actually runs. ## Implement SumActuator diff --git a/docs/implement-a-customized-actuator-zh.md b/docs/implement-a-customized-actuator-zh.md index 9aa0e258127..b8a765b5668 100644 --- a/docs/implement-a-customized-actuator-zh.md +++ b/docs/implement-a-customized-actuator-zh.md @@ -58,19 +58,20 @@ service Wallet { ... }; ``` -最后重新编译修改过 proto 文件,可自行编译也可直接通过编译 java-tron 项目来编译 proto 文件: +最后重新编译修改过的 proto 文件,直接编译 java-tron 项目即可,Gradle protobuf 插件会自动重新生成: ```shell # 推荐方式 —— 直接编译项目,proto 文件会自动重新编译 ./gradlew build -x test -# 或者手动使用 protoc(版本需与 build.gradle 中声明的一致) -protoc -I=src/main/protos -I=src/main/protos/core --java_out=src/main/java Tron.proto -protoc -I=src/main/protos/core/contract --java_out=src/main/java math_contract.proto -protoc -I=src/main/protos/api -I=src/main/protos/core -I=src/main/protos --java_out=src/main/java api.proto +# 或者只重新生成 protobuf/gRPC 源码 +./gradlew :protocol:generateProto ``` -编译之后会更新 java_out 目录中对应的 java 文件。 +执行 `generateProto` 后,生成的源码位于 +`protocol/build/generated/sources/proto/main/java`。之后 `compileJava` 会编译这些源码, +正常构建也包含这一流程。请勿将生成的 java 文件放入 `protocol/src/main/java`: +该目录不参与编译,并会在执行 `clean` 或 protobuf 代码生成任务实际运行时被清理。 ## 实现 SumActuator diff --git a/docs/modular-deployment-en.md b/docs/modular-deployment-en.md index c93ba6c39d8..518ff0b6961 100644 --- a/docs/modular-deployment-en.md +++ b/docs/modular-deployment-en.md @@ -43,9 +43,13 @@ java-tron-1.0.0/bin/FullNode -c config.conf -w ## JVM configuration -JVM options can also be specified, located in `bin/java-tron.vmoptions`: +java-tron requires JDK 8 or newer on x86_64 and JDK 17 or newer on ARM64. The +packaged defaults use the JDK 17+ JVM options when built with JDK 17 or newer; +otherwise they use the CMS options. + +JVM options can also be specified in `bin/java-tron.vmoptions`: ``` -# demo (compatible with JDK 8 / JDK 17) +# demo for JDK versions below 17 -Xms2g -Xmx9g -XX:+PrintGCDetails diff --git a/docs/modular-deployment-zh.md b/docs/modular-deployment-zh.md index 27cc2ab3856..129f53878d3 100644 --- a/docs/modular-deployment-zh.md +++ b/docs/modular-deployment-zh.md @@ -41,9 +41,13 @@ java-tron-1.0.0/bin/FullNode -c config.conf -w ## jvm参数配置 -java-tron 支持对 jvm 参数进行配置,配置文件为 bin 目录下的 java-tron.vmoptions 文件。 +java-tron 在 x86_64 架构上要求 JDK 8 及以上版本,在 ARM64 架构上要求 JDK 17 +及以上版本。使用 JDK 17 及以上版本构建时,发布包默认使用 JDK 17+ 的 JVM 参数; +低于 JDK 17 时使用 CMS 参数。 + +java-tron 支持在 bin 目录下的 java-tron.vmoptions 文件中配置 JVM 参数。 ``` -# demo(兼容 JDK 8 / JDK 17) +# JDK 17 以下版本示例 -Xms2g -Xmx9g -XX:+PrintGCDetails diff --git a/errorprone/build.gradle b/errorprone/build.gradle index f8a634b7edc..a078ba096fc 100644 --- a/errorprone/build.gradle +++ b/errorprone/build.gradle @@ -1,5 +1,5 @@ -if (!JavaVersion.current().isJava11Compatible()) { - // ErrorProne core requires JDK 11+; skip this module on JDK 8 +if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) { + // ErrorProne core 2.42.0 ships Java 17 bytecode; skip below JDK 17 tasks.withType(JavaCompile).configureEach { enabled = false } tasks.withType(Jar).configureEach { enabled = false } } else { diff --git a/framework/build.gradle b/framework/build.gradle index 8255fc30d18..c7a7ad510ae 100644 --- a/framework/build.gradle +++ b/framework/build.gradle @@ -1,5 +1,5 @@ plugins { - id "org.gradle.test-retry" version "1.5.9" + id "org.gradle.test-retry" version "1.6.5" id "org.sonarqube" version "2.6" id "com.gorylenko.gradle-git-properties" version "2.4.1" } @@ -9,7 +9,13 @@ gitProperties.failOnNoGitDirectory = false; apply plugin: 'application' apply plugin: 'checkstyle' -mainClassName = 'org.tron.program.FullNode' +application { + mainClass = 'org.tron.program.FullNode' + applicationName = 'java-tron' + applicationDistribution.from(rootProject.archInfo.VMOptions) { + into "bin" + } +} def versions = [ checkstyle: '8.7', @@ -99,7 +105,9 @@ tasks.matching { it instanceof Test }.all { } if (project.hasProperty("mainClass")) { - mainClassName = mainClass + application { + mainClass = project.property("mainClass") + } } run { @@ -171,17 +179,17 @@ tasks.register('testWithRocksDb', Test) { jacocoTestReport { reports { - xml.enabled true - csv.enabled false - html.destination file("${buildDir}/jacocoHtml") + xml.required = true + csv.required = false + html.outputLocation = file("${buildDir}/jacocoHtml") } getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec")) } def binaryRelease(taskName, jarName, mainClass) { return tasks.create("${taskName}", Jar) { - baseName = jarName - version = null + archiveBaseName = jarName + archiveVersion = "" from(sourceSets.main.output) { include "/**" } @@ -211,12 +219,12 @@ def binaryRelease(taskName, jarName, mainClass) { } } -def createScript(project, mainClass, name) { +def createScript(project, mainClassName, name) { project.tasks.create(name: name, type: CreateStartScripts) { unixStartScriptGenerator.template = resources.text.fromFile('../gradle/unixStartScript.txt') windowsStartScriptGenerator.template = resources.text.fromFile('../gradle/windowsStartScript.txt') outputDir = new File(project.buildDir, 'scripts') - mainClassName = mainClass + mainClass = mainClassName applicationName = name classpath = project.tasks[JavaPlugin.JAR_TASK_NAME].outputs.files + project.configurations.runtimeClasspath // defaultJvmOpts = ['-XX:+UseConcMarkSweepGC', @@ -229,23 +237,21 @@ def createScript(project, mainClass, name) { // ] } project.tasks[name].dependsOn(project.jar) - project.applicationDistribution.with { + project.extensions.getByType(org.gradle.api.plugins.JavaApplication).applicationDistribution.with { into("bin") { from(project.tasks[name]) - fileMode = 0755 + filePermissions { + unix('rwxr-xr-x') + } } } } -applicationDistribution.from(rootProject.archInfo.VMOptions) { - into "bin" -} //distZip { // doLast { // file("$destinationDir/$archiveName").renameTo("$destinationDir/"+'java-tron-'+version+'-bin.zip') // } //} configurations.archives.artifacts.removeAll { it.type == 'tar' } -applicationName = 'java-tron' startScripts.enabled = false run.enabled = false tasks.distTar.enabled = false diff --git a/framework/src/main/java/org/tron/program/FullNode.java b/framework/src/main/java/org/tron/program/FullNode.java index 96b9f73d577..dd48d287af5 100644 --- a/framework/src/main/java/org/tron/program/FullNode.java +++ b/framework/src/main/java/org/tron/program/FullNode.java @@ -6,7 +6,6 @@ import org.tron.common.application.Application; import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; -import org.tron.common.arch.Arch; import org.tron.common.exit.ExitManager; import org.tron.common.log.LogService; import org.tron.common.parameter.CommonParameter; @@ -23,7 +22,6 @@ public class FullNode { */ public static void main(String[] args) { ExitManager.initExceptionHandler(); - checkJdkVersion(); Args.setParam(args, "config.conf"); CommonParameter parameter = Args.getInstance(); @@ -66,13 +64,4 @@ public static void main(String[] args) { } appT.blockUntilShutdown(); } - - private static void checkJdkVersion() { - try { - Arch.throwIfUnsupportedJavaVersion(); - } catch (UnsupportedOperationException e) { - System.err.println(e.getMessage()); - throw new TronError(e, TronError.ErrCode.JDK_VERSION); - } - } } diff --git a/framework/src/test/java/org/tron/core/exception/TronErrorTest.java b/framework/src/test/java/org/tron/core/exception/TronErrorTest.java index 91559d86362..75a7b428626 100644 --- a/framework/src/test/java/org/tron/core/exception/TronErrorTest.java +++ b/framework/src/test/java/org/tron/core/exception/TronErrorTest.java @@ -2,11 +2,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThrows; -import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mockStatic; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.util.ContextInitializer; @@ -32,7 +29,6 @@ import org.mockito.junit.MockitoJUnitRunner; import org.slf4j.LoggerFactory; import org.tron.common.TestConstants; -import org.tron.common.arch.Arch; import org.tron.common.log.LogService; import org.tron.common.parameter.RateLimiterInitialization; import org.tron.common.utils.ReflectUtils; @@ -153,58 +149,4 @@ public void shutdownBlockTimeInitTest() { assertEquals(TronError.ErrCode.AUTO_STOP_PARAMS, thrown.getErrCode()); } - @Test - public void testThrowIfUnsupportedJavaVersion() { - runArchTest("x86_64", "1.8", false); - runArchTest("x86_64", "11", true); - runArchTest("x86_64", "17", true); - runArchTest("aarch64", "17", false); - runArchTest("aarch64", "1.8", true); - runArchTest("aarch64", "11", true); - } - - private void runArchTest(String osArch, String javaVersion, boolean expectThrow) { - try (MockedStatic mocked = mockStatic(Arch.class)) { - boolean isX86 = "x86_64".equals(osArch); - boolean isArm64 = "aarch64".equals(osArch); - - boolean isJava8 = "1.8".equals(javaVersion); - boolean isJava17 = "17".equals(javaVersion); - - mocked.when(Arch::isX86).thenReturn(isX86); - mocked.when(Arch::isArm64).thenReturn(isArm64); - - mocked.when(Arch::isJava8).thenReturn(isJava8); - mocked.when(Arch::isJava17).thenReturn(isJava17); - - mocked.when(Arch::getOsArch).thenReturn(osArch); - mocked.when(Arch::javaSpecificationVersion).thenReturn(javaVersion); - mocked.when(Arch::withAll).thenReturn(String.format( - "Architecture: %s, Java Version: %s", osArch, javaVersion)); - - mocked.when(Arch::throwIfUnsupportedJavaVersion).thenCallRealMethod(); - - if (expectThrow) { - UnsupportedOperationException err = assertThrows( - UnsupportedOperationException.class, - Arch::throwIfUnsupportedJavaVersion); - - String expectedJavaVersion = isX86 ? "1.8" : "17"; - String expectedMessage = String.format( - "Java %s is required for %s architecture." - + " Detected version %s", - expectedJavaVersion, osArch, javaVersion); - assertEquals(expectedMessage, err.getMessage()); - mocked.verify(Arch::withAll, times(1)); - } else { - try { - Arch.throwIfUnsupportedJavaVersion(); - } catch (Exception e) { - fail("Expected no exception, but got: " + e.getMessage()); - } - mocked.verify(Arch::withAll, never()); - } - } - } - } diff --git a/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java b/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java index e8d14ace060..36ea2faab54 100644 --- a/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java +++ b/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java @@ -1563,7 +1563,8 @@ public void testWeb3ClientVersion() { try { String[] versions = tronJsonRpc.web3ClientVersion().split("/"); String javaVersion = versions[versions.length - 1]; - Assert.assertTrue("Java1.8".equals(javaVersion) || "Java17".equals(javaVersion)); + Assert.assertEquals( + "Java" + System.getProperty("java.specification.version"), javaVersion); } catch (Exception e) { Assert.fail(); } diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 6a3e641d5d6..ffde89dee42 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -1,5 +1,5 @@ - + true false @@ -565,12 +565,12 @@ - - - + + + - - + + @@ -777,12 +777,12 @@ - - - + + + - - + + @@ -1544,12 +1544,12 @@ - - - + + + - - + + @@ -1560,25 +1560,25 @@ - - - + + + - - + + - - - + + + - - + + - - - + + + @@ -1937,28 +1937,20 @@ - - - + + + - - + + - - - + + + - - - - - - - - - - + + @@ -2221,20 +2213,20 @@ - - - + + + - - + + - - + + - - - + + + @@ -2268,12 +2260,12 @@ - - - + + + - - + + @@ -2284,17 +2276,17 @@ - - - + + + - - + + - - - + + + @@ -2302,20 +2294,20 @@ - - - + + + - - + + - - - + + + - - + + @@ -2487,6 +2479,14 @@ + + + + + + + + @@ -2511,11 +2511,24 @@ + + + + + + + + + + + + + @@ -2532,6 +2545,14 @@ + + + + + + + + @@ -2572,12 +2593,12 @@ - - - + + + - - + + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 5c2d1cf016b..1b33c55baab 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3994438e229..4f5eb9dcc0e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 83f2acfdc31..23d15a93670 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,80 +15,115 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -97,92 +132,120 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" fi +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 24467a141f7..5eed7ee8452 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,8 +13,10 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,10 +27,14 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @@ -37,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -51,48 +57,36 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/install_dependencies.sh b/install_dependencies.sh index f72ecf2e192..5f7484380ce 100755 --- a/install_dependencies.sh +++ b/install_dependencies.sh @@ -35,10 +35,10 @@ fi echo "" echo ">>> Tested platforms:" -echo " - macOS x86_64 (JDK 8)" -echo " - macOS arm64 (JDK 17)" -echo " - Linux x86_64 (generic, including Ubuntu) (JDK 8)" -echo " - Linux arm64/aarch64 (generic, including Ubuntu) (JDK 17)" +echo " - macOS x86_64 (JDK 8 or newer)" +echo " - macOS arm64 (JDK 17 or newer)" +echo " - Linux x86_64 (generic, including Ubuntu) (JDK 8 or newer)" +echo " - Linux arm64/aarch64 (generic, including Ubuntu) (JDK 17 or newer)" echo " Note: Other platforms may require manual installation if errors occur" echo "" echo ">>> This script will install the following components if not already installed:" @@ -50,15 +50,15 @@ else fi if [[ "$OS" == "Darwin" ]]; then if [[ "$ARCH" == "x86_64" ]]; then - echo " 3. OpenJDK 8 (required for x86_64 architecture)" + echo " 3. OpenJDK 8 (default installer choice for x86_64)" else - echo " 3. OpenJDK 17 (required for arm64 architecture)" + echo " 3. OpenJDK 17 (default installer choice for arm64)" fi else if [[ "$ARCH" == "x86_64" ]]; then - echo " 2. OpenJDK 8 (required for x86_64 architecture)" + echo " 2. OpenJDK 8 (default installer choice for x86_64)" else - echo " 2. OpenJDK 17 (required for arm64/aarch64 architecture)" + echo " 2. OpenJDK 17 (default installer choice for arm64/aarch64)" fi fi echo "" @@ -75,49 +75,100 @@ ask_confirmation() { done } -# Function to check Java version -check_java_version() { - if command -v java &> /dev/null; then - local java_version=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2) - echo " Current Java version: $java_version" - - # Check if it's JDK 8 (version starts with 1.8) - if [[ "$java_version" =~ ^1\.8\. ]]; then - echo " JDK 8 is installed." - return 0 - # Check if it's JDK 17 (version starts with 17) - elif [[ "$java_version" =~ ^17\. ]]; then - echo " JDK 17 is installed." +# Return success when javac ships with the installation the given java +# launcher belongs to. +has_javac() { + local java_cmd="$1" + local java_major="$2" + + # An explicit JAVA_HOME must be a complete JDK on its own: that directory + # is what gradlew hands to the Gradle daemon. + if [[ -n "${JAVA_HOME:-}" ]]; then + [[ -x "$JAVA_HOME/bin/javac" ]] + return $? + fi + + local java_home + java_home=$("$java_cmd" -XshowSettings:properties -version 2>&1 \ + | awk -F'= ' '/java\.home/ {print $2}') + if [[ -z "$java_home" ]]; then + return 1 + fi + if [[ -x "$java_home/bin/javac" ]]; then + return 0 + fi + # On JDK 8 java.home is the jre subdirectory of the JDK. + [[ "$java_major" == "8" && -x "$java_home/../bin/javac" ]] +} + +# Return success when the installed JDK meets the architecture's minimum version. +check_supported_java_version() { + local minimum_major="$1" + + # Check the JVM gradlew would pick: JAVA_HOME wins over PATH. Callers + # report on the very same launcher through SELECTED_JAVA_CMD. + local java_cmd + SELECTED_JAVA_CMD="" + if [[ -n "${JAVA_HOME:-}" ]]; then + java_cmd="$JAVA_HOME/bin/java" + if [[ ! -x "$java_cmd" ]]; then + echo " JAVA_HOME is set to an invalid directory: $JAVA_HOME" return 1 - else - echo " Different Java version detected: $java_version" - return 2 fi + elif command -v java &> /dev/null; then + java_cmd="$(command -v java)" + else + return 2 + fi + SELECTED_JAVA_CMD="$java_cmd" + + local java_version + local java_major + java_version=$("$java_cmd" -version 2>&1 | head -n 1 | cut -d'"' -f2) + echo " Current Java version: $java_version ($java_cmd)" + + if [[ "$java_version" =~ ^1\.([0-9]+) ]]; then + java_major="${BASH_REMATCH[1]}" else - return 3 + java_major="${java_version%%.*}" fi + + if [[ "$java_major" =~ ^[0-9]+$ ]] && (( java_major >= minimum_major )); then + # A JRE-only installation passes the version check but cannot compile. + if ! has_javac "$java_cmd" "$java_major"; then + echo " Found java $java_version but no javac in the same" + echo " installation: building java-tron requires a full JDK." + return 1 + fi + echo " JDK $java_major is supported on $ARCH (minimum JDK $minimum_major)." + return 0 + fi + + echo " Unsupported Java version detected: $java_version" + echo " Minimum version for $ARCH: JDK $minimum_major" + return 1 } # Function to ask for JDK installation confirmation ask_jdk_confirmation() { local current_version="$1" - local required_version="$2" + local recommended_version="$2" local arch="$3" echo "" - echo "JDK Version Mismatch Detected!" + echo "Unsupported JDK Version Detected!" echo " Current version: $current_version" - echo " Current installation path: $(which java 2>/dev/null || echo 'Not found')" - if command -v java &> /dev/null && [[ -n "$JAVA_HOME" ]]; then + echo " Current installation path: ${SELECTED_JAVA_CMD:-Not found}" + if [[ -n "${JAVA_HOME:-}" ]]; then echo " Current JAVA_HOME: $JAVA_HOME" fi - echo " Required version for $arch: $required_version" - echo " This script will install $required_version alongside your existing installation." + echo " Recommended installation for $arch: $recommended_version" + echo " This script will install $recommended_version alongside your existing installation." echo " Your current Java installation will not be removed." echo "" while true; do - read -p "Do you want to install $required_version? (y/N): " yn + read -p "Do you want to install $recommended_version? (y/N): " yn case $yn in [Yy]* ) return 0;; [Nn]* | "" ) echo "JDK installation cancelled. Exiting."; exit 0;; @@ -150,34 +201,34 @@ else INSTALL_GIT=false fi -echo "" -echo ">>> Checking existing Java installation..." -set +e # Temporarily disable exit on error -check_java_version -java_status=$? -set -e # Re-enable exit on error - -# Determine required JDK version based on architecture +# Determine the minimum and default JDK for the current architecture. if [[ "$OS" == "Darwin" ]]; then if [[ "$ARCH" == "x86_64" ]]; then - required_jdk="JDK 8" - required_status=0 + recommended_jdk="JDK 8" + minimum_java_major=8 elif [[ "$ARCH" == "arm64" ]]; then - required_jdk="JDK 17" - required_status=1 + recommended_jdk="JDK 17" + minimum_java_major=17 fi elif [[ "$OS" == "Linux" ]]; then if [[ "$ARCH" == "x86_64" ]]; then - required_jdk="JDK 8" - required_status=0 + recommended_jdk="JDK 8" + minimum_java_major=8 elif [[ "$ARCH" == "aarch64" ]] || [[ "$ARCH" == "arm64" ]]; then - required_jdk="JDK 17" - required_status=1 + recommended_jdk="JDK 17" + minimum_java_major=17 fi fi -# Check if correct JDK version is already installed -if [[ $java_status -eq $required_status ]]; then +echo "" +echo ">>> Checking existing Java installation..." +set +e # Temporarily disable exit on error +check_supported_java_version "$minimum_java_major" +java_status=$? +set -e # Re-enable exit on error + +# Keep every existing JDK that meets the architecture's minimum version. +if [[ $java_status -eq 0 ]]; then echo " You can skip the Java installation part." echo "" if [[ "$INSTALL_GIT" == "false" ]]; then @@ -188,16 +239,19 @@ if [[ $java_status -eq $required_status ]]; then echo ">>> Proceeding with Git installation only..." SKIP_JAVA_INSTALL=true fi -elif [[ $java_status -eq 0 ]] || [[ $java_status -eq 1 ]] || [[ $java_status -eq 2 ]]; then - # Different JDK version is installed, ask for confirmation - current_version=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2) - ask_jdk_confirmation "$current_version" "$required_jdk" "$ARCH" +elif [[ $java_status -eq 1 ]]; then + # An older or unrecognized JDK is installed; offer a supported default. + current_version="Not found" + if [[ -n "${SELECTED_JAVA_CMD:-}" ]]; then + current_version=$("$SELECTED_JAVA_CMD" -version 2>&1 | head -n 1 | cut -d'"' -f2) + fi + ask_jdk_confirmation "$current_version" "$recommended_jdk" "$ARCH" SKIP_JAVA_INSTALL=false else # No Java installation found, ask for general confirmation echo "" echo "No Java installation detected!" - echo " This script will install $required_jdk which is required for $ARCH architecture." + echo " This script will install $recommended_jdk as the default for $ARCH." echo "" ask_confirmation SKIP_JAVA_INSTALL=false @@ -547,22 +601,16 @@ install_macos() { fi if [[ "$ARCH" == "x86_64" ]]; then - echo ">>> Architecture is x86_64. Checking for JDK 8..." + echo ">>> Architecture is x86_64. Checking for a supported JDK..." set +e # Temporarily disable exit on error - check_java_version + check_supported_java_version "$minimum_java_major" local java_status=$? set -e # Re-enable exit on error if [[ $java_status -eq 0 ]]; then - echo ">>> JDK 8 is already installed. Skipping installation." + echo ">>> A supported JDK is already installed. Skipping installation." else - if [[ $java_status -eq 1 ]]; then - echo ">>> Installing JDK 8 alongside existing JDK 17..." - elif [[ $java_status -eq 2 ]]; then - echo ">>> Installing JDK 8 alongside existing Java installation..." - else - echo ">>> Installing JDK 8..." - fi + echo ">>> Installing JDK 8 alongside any existing Java installation..." if brew install openjdk@8; then echo ">>> JDK 8 installation completed successfully." @@ -580,22 +628,16 @@ install_macos() { fi elif [[ "$ARCH" == "arm64" ]]; then - echo ">>> Architecture is arm64. Checking for JDK 17..." + echo ">>> Architecture is arm64. Checking for a supported JDK..." set +e # Temporarily disable exit on error - check_java_version + check_supported_java_version "$minimum_java_major" local java_status=$? set -e # Re-enable exit on error - if [[ $java_status -eq 1 ]]; then - echo ">>> JDK 17 is already installed. Skipping installation." + if [[ $java_status -eq 0 ]]; then + echo ">>> A supported JDK is already installed. Skipping installation." else - if [[ $java_status -eq 0 ]]; then - echo ">>> Installing JDK 17 alongside existing JDK 8..." - elif [[ $java_status -eq 2 ]]; then - echo ">>> Installing JDK 17 alongside existing Java installation..." - else - echo ">>> Installing JDK 17..." - fi + echo ">>> Installing JDK 17 alongside any existing Java installation..." if brew install openjdk@17; then echo ">>> JDK 17 installation completed successfully." @@ -704,22 +746,16 @@ install_linux() { } if [[ "$ARCH" == "x86_64" ]]; then - echo ">>> Architecture is x86_64. Checking for JDK 8..." + echo ">>> Architecture is x86_64. Checking for a supported JDK..." set +e # Temporarily disable exit on error - check_java_version + check_supported_java_version "$minimum_java_major" local java_status=$? set -e # Re-enable exit on error if [[ $java_status -eq 0 ]]; then - echo ">>> JDK 8 is already installed. Skipping installation." + echo ">>> A supported JDK is already installed. Skipping installation." else - if [[ $java_status -eq 1 ]]; then - echo ">>> Installing JDK 8 alongside existing JDK 17..." - elif [[ $java_status -eq 2 ]]; then - echo ">>> Installing JDK 8 alongside existing Java installation..." - else - echo ">>> Installing JDK 8..." - fi + echo ">>> Installing JDK 8 alongside any existing Java installation..." if [[ "$PKG_MANAGER" == "apt-get" ]]; then if install_first_available "8" openjdk-8-jdk; then install_result=0 @@ -805,22 +841,16 @@ install_linux() { fi elif [[ "$ARCH" == "aarch64" ]] || [[ "$ARCH" == "arm64" ]]; then - echo ">>> Architecture is arm64/aarch64. Checking for JDK 17..." + echo ">>> Architecture is arm64/aarch64. Checking for a supported JDK..." set +e # Temporarily disable exit on error - check_java_version + check_supported_java_version "$minimum_java_major" local java_status=$? set -e # Re-enable exit on error - - if [[ $java_status -eq 1 ]]; then - echo ">>> JDK 17 is already installed. Skipping installation." + + if [[ $java_status -eq 0 ]]; then + echo ">>> A supported JDK is already installed. Skipping installation." else - if [[ $java_status -eq 0 ]]; then - echo ">>> Installing JDK 17 alongside existing JDK 8..." - elif [[ $java_status -eq 2 ]]; then - echo ">>> Installing JDK 17 alongside existing Java installation..." - else - echo ">>> Installing JDK 17..." - fi + echo ">>> Installing JDK 17 alongside any existing Java installation..." if [[ "$PKG_MANAGER" == "apt-get" ]]; then if install_first_available "17" openjdk-17-jdk; then install_result=0 @@ -926,32 +956,31 @@ else fi echo "----------------------------------------" -echo "Installation completed successfully!" -echo "" -echo ">>> Verification Commands:" -echo " git --version" -echo " java -version" -echo "" -# Verify that Java is actually working -echo ">>> Verifying Java installation..." -if command -v java &> /dev/null; then - echo " Java command found: $(which java)" - if java -version &> /dev/null; then - echo " Java version: $(java -version 2>&1 | head -n 1)" - else - echo " ✗ Java command exists but cannot run properly" - echo " Please run: source ./tron_java_env.sh" - fi -else - echo " ✗ Java command not found in PATH" - echo " Please run: source ./tron_java_env.sh" - echo " If that doesn't work, check the Java environment configuration above." +# Re-run the same validator the build relies on, so the script never reports +# success for an environment gradlew cannot build with. +echo ">>> Verifying the Java environment..." +set +e # Temporarily disable exit on error +check_supported_java_version "$minimum_java_major" +final_java_status=$? +set -e # Re-enable exit on error + +if [[ $final_java_status -ne 0 ]]; then + echo "" + echo "✗ The current environment cannot build java-tron." + echo "" + echo ">>> Troubleshooting:" + echo " - Load the JDK installed above: source ./tron_java_env.sh" + echo " - Or point JAVA_HOME at a JDK $minimum_java_major or newer installation." + echo " - For permanent configuration, follow the instructions shown above." + echo "" + exit 1 fi echo "" -echo ">>> Troubleshooting:" -echo " - If 'java -version' shows incorrect version, run: source ./tron_java_env.sh" -echo " - For permanent configuration, follow the instructions shown above." +echo "Installation completed successfully!" echo "" +echo ">>> Verification Commands:" +echo " git --version" +echo " java -version" echo "" \ No newline at end of file diff --git a/platform/src/main/java/common/org/tron/common/arch/Arch.java b/platform/src/main/java/common/org/tron/common/arch/Arch.java index 999bb631bea..38552fdf317 100644 --- a/platform/src/main/java/common/org/tron/common/arch/Arch.java +++ b/platform/src/main/java/common/org/tron/common/arch/Arch.java @@ -1,9 +1,7 @@ package org.tron.common.arch; import java.util.Locale; -import lombok.extern.slf4j.Slf4j; -@Slf4j(topic = "arch") public final class Arch { private Arch() { @@ -62,27 +60,6 @@ public static boolean isArm64() { return osArch.contains("arm64") || osArch.contains("aarch64"); } - public static boolean isX86() { - return !isArm64(); - } - - public static boolean isJava8() { - return javaSpecificationVersion().equals("1.8"); - } - - public static boolean isJava17() { - return javaSpecificationVersion().equals("17"); - } - - public static void throwIfUnsupportedJavaVersion() { - if ((isX86() && !isJava8()) || (isArm64() && !isJava17())) { - logger.info(withAll()); - throw new UnsupportedOperationException(String.format( - "Java %s is required for %s architecture. Detected version %s", isX86() ? "1.8" : "17", - getOsArch(), javaSpecificationVersion())); - } - } - public static void throwIfUnsupportedArm64Exception(String message) { if (isArm64()) { throw new UnsupportedOperationException( diff --git a/platform/src/main/java/arm/org/tron/common/math/MathWrapper.java b/platform/src/main/java/common/org/tron/common/math/MathWrapper.java similarity index 100% rename from platform/src/main/java/arm/org/tron/common/math/MathWrapper.java rename to platform/src/main/java/common/org/tron/common/math/MathWrapper.java diff --git a/platform/src/main/java/x86/org/tron/common/math/MathWrapper.java b/platform/src/main/java/x86/org/tron/common/math/MathWrapper.java deleted file mode 100644 index 758a0f18370..00000000000 --- a/platform/src/main/java/x86/org/tron/common/math/MathWrapper.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.tron.common.math; - -/** - * This class is deprecated and should not be used in new code, - * for cross-platform consistency, please use {@link StrictMathWrapper} instead, - * especially for floating-point calculations. - */ -@Deprecated -public class MathWrapper { - - public static double pow(double a, double b) { - return Math.pow(a, b); - } - - public static long addExact(long x, long y) { - return Math.addExact(x, y); - } - - public static int addExact(int x, int y) { - return Math.addExact(x, y); - } - - public static long floorDiv(long x, long y) { - return Math.floorDiv(x, y); - } - - public static int multiplyExact(int x, int y) { - return Math.multiplyExact(x, y); - } - - public static long multiplyExact(long x, long y) { - return Math.multiplyExact(x, y); - } - - public static long subtractExact(long x, long y) { - return Math.subtractExact(x, y); - } - - public static int min(int a, int b) { - return Math.min(a, b); - } - - public static long min(long a, long b) { - return Math.min(a, b); - } - - public static int max(int a, int b) { - return Math.max(a, b); - } - - public static long max(long a, long b) { - return Math.max(a, b); - } - - public static int round(float a) { - return Math.round(a); - } - - public static long round(double a) { - return Math.round(a); - } - - public static double ceil(double a) { - return Math.ceil(a); - } - - public static double signum(double a) { - return Math.signum(a); - } - - public static double random() { - return Math.random(); - } - - public static long abs(long a) { - return Math.abs(a); - } -} diff --git a/plugins/build.gradle b/plugins/build.gradle index 09a13a19b1b..0628f573148 100644 --- a/plugins/build.gradle +++ b/plugins/build.gradle @@ -8,9 +8,14 @@ apply plugin: 'checkstyle' def versions = [ checkstyle: '8.7', ] -mainClassName = 'org.tron.plugins.ArchiveManifest' -group 'org.tron' -version '1.0.0' +application { + mainClass = 'org.tron.plugins.ArchiveManifest' + applicationDistribution.from(rootProject.archInfo.VMOptions) { + into "bin" + } +} +group = 'org.tron' +version = '1.0.0' configurations { checkstyleConfig @@ -102,7 +107,9 @@ tasks.matching { it instanceof Test }.all { } if (project.hasProperty("mainClass")) { - mainClassName = mainClass + application { + mainClass = project.property("mainClass") + } } test { @@ -129,17 +136,17 @@ test { jacocoTestReport { reports { - xml.enabled true - csv.enabled false - html.destination file("${buildDir}/jacocoHtml") + xml.required = true + csv.required = false + html.outputLocation = file("${buildDir}/jacocoHtml") } getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec")) } def binaryRelease(taskName, jarName, mainClass) { return tasks.create("${taskName}", Jar) { - baseName = jarName - version = null + archiveBaseName = jarName + archiveVersion = "" from(sourceSets.main.output) { include "/**" } @@ -167,24 +174,23 @@ def binaryRelease(taskName, jarName, mainClass) { } } -def createScript(project, mainClass, name) { +def createScript(project, mainClassName, name) { project.tasks.create(name: name, type: CreateStartScripts) { outputDir = new File(project.buildDir, 'scripts') - mainClassName = mainClass + mainClass = mainClassName applicationName = name classpath = project.tasks[JavaPlugin.JAR_TASK_NAME].outputs.files + project.configurations.runtimeClasspath } project.tasks[name].dependsOn(project.jar) - project.applicationDistribution.with { + project.extensions.getByType(org.gradle.api.plugins.JavaApplication).applicationDistribution.with { into("bin") { from(project.tasks[name]) - fileMode = 0755 + filePermissions { + unix('rwxr-xr-x') + } } } } -applicationDistribution.from(rootProject.archInfo.VMOptions) { - into "bin" -} createScript(project, 'org.tron.plugins.ArchiveManifest', 'ArchiveManifest') createScript(project, 'org.tron.plugins.Toolkit', 'Toolkit') diff --git a/protocol/build.gradle b/protocol/build.gradle index ed8914343b8..28ea6f6fbcb 100644 --- a/protocol/build.gradle +++ b/protocol/build.gradle @@ -30,16 +30,19 @@ sourceSets { proto { srcDir 'src/main/protos' } + // The protocol module has no hand-written java sources; anything under + // src/main/java is leftover output of builds that predate the codegen + // relocation to build/generated. Drop that srcDir (keeping the dirs the + // protobuf plugin registered) so leftovers can never shadow the + // generated classes, even when generateProto is UP-TO-DATE. java { - srcDir 'src/main/gen' - srcDir 'src/main/java' + srcDirs = srcDirs.findAll { it != file('src/main/java') } } } } protobuf { - generatedFilesBaseDir = "$projectDir/src/" protoc { artifact = "com.google.protobuf:protoc:${protobufVersion}" } @@ -63,8 +66,16 @@ protobuf { } } -clean.doFirst { - delete "src/main/java" +// Disk hygiene only (correctness is handled by the srcDirs override above, +// which also covers the case where generateProto is UP-TO-DATE and its +// doFirst never runs): sweep pre-relocation codegen leftovers from src/. +def purgeLegacyGeneratedSources = { + project.delete('src/main/java', 'src/main/gen') } +generateProto.doFirst { purgeLegacyGeneratedSources() } +clean.doFirst { purgeLegacyGeneratedSources() } +// The srcDirs override above flattens the source set to plain files, losing +// the builtBy dependency the protobuf plugin registered, so declare it here. +compileJava.dependsOn(generateProto) // explicit_dependency processResources.dependsOn(generateProto) // explicit_dependency