diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c0c12448..e53a756e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,7 +1,17 @@ version: 2 updates: - package-ecosystem: "gradle" - directory: "/" + directory: "/pbj-core" + schedule: + interval: "daily" + open-pull-requests-limit: 10 + - package-ecosystem: "gradle" + directory: "/pbj-integration-tests" + schedule: + interval: "daily" + open-pull-requests-limit: 10 + - package-ecosystem: "gradle" + directory: "/pbj-core/hiero-dependency-versions" schedule: interval: "daily" open-pull-requests-limit: 10 diff --git a/.github/workflows/flow-deploy-release-artifact.yaml b/.github/workflows/flow-deploy-release-artifact.yaml index c80a954e..777bd1f1 100644 --- a/.github/workflows/flow-deploy-release-artifact.yaml +++ b/.github/workflows/flow-deploy-release-artifact.yaml @@ -150,22 +150,21 @@ jobs: working-directory: ${{ env.PBJ_CORE }} run: ./gradlew assemble --scan - - name: Gradle Maven Central Release - if: ${{ needs.prepare-release.outputs.mode == 'specified' && !cancelled() && !failure() }} + - name: Gradle Release Maven Central + if: ${{ !cancelled() && !failure() }} working-directory: ${{ env.PBJ_CORE }} env: - OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} - GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }} - GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }} + NEXUS_USERNAME: ${{ secrets.OSSRH_USERNAME }} + NEXUS_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + # The 'releaseMavenCentral' task will select if Release or Snapshot based on the version run: | - ./gradlew release --no-parallel --scan -PpublishSigningEnabled=true \ - -Pgradle.publish.key=${GRADLE_PUBLISH_KEY} -Pgradle.publish.secret=${GRADLE_PUBLISH_SECRET} + ./gradlew releaseMavenCentral -PpublishingPackageGroup=com.hedera.pbj -PpublishSigningEnabled=true --no-configuration-cache --scan - - name: Gradle Maven Central Snapshot - if: ${{ needs.prepare-release.outputs.mode == 'snapshot' && !cancelled() && !failure() }} + - name: Gradle Plugin Portal Release + if: ${{ needs.prepare-release.outputs.mode == 'specified' && !cancelled() && !failure() }} working-directory: ${{ env.PBJ_CORE }} env: - OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} - run: ./gradlew releaseSnapshot --no-parallel --scan -PpublishSigningEnabled=true + GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }} + GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }} + run: | + ./gradlew publishPlugins -PpublishSigningEnabled=true --no-configuration-cache --scan diff --git a/.github/workflows/zxc-compile-pbj-code.yaml b/.github/workflows/zxc-compile-pbj-code.yaml index aec611ed..d7e57d37 100644 --- a/.github/workflows/zxc-compile-pbj-code.yaml +++ b/.github/workflows/zxc-compile-pbj-code.yaml @@ -126,15 +126,6 @@ jobs: # project-token: ${{ secrets.codacy-project-token }} # coverage-reports: ${{ env.PBJ_CORE }}/pbj-compiler/build/reports/jacoco/test/jacocoTestReport.xml, ${{ env.PBJ_CORE }}/pbj-runtime/build/reports/jacoco/test/jacocoTestReport.xml - - name: Gradle Maven Local (PBJ Core) - id: gradle-publish-local - uses: gradle/actions/setup-gradle@dbbdc275be76ac10734476cc723d82dfe7ec6eda # v3.4.2 - if: ${{ (inputs.enable-integration-tests || inputs.enable-jmh-tests) && steps.gradle-build.conclusion == 'success' && !cancelled() }} - with: - gradle-version: ${{ inputs.gradle-version }} - build-root-directory: ${{ env.PBJ_CORE }} - arguments: publishToMavenLocal --scan - - name: Gradle Assemble (PBJ Integration) id: gradle-integration-build uses: gradle/actions/setup-gradle@dbbdc275be76ac10734476cc723d82dfe7ec6eda # v3.4.2 diff --git a/pbj-core/build.gradle.kts b/pbj-core/build.gradle.kts deleted file mode 100644 index bd4c357a..00000000 --- a/pbj-core/build.gradle.kts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2022-2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id("com.hedera.pbj.root") -} diff --git a/pbj-core/gradle.properties b/pbj-core/gradle.properties index 88c7182e..c2605b94 100644 --- a/pbj-core/gradle.properties +++ b/pbj-core/gradle.properties @@ -1,13 +1,6 @@ -# Version number -version=0.9.13-SNAPSHOT +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 -# Need increased heap for running Gradle itself, or SonarQube will run the JVM out of metaspace -org.gradle.jvmargs=-Xmx2048m - -# Enable Gradle Caching +# Enable Gradle Caching and Parallelism org.gradle.caching=true - +org.gradle.configuration-cache=true org.gradle.parallel=true - -# Disable publish signing by default -publishSigningEnabled=false diff --git a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.helidon.gradle.kts b/pbj-core/gradle/aggregation/build.gradle.kts similarity index 66% rename from pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.helidon.gradle.kts rename to pbj-core/gradle/aggregation/build.gradle.kts index 6cad4fd9..dc9653a1 100644 --- a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.helidon.gradle.kts +++ b/pbj-core/gradle/aggregation/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,10 @@ */ plugins { - id("java-library") - id("com.hedera.pbj.conventions") + id("org.hiero.gradle.base.lifecycle") + id("org.hiero.gradle.report.code-coverage") + id("org.hiero.gradle.check.spotless") + id("org.hiero.gradle.check.spotless-kotlin") } -val maven = publishing.publications.create("maven") { from(components["java"]) } - -signing.sign(maven) +dependencies { implementation(project(":pbj-grpc-helidon")) } diff --git a/pbj-core/gradle/license-header.txt b/pbj-core/gradle/license-header.txt new file mode 100644 index 00000000..2e707c37 --- /dev/null +++ b/pbj-core/gradle/license-header.txt @@ -0,0 +1,13 @@ +Copyright (C) $YEAR Hedera Hashgraph, LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/pbj-core/gradle/modules.properties b/pbj-core/gradle/modules.properties deleted file mode 100644 index 0bedbc1a..00000000 --- a/pbj-core/gradle/modules.properties +++ /dev/null @@ -1,8 +0,0 @@ -com.google.protobuf=com.google.protobuf:protobuf-java -com.google.protobuf.util=com.google.protobuf:protobuf-java-util -io.grpc.netty=io.grpc:grpc-netty -io.grpc.protobuf=io.grpc:grpc-protobuf -io.grpc.stub=io.grpc:grpc-stub -java.annotation=javax.annotation:javax.annotation-api -io.helidon.codegen.apt=io.helidon.codegen:helidon-codegen-apt -io.helidon.builder.codegen=io.helidon.builder:helidon-builder-codegen diff --git a/pbj-core/gradle/plugins/build.gradle.kts b/pbj-core/gradle/plugins/build.gradle.kts deleted file mode 100644 index 6041c61c..00000000 --- a/pbj-core/gradle/plugins/build.gradle.kts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2023-2024 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { `kotlin-dsl` } - -repositories { gradlePluginPortal() } - -dependencies { - implementation("com.adarshr:gradle-test-logger-plugin:4.0.0") - implementation("com.autonomousapps:dependency-analysis-gradle-plugin:1.29.0") - implementation("com.diffplug.spotless:spotless-plugin-gradle:6.25.0") - implementation("com.google.protobuf:protobuf-gradle-plugin:0.9.4") - implementation("com.gradle.publish:plugin-publish-plugin:1.2.1") - implementation("gradle.plugin.lazy.zoo.gradle:git-data-plugin:1.2.2") - implementation("io.github.gradle-nexus:publish-plugin:1.3.0") - implementation("me.champeau.jmh:jmh-gradle-plugin:0.7.2") - implementation("net.swiftzer.semver:semver:1.3.0") - implementation("org.gradlex:java-module-dependencies:1.6.6") -} diff --git a/pbj-core/gradle/plugins/src/main/kotlin/Utils.kt b/pbj-core/gradle/plugins/src/main/kotlin/Utils.kt deleted file mode 100644 index 0d3d1087..00000000 --- a/pbj-core/gradle/plugins/src/main/kotlin/Utils.kt +++ /dev/null @@ -1,83 +0,0 @@ -import net.swiftzer.semver.SemVer -import org.gradle.api.Project -import java.io.File -import java.io.OutputStream -import java.io.PrintStream - -/* - * Copyright (C) 2022 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -class Utils { - companion object { - @JvmStatic - fun updateVersion(project: Project, newVersion: SemVer) { - val gradlePropFile = File(project.projectDir, "gradle.properties") - var lines: List = mutableListOf() - - if (gradlePropFile.exists()) { - lines = gradlePropFile.readLines(Charsets.UTF_8) - } - - var versionStr = "version=${newVersion.toString()}" - val finalLines: List - - - if (lines.isNotEmpty()) { - finalLines = lines.map { - if (it.trimStart().startsWith("version=")) { - versionStr - } else { - it - } - } - } else { - finalLines = listOf(versionStr) - } - - - gradlePropFile.bufferedWriter(Charsets.UTF_8).use { - val writer = it - finalLines.forEach { - writer.write(it) - writer.newLine() - } - writer.flush() - } - } - - @JvmStatic - fun generateProjectVersionReport(rootProject: Project, ostream: OutputStream) { - val writer = PrintStream(ostream, false, Charsets.UTF_8) - - ostream.use { - writer.use { - // Writer headers - writer.println("### Deployed Version Information") - writer.println() - writer.println("| Artifact Name | Version Number |") - writer.println("| --- | --- |") - - // Write table rows - rootProject.childProjects.values.onEach { - writer.printf("| %s | %s |\n", it.name, it.version.toString()) - } - writer.flush() - ostream.flush() - } - } - } - } -} diff --git a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.aggregate-reports.gradle.kts b/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.aggregate-reports.gradle.kts deleted file mode 100644 index 24347792..00000000 --- a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.aggregate-reports.gradle.kts +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2022-2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.io.BufferedOutputStream -import net.swiftzer.semver.SemVer - -plugins { id("lazy.zoo.gradle.git-data-plugin") } - -tasks.register("githubVersionSummary") { - group = "github" - doLast { - val ghStepSummaryPath: String = - System.getenv("GITHUB_STEP_SUMMARY") - ?: throw IllegalArgumentException( - "This task may only be run in a Github Actions CI environment! Unable to locate the GITHUB_STEP_SUMMARY environment variable." - ) - - val ghStepSummaryFile = File(ghStepSummaryPath) - Utils.generateProjectVersionReport( - rootProject, - BufferedOutputStream(ghStepSummaryFile.outputStream()) - ) - } -} - -tasks.register("showVersion") { - group = "versioning" - doLast { println(project.version) } -} - -tasks.register("versionAsPrefixedCommit") { - group = "versioning" - doLast { - gitData.lastCommitHash?.let { - val prefix = findProperty("commitPrefix")?.toString() ?: "adhoc" - val newPrerel = prefix + ".x" + it.take(8) - val currVer = SemVer.parse(project.version.toString()) - try { - val newVer = SemVer(currVer.major, currVer.minor, currVer.patch, newPrerel) - Utils.updateVersion(project, newVer) - } catch (e: java.lang.IllegalArgumentException) { - throw IllegalArgumentException(String.format("%s: %s", e.message, newPrerel), e) - } - } - } -} - -tasks.register("versionAsSnapshot") { - group = "versioning" - doLast { - val currVer = SemVer.parse(project.version.toString()) - val newVer = SemVer(currVer.major, currVer.minor, currVer.patch, "SNAPSHOT") - - Utils.updateVersion(project, newVer) - } -} - -tasks.register("versionAsSpecified") { - group = "versioning" - doLast { - val verStr = - providers.gradleProperty("newVersion").orNull - ?: throw IllegalArgumentException( - "No newVersion property provided! Please add the parameter -PnewVersion= when running this task." - ) - - val newVer = SemVer.parse(verStr) - Utils.updateVersion(project, newVer) - } -} diff --git a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.conventions.gradle.kts b/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.conventions.gradle.kts deleted file mode 100644 index 6487e31e..00000000 --- a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.conventions.gradle.kts +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.adarshr.gradle.testlogger.theme.ThemeType - -plugins { - id("java") - id("jacoco") - id("antlr") - id("org.gradlex.java-module-dependencies") - id("com.adarshr.test-logger") - id("com.hedera.pbj.repositories") - id("com.hedera.pbj.spotless-conventions") - id("com.hedera.pbj.spotless-java-conventions") - id("com.hedera.pbj.spotless-kotlin-conventions") - id("com.hedera.pbj.maven-publish") -} - -group = "com.hedera.pbj" - -java { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 - toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) - vendor.set(JvmVendorSpec.ADOPTIUM) - } - - // Enable JAR file generation required for publishing - withJavadocJar() - withSourcesJar() -} - -testing { - @Suppress("UnstableApiUsage") suites.getByName("test") { useJUnitJupiter() } -} - -tasks.withType { - isPreserveFileTimestamps = false - isReproducibleFileOrder = true - fileMode = 436 // octal: 0664 - dirMode = 509 // octal: 0775 -} - -tasks.withType { options.encoding = "UTF-8" } - -tasks.withType { - options.encoding = "UTF-8" - (options as StandardJavadocDocletOptions).tags( - "apiNote:a:API Note:", - "implSpec:a:Implementation Requirements:", - "implNote:a:Implementation Note:" - ) -} - -testlogger { - theme = ThemeType.MOCHA - slowThreshold = 10000 - showStandardStreams = true - showPassedStandardStreams = false - showSkippedStandardStreams = false - showFailedStandardStreams = true -} - -val libs = the().named("libs") - -configurations { - // Treat the ANTLR compiler as a separate tool that should not end up on the compile/runtime - // classpath of our runtime. - // https://github.com/gradle/gradle/issues/820 - api { setExtendsFrom(extendsFrom.filterNot { it == antlr.get() }) } -} - -dependencies { - antlr("org.antlr:antlr4") { - version { require(libs.findVersion("org.antlr.antlr4.runtime").get().requiredVersion) } - } -} - -// See: https://github.com/gradle/gradle/issues/25885 -tasks.named("sourcesJar") { dependsOn(tasks.generateGrammarSource) } - -tasks.withType().configureEach { - dependsOn(tasks.withType()) -} - -// Ensure JaCoCo coverage is generated and aggregated -tasks.jacocoTestReport.configure { - reports { - xml.required.set(true) - html.required.set(true) - } - - val testExtension = tasks.test.get().extensions.getByType() - executionData.setFrom(testExtension.destinationFile) - - shouldRunAfter(tasks.named("check")) -} - -// Ensure the check task also runs the JaCoCo coverage report -tasks.named("check").configure { dependsOn(tasks.named("jacocoTestReport")) } diff --git a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.gradle-plugin.gradle.kts b/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.gradle-plugin.gradle.kts deleted file mode 100644 index 34218a22..00000000 --- a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.gradle-plugin.gradle.kts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.autonomousapps.DependencyAnalysisSubExtension - -plugins { - id("com.hedera.pbj.conventions") - id("com.gradle.plugin-publish") -} - -tasks.generateGrammarSource { - arguments = arguments + listOf("-package", "com.hedera.pbj.compiler.impl.grammar") -} - -// Do not generate Java Doc for generated antlr grammar -tasks.withType { excludes.add("com/hedera/pbj/compiler/impl/grammar/**") } - -tasks.register("release") { - group = "release" - dependsOn(tasks.named("publishPlugins")) -} - -// As a Gradle plugin cannot be a Java Module, we do not have official internal packages. -// We tell the dependency analysis to treat packages as "internal". -configure() { abi { exclusions { ignoreSubPackage("impl") } } } diff --git a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.maven-publish.gradle.kts b/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.maven-publish.gradle.kts deleted file mode 100644 index 5cacbdc2..00000000 --- a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.maven-publish.gradle.kts +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2022-2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id("java") - id("maven-publish") - id("signing") -} - -publishing { - publications.withType().configureEach { - pom { - packaging = findProperty("maven.project.packaging")?.toString() ?: "jar" - name.set(project.name) - url.set("https://www.hedera.com/") - inceptionYear.set("2022") - - description.set( - "A high performance Google Protocol Buffers parser, code generator, and runtime library." - ) - - organization { - name.set("Hedera Hashgraph, LLC") - url.set("https://www.hedera.com") - } - - licenses { - license { - name.set("Apache 2.0 License") - url.set("https://raw.githubusercontent.com/hashgraph/pbj/main/LICENSE") - } - } - - developers { - developer { - name.set("Jasper Potts") - email.set("jasper.potts@swirldslabs.com") - organization.set("Swirlds Labs, Inc.") - organizationUrl.set("https://www.swirldslabs.com") - } - } - - scm { - connection.set("scm:git:git://github.com/hashgraph/pbj.git") - developerConnection.set("scm:git:ssh://github.com:hashgraph/pbj.git") - url.set("https://github.com/hashgraph/pbj") - } - } - } -} - -signing { useGpgCmd() } - -tasks.withType { - onlyIf { providers.gradleProperty("publishSigningEnabled").getOrElse("false").toBoolean() } -} diff --git a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.protoc.gradle.kts b/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.protoc.gradle.kts deleted file mode 100644 index b7893882..00000000 --- a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.protoc.gradle.kts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { id("com.google.protobuf") } - -protobuf { - // Configure the protoc executable - protoc { - // Download from repositories - artifact = "com.google.protobuf:protoc:4.28.2" - } - plugins { - create("grpc") { - artifact = "io.grpc:protoc-gen-grpc-java:1.65.1" - } - } - - generateProtoTasks { - all().forEach { - it.plugins { - create("grpc") - } - } - } -} diff --git a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.repositories.gradle.kts b/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.repositories.gradle.kts deleted file mode 100644 index ac4586a4..00000000 --- a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.repositories.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (C) 2022-2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -repositories { mavenCentral() } diff --git a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.root.gradle.kts b/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.root.gradle.kts deleted file mode 100644 index 4884da2f..00000000 --- a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.root.gradle.kts +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import io.github.gradlenexus.publishplugin.CloseNexusStagingRepository - -plugins { - id("com.hedera.pbj.repositories") - id("com.hedera.pbj.aggregate-reports") - id("com.hedera.pbj.spotless-conventions") - id("com.hedera.pbj.spotless-kotlin-conventions") - id("com.autonomousapps.dependency-analysis") - id("io.github.gradle-nexus.publish-plugin") -} - -group = "com.hedera.pbj" - -spotless { kotlinGradle { target("buildSrc/**/*.gradle.kts") } } - -nexusPublishing { - repositories { - sonatype { - username = System.getenv("OSSRH_USERNAME") - password = System.getenv("OSSRH_PASSWORD") - } - } -} - -tasks.withType { - // The publishing of all components to Maven Central (in this case only 'pbj-runtime') is - // automatically done before close (which is done before release). - dependsOn(":pbj-runtime:publishToSonatype") - dependsOn(":pbj-grpc-helidon:publishToSonatype") - dependsOn(":pbj-grpc-helidon-config:publishToSonatype") -} - -tasks.register("release") { - group = "release" - dependsOn(tasks.closeAndReleaseStagingRepository) -} - -tasks.register("releaseSnapshot") { - group = "release" - dependsOn(":pbj-runtime:publishToSonatype") - dependsOn(":pbj-grpc-helidon:publishToSonatype") - dependsOn(":pbj-grpc-helidon-config:publishToSonatype") -} diff --git a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.runtime.gradle.kts b/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.runtime.gradle.kts deleted file mode 100644 index aaba1944..00000000 --- a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.runtime.gradle.kts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id("java-library") - id("com.hedera.pbj.conventions") - id("com.hedera.pbj.protoc") // protobuf plugin is only used for tests - id("me.champeau.jmh") -} - -tasks.generateGrammarSource { - arguments = arguments + listOf("-package", "com.hedera.pbj.runtime.jsonparser") -} - -val maven = publishing.publications.create("maven") { from(components["java"]) } - -signing.sign(maven) - -// Filter JMH benchmarks for testing -//jmh { -// includes.add("WriteBytesBench") -// includes.add("WriteBufferedDataBench") -//} diff --git a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.spotless-conventions.gradle.kts b/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.spotless-conventions.gradle.kts deleted file mode 100644 index f40e9dd2..00000000 --- a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.spotless-conventions.gradle.kts +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2022-2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { id("com.diffplug.spotless") } - -spotless { - // Disable strong enforcement during gradle check tasks - isEnforceCheck = false - - // optional: limit format enforcement to just the files changed by this feature branch - ratchetFrom("origin/main") - - format("misc") { - // define the files to apply `misc` to - target("*.gradle", "*.md", ".gitignore") - - // define the steps to apply to those files - trimTrailingWhitespace() - indentWithSpaces() - endWithNewline() - } - - format("actionYaml") { - target(".github/workflows/*.yaml") - /* - * Prettier requires NodeJS and NPM installed; however, the NodeJS Gradle plugin and Spotless do not yet - * integrate with each other. Currently there is an open issue report against spotless. - * - * *** Please see for more information: https://github.com/diffplug/spotless/issues/728 *** - * - * The workaround provided in the above issue does not work in Gradle 7.5+ and therefore is not a viable solution. - */ - // prettier() - - trimTrailingWhitespace() - indentWithSpaces() - endWithNewline() - - licenseHeader( - """ - ## - # Copyright (C) ${'$'}YEAR Hedera Hashgraph, LLC - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - ## - """ - .trimIndent(), - "(name|on)" - ) - } -} diff --git a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.spotless-java-conventions.gradle.kts b/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.spotless-java-conventions.gradle.kts deleted file mode 100644 index ae83aed1..00000000 --- a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.spotless-java-conventions.gradle.kts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2022-2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { id("com.diffplug.spotless") } - -spotless { - java { - targetExclude("build/generated/sources/**/*.java") - // enable toggle comment support - toggleOffOn() - // don't need to set target, it is inferred from java - // apply a specific flavor of google-java-format - googleJavaFormat("1.17.0").aosp().reflowLongStrings() - // make sure every file has the following copyright header. - // optionally, Spotless can set copyright years by digging - // through git history (see "license" section below). - // The delimiter override below is required to support some - // of our test classes which are in the default package. - licenseHeader( - """ - /* - * Copyright (C) ${'$'}YEAR Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */${"\n\n"} - """ - .trimIndent(), - "(package|import)" - ) - } -} diff --git a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.spotless-kotlin-conventions.gradle.kts b/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.spotless-kotlin-conventions.gradle.kts deleted file mode 100644 index ef2755ec..00000000 --- a/pbj-core/gradle/plugins/src/main/kotlin/com.hedera.pbj.spotless-kotlin-conventions.gradle.kts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2022-2023 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { id("com.diffplug.spotless") } - -spotless { - kotlinGradle { - ktfmt().kotlinlangStyle() - - licenseHeader( - """ - /* - * Copyright (C) ${'$'}YEAR Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */${"\n\n"} - """ - .trimIndent(), - "(import|plugins|repositories)", - ) - } -} diff --git a/pbj-core/gradle/toolchain-versions.properties b/pbj-core/gradle/toolchain-versions.properties new file mode 100644 index 00000000..04e458fa --- /dev/null +++ b/pbj-core/gradle/toolchain-versions.properties @@ -0,0 +1 @@ +jdk=21.0.4 diff --git a/pbj-core/gradle/wrapper/gradle-wrapper.jar b/pbj-core/gradle/wrapper/gradle-wrapper.jar index 7f93135c..a4b76b95 100644 Binary files a/pbj-core/gradle/wrapper/gradle-wrapper.jar and b/pbj-core/gradle/wrapper/gradle-wrapper.jar differ diff --git a/pbj-core/gradle/wrapper/gradle-wrapper.properties b/pbj-core/gradle/wrapper/gradle-wrapper.properties index a4413138..cea7a793 100644 --- a/pbj-core/gradle/wrapper/gradle-wrapper.properties +++ b/pbj-core/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/pbj-core/gradlew b/pbj-core/gradlew index 0adc8e1a..f3b75f3b 100755 --- a/pbj-core/gradlew +++ b/pbj-core/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# 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/. @@ -84,7 +86,7 @@ done # 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 "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +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 @@ -145,7 +147,7 @@ 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=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -153,7 +155,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -202,11 +204,11 @@ fi # 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"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_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" \ diff --git a/pbj-core/gradlew.bat b/pbj-core/gradlew.bat index 6689b85b..9b42019c 100644 --- a/pbj-core/gradlew.bat +++ b/pbj-core/gradlew.bat @@ -13,6 +13,8 @@ @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 @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 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 @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe 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 diff --git a/pbj-core/hiero-dependency-versions/build.gradle.kts b/pbj-core/hiero-dependency-versions/build.gradle.kts new file mode 100644 index 00000000..4be27461 --- /dev/null +++ b/pbj-core/hiero-dependency-versions/build.gradle.kts @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id("org.hiero.gradle.base.lifecycle") + id("org.hiero.gradle.base.jpms-modules") + id("org.hiero.gradle.check.spotless") + id("org.hiero.gradle.check.spotless-kotlin") +} + +group = "com.hedera.hashgraph" + +val antlr = "4.11.1" +val grpc = "1.65.1" +val helidon = "4.1.6" +val protobuf = "4.28.2" + +val junit5 = "5.8.2" +val mockito = "5.10.0" + +dependencies.constraints { + api("org.antlr:antlr4-runtime:$antlr") { because("org.antlr.antlr4.runtime") } + api("com.github.spotbugs:spotbugs-annotations:4.8.6") { + because("com.github.spotbugs.annotations") + } + + // The libs of this catalog are used to compile but are not bundled. The user will select + // helidon, which will have the set of these dependencies that are required. + api("io.helidon.webserver:helidon-webserver:$helidon") { because("io.helidon.webserver") } + api("io.helidon.webserver:helidon-webserver-http2:$helidon") { + because("io.helidon.webserver.http2") + } + api("io.helidon.metrics:helidon-metrics-api:$helidon") { because("io.helidon.metrics.api") } + api("io.helidon.common.features:helidon-common-features-api:$helidon") { + because("io.helidon.common.features.api") + } + + // Annotation processing + api("io.helidon.common.features:helidon-common-features-processor:$helidon") { + because("io.helidon.common.features.processor") + } + api("io.helidon.config:helidon-config-metadata-processor:$helidon") { + because("io.helidon.config.metadata.processor") + } + api("io.helidon.codegen:helidon-codegen-apt:$helidon") { because("io.helidon.codegen.apt") } + api("io.helidon.builder:helidon-builder-codegen:$helidon") { + because("io.helidon.builder.codegen") + } + + // Code generation + api("org.antlr:antlr4:$antlr") + api("com.google.protobuf:protoc:$protobuf") + api("io.grpc:protoc-gen-grpc-java:1.66.0") + + // Testing only + api("com.google.guava:guava:33.3.1-jre") { because("com.google.common") } + api("com.google.protobuf:protobuf-java:$protobuf") { because("com.google.protobuf") } + api("com.google.protobuf:protobuf-java-util:$protobuf") { because("com.google.protobuf.util") } + api("org.assertj:assertj-core:3.23.1") { because("org.assertj.core") } + api("org.junit.jupiter:junit-jupiter-api:$junit5") { because("org.junit.jupiter.api") } + api("org.junit.jupiter:junit-jupiter-engine:$junit5") { because("org.junit.jupiter.engine") } + + api("org.mockito:mockito-core:$mockito") { because("org.mockito") } + api("org.mockito:mockito-junit-jupiter:$mockito") { because("org.mockito.junit.jupiter") } + api("io.grpc:grpc-netty:$grpc") { because("io.grpc.netty") } + api("io.grpc:grpc-protobuf:$grpc") { because("io.grpc.protobuf") } + api("io.grpc:grpc-stub:$grpc") { because("io.grpc.stub") } + + api("io.helidon.webserver.observe:helidon-webserver-observe-metrics:$helidon") { + because("io.helidon.webserver.observe.metrics") + } + api("io.helidon.webclient:helidon-webclient:$helidon") { because("io.helidon.webclient") } + api("io.helidon.webclient:helidon-webclient-http2:$helidon") { + because("io.helidon.webclient.http2") + } +} diff --git a/pbj-core/pbj-compiler/build.gradle.kts b/pbj-core/pbj-compiler/build.gradle.kts index 7ecc2d8a..8c3c6b70 100644 --- a/pbj-core/pbj-compiler/build.gradle.kts +++ b/pbj-core/pbj-compiler/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC + * Copyright (C) 2022-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,15 @@ * limitations under the License. */ -plugins { id("com.hedera.pbj.gradle-plugin") } +plugins { + id("org.hiero.gradle.module.gradle-plugin") + id("org.hiero.gradle.feature.antlr") +} + +description = "The PBJ Protobuf plugin provides protobuf compilation to java records." + +// Address warnings and remove this exception +tasks.compileJava { options.compilerArgs.add("-Xlint:-text-blocks") } // This project does not have a module-info.java, as Gradle does not support plugins that are // Java Modules. For consistency, we still defined dependencies in terms of Module Names here. @@ -36,10 +44,22 @@ gradlePlugin { group = "com.hedera.pbj" implementationClass = "com.hedera.pbj.compiler.PbjCompilerPlugin" displayName = "PBJ Compiler" - description = "The PBJ Protobuf plugin provides protobuf compilation to java records." + description = project.description website = "https://github.com/hashgraph/pbj" vcsUrl = "https://github.com/hashgraph/pbj" tags.set(listOf("protobuf", "compiler", "generator", "runtime")) } } } + +// Define package name for code generated by ANTLR +tasks.generateGrammarSource { + arguments = arguments + listOf("-package", "com.hedera.pbj.compiler.impl.grammar") +} + +// Do not generate Java Doc for generated antlr grammar +tasks.javadoc { excludes.add("com/hedera/pbj/compiler/impl/grammar/**") } + +// As a Gradle plugin cannot be a Java Module, we do not have official internal packages. +// We tell the dependency analysis to treat packages as "internal". +dependencyAnalysis { abi { exclusions { ignoreSubPackage("impl") } } } diff --git a/pbj-core/pbj-compiler/src/main/java/com/hedera/pbj/compiler/PbjCompiler.java b/pbj-core/pbj-compiler/src/main/java/com/hedera/pbj/compiler/PbjCompiler.java new file mode 100644 index 00000000..3ffadb62 --- /dev/null +++ b/pbj-core/pbj-compiler/src/main/java/com/hedera/pbj/compiler/PbjCompiler.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.pbj.compiler; + +import com.hedera.pbj.compiler.impl.ContextualLookupHelper; +import com.hedera.pbj.compiler.impl.LookupHelper; +import com.hedera.pbj.compiler.impl.generators.EnumGenerator; +import com.hedera.pbj.compiler.impl.generators.Generator; +import com.hedera.pbj.compiler.impl.grammar.Protobuf3Lexer; +import com.hedera.pbj.compiler.impl.grammar.Protobuf3Parser; +import java.io.File; +import java.io.FileInputStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CommonTokenStream; + +/** Compiler entry point to generate java src code from protobuf proto schema files. */ +public abstract class PbjCompiler { + private static final int MAX_TRACE_FRAMES = 8; + private static final String STACK_ELEMENT_INDENT = " "; + + public static void compileFilesIn(Iterable sourceFiles, File mainOutputDir, File testOutputDir) + throws Exception { + // first we do a scan of files to build lookup tables for imports, packages etc. + final LookupHelper lookupHelper = new LookupHelper(sourceFiles); + // for each proto src directory generate code + for (final File protoFile : sourceFiles) { + if (protoFile.exists() + && protoFile.isFile() + && protoFile.getName().endsWith(LookupHelper.PROTO_EXTENSIION)) { + final ContextualLookupHelper contextualLookupHelper = + new ContextualLookupHelper(lookupHelper, protoFile); + try (final var input = new FileInputStream(protoFile)) { + final var lexer = new Protobuf3Lexer(CharStreams.fromStream(input)); + final var parser = new Protobuf3Parser(new CommonTokenStream(lexer)); + final Protobuf3Parser.ProtoContext parsedDoc = parser.proto(); + for (final var topLevelDef : parsedDoc.topLevelDef()) { + final Protobuf3Parser.MessageDefContext msgDef = topLevelDef.messageDef(); + if (msgDef != null) { + // run all generators for message + for (final var generatorClass : Generator.GENERATORS) { + final var generator = + generatorClass.getDeclaredConstructor().newInstance(); + generator.generate(msgDef, mainOutputDir, testOutputDir, contextualLookupHelper); + } + } + final Protobuf3Parser.EnumDefContext enumDef = topLevelDef.enumDef(); + if (enumDef != null) { + // run just enum generators for enum + EnumGenerator.generateEnumFile(enumDef, mainOutputDir, contextualLookupHelper); + } + } + } catch (Exception e) { + System.err.println("Exception while processing file: " + protoFile); + // Print an abbreviated stack trace for help in debugging. + System.err.println(e); + var trace = e.getStackTrace(); + int count = 0; + for (var element : trace) { + if (count++ < MAX_TRACE_FRAMES) System.err.println(STACK_ELEMENT_INDENT + element); + } + throw e; + } + } + } + } +} diff --git a/pbj-core/pbj-compiler/src/main/java/com/hedera/pbj/compiler/PbjCompilerTask.java b/pbj-core/pbj-compiler/src/main/java/com/hedera/pbj/compiler/PbjCompilerTask.java index 47a684af..f82e3c74 100644 --- a/pbj-core/pbj-compiler/src/main/java/com/hedera/pbj/compiler/PbjCompilerTask.java +++ b/pbj-core/pbj-compiler/src/main/java/com/hedera/pbj/compiler/PbjCompilerTask.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Hedera Hashgraph, LLC + * Copyright (C) 2023-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,17 +16,7 @@ package com.hedera.pbj.compiler; -import com.hedera.pbj.compiler.impl.ContextualLookupHelper; -import com.hedera.pbj.compiler.impl.LookupHelper; -import com.hedera.pbj.compiler.impl.generators.EnumGenerator; -import com.hedera.pbj.compiler.impl.generators.Generator; -import com.hedera.pbj.compiler.impl.grammar.Protobuf3Lexer; -import com.hedera.pbj.compiler.impl.grammar.Protobuf3Parser; -import java.io.File; -import java.io.FileInputStream; import javax.inject.Inject; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; import org.gradle.api.file.DirectoryProperty; import org.gradle.api.internal.file.FileOperations; import org.gradle.api.tasks.OutputDirectory; @@ -35,8 +25,6 @@ /** Gradle Task that generates java src code from protobuf proto schema files. */ public abstract class PbjCompilerTask extends SourceTask { - private static final int MAX_TRACE_FRAMES = 8; - private static final String STACK_ELEMENT_INDENT = " "; /** * Set the java main directory that we write generated code into @@ -69,69 +57,9 @@ public abstract class PbjCompilerTask extends SourceTask { public void perform() throws Exception { // Clean output directories getFileOperations().delete(getJavaMainOutputDirectory(), getJavaTestOutputDirectory()); - compileFilesIn(getSource(), + PbjCompiler.compileFilesIn( + getSource(), getJavaMainOutputDirectory().get().getAsFile(), getJavaTestOutputDirectory().get().getAsFile()); } - - /** - * Compile all the proto files in the given source directories - * @param sourceFiles The source files to compile - * @param mainOutputDir The main output directory - * @param testOutputDir The test output directory - */ - - public static void compileFilesIn(Iterable sourceFiles, - File mainOutputDir, - File testOutputDir) throws Exception { - // first we do a scan of files to build lookup tables for imports, packages etc. - final LookupHelper lookupHelper = new LookupHelper(sourceFiles); - // for each proto src directory generate code - for (final File protoFile : sourceFiles) { - if (protoFile.exists() - && protoFile.isFile() - && protoFile.getName().endsWith(LookupHelper.PROTO_EXTENSIION)) { - final ContextualLookupHelper contextualLookupHelper = - new ContextualLookupHelper(lookupHelper, protoFile); - try (final var input = new FileInputStream(protoFile)) { - final var lexer = new Protobuf3Lexer(CharStreams.fromStream(input)); - final var parser = new Protobuf3Parser(new CommonTokenStream(lexer)); - final Protobuf3Parser.ProtoContext parsedDoc = parser.proto(); - for (final var topLevelDef : parsedDoc.topLevelDef()) { - final Protobuf3Parser.MessageDefContext msgDef = topLevelDef.messageDef(); - if (msgDef != null) { - // run all generators for message - for (final var generatorClass : Generator.GENERATORS) { - final var generator = - generatorClass.getDeclaredConstructor().newInstance(); - generator.generate( - msgDef, - mainOutputDir, - testOutputDir, - contextualLookupHelper); - } - } - final Protobuf3Parser.EnumDefContext enumDef = topLevelDef.enumDef(); - if (enumDef != null) { - // run just enum generators for enum - EnumGenerator.generateEnumFile( - enumDef, - mainOutputDir, - contextualLookupHelper); - } - } - } catch (Exception e) { - System.err.println("Exception while processing file: " + protoFile); - // Print an abbreviated stack trace for help in debugging. - System.err.println(e); - var trace = e.getStackTrace(); - int count = 0; - for (var element : trace) { - if (count++ < MAX_TRACE_FRAMES) System.err.println(STACK_ELEMENT_INDENT + element); - } - throw e; - } - } - } - } } diff --git a/pbj-core/pbj-grpc-helidon-config/build.gradle.kts b/pbj-core/pbj-grpc-helidon-config/build.gradle.kts index 520efc6b..3fdfb3ce 100644 --- a/pbj-core/pbj-grpc-helidon-config/build.gradle.kts +++ b/pbj-core/pbj-grpc-helidon-config/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC + * Copyright (C) 2022-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,12 @@ * limitations under the License. */ -plugins { id("com.hedera.pbj.helidon") } +plugins { id("org.hiero.gradle.module.library") } + +description = "Configuration for a Helidon gRPC plugin for PBJ" + +// TODO fix warning 'helidon-config-metadata-processor is deprecated' and remove this +tasks.compileJava { options.compilerArgs.remove("-Werror") } mainModuleInfo { annotationProcessor("io.helidon.common.features.processor") @@ -22,11 +27,3 @@ mainModuleInfo { annotationProcessor("io.helidon.codegen.apt") annotationProcessor("io.helidon.builder.codegen") } - -tasks.named("javadoc").configure { enabled = false } - -publishing { - publications.withType().configureEach { - pom { description.set("Configuration for a Helidon gRPC plugin for PBJ") } - } -} diff --git a/pbj-core/pbj-grpc-helidon-config/src/main/java/module-info.java b/pbj-core/pbj-grpc-helidon-config/src/main/java/module-info.java index 1ad9b4fe..55b08999 100644 --- a/pbj-core/pbj-grpc-helidon-config/src/main/java/module-info.java +++ b/pbj-core/pbj-grpc-helidon-config/src/main/java/module-info.java @@ -8,10 +8,10 @@ description = "WebServer gRPC-PBJ Config", in = HelidonFlavor.SE, path = {"WebServer", "PBJ"}) -@SuppressWarnings({"requires-automatic"}) module com.hedera.pbj.grpc.helidon.config { - requires com.hedera.pbj.runtime; - requires io.helidon.webserver.http2; + requires transitive io.helidon.builder.api; + requires transitive io.helidon.common.config; + requires transitive io.helidon.common; requires io.helidon.webserver; requires static io.helidon.common.features.api; requires static io.helidon.common.features.processor; diff --git a/pbj-core/pbj-grpc-helidon/build.gradle.kts b/pbj-core/pbj-grpc-helidon/build.gradle.kts index 596bc589..0dfaa0db 100644 --- a/pbj-core/pbj-grpc-helidon/build.gradle.kts +++ b/pbj-core/pbj-grpc-helidon/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC + * Copyright (C) 2022-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,12 @@ */ plugins { - id("com.hedera.pbj.helidon") - id("com.hedera.pbj.protoc") // protobuf plugin is only used for tests + id("org.hiero.gradle.module.library") + id("org.hiero.gradle.feature.protobuf") // protobuf plugin is only used for tests } +description = "A Helidon gRPC plugin with PBJ" + // These annotation processors are used to generate config and other files that Helidon needs mainModuleInfo { annotationProcessor("io.helidon.common.features.processor") @@ -27,26 +29,23 @@ mainModuleInfo { } testModuleInfo { - requires("org.assertj.core") - requires("org.junit.jupiter.api") - requires("org.junit.jupiter.params") - requires("io.helidon.webclient") - requires("io.helidon.webserver") - requires("io.helidon.webserver.http2") - requires("io.helidon.webserver.observe.metrics") - requires("io.helidon.webclient.http2") + requires("com.google.common") + requires("com.google.protobuf") requires("com.google.protobuf.util") + requires("io.grpc") requires("io.grpc.protobuf") - requires("io.grpc.netty") requires("io.grpc.stub") + requires("io.helidon.http.media") + requires("io.helidon.webclient.api") + requires("io.helidon.webclient.http2") + requires("io.netty.codec.http2") + requires("org.assertj.core") + requires("org.junit.jupiter.api") + requires("org.junit.jupiter.params") requiresStatic("com.github.spotbugs.annotations") requiresStatic("java.annotation") + runtimeOnly("io.grpc.netty") + runtimeOnly("io.helidon.webserver.observe.metrics") } -tasks.named("compileJava") { dependsOn(":pbj-runtime:jar") } - -publishing { - publications.withType().configureEach { - pom { description.set("A Helidon gRPC plugin with PBJ") } - } -} +tasks.named("compileJava") { dependsOn(":pbj-runtime:jar") } // FIXME !!! diff --git a/pbj-core/pbj-grpc-helidon/src/main/java/module-info.java b/pbj-core/pbj-grpc-helidon/src/main/java/module-info.java index bbf8121a..fbfc5a0f 100644 --- a/pbj-core/pbj-grpc-helidon/src/main/java/module-info.java +++ b/pbj-core/pbj-grpc-helidon/src/main/java/module-info.java @@ -9,19 +9,25 @@ description = "WebServer gRPC-PBJ Support", in = HelidonFlavor.SE, path = {"WebServer", "PBJ"}) -@SuppressWarnings({"requires-automatic"}) module com.hedera.pbj.grpc.helidon { - requires static io.helidon.common.features.api; - requires static com.github.spotbugs.annotations; - requires static io.helidon.common.features.processor; - requires static io.helidon.codegen.apt; - requires static io.helidon.builder.codegen; - requires com.hedera.pbj.grpc.helidon.config; - requires com.hedera.pbj.runtime; - requires io.helidon.webserver; - requires io.helidon.webserver.http2; + requires transitive com.hedera.pbj.grpc.helidon.config; + requires transitive com.hedera.pbj.runtime; + requires transitive io.helidon.common.config; + requires transitive io.helidon.common; + requires transitive io.helidon.webserver.http2; + requires transitive io.helidon.webserver; + requires io.helidon.common.buffers; + requires io.helidon.common.media.type; + requires io.helidon.common.uri; + requires io.helidon.http.http2; + requires io.helidon.http; requires io.helidon.metrics.api; requires java.net.http; + requires static transitive com.github.spotbugs.annotations; + requires static io.helidon.builder.codegen; + requires static io.helidon.codegen.apt; + requires static io.helidon.common.features.api; + requires static io.helidon.common.features.processor; exports com.hedera.pbj.grpc.helidon; diff --git a/pbj-core/pbj-runtime/build.gradle.kts b/pbj-core/pbj-runtime/build.gradle.kts index e65bc024..89f9a51e 100644 --- a/pbj-core/pbj-runtime/build.gradle.kts +++ b/pbj-core/pbj-runtime/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC + * Copyright (C) 2022-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,15 @@ * limitations under the License. */ -plugins { id("com.hedera.pbj.runtime") } +plugins { + id("org.hiero.gradle.module.library") + id("org.hiero.gradle.feature.antlr") + id("org.hiero.gradle.feature.protobuf") // protobuf is only used for tests + id("org.hiero.gradle.feature.benchmark") +} + +description = + "A high performance Google Protocol Buffers parser, code generator, and runtime library." testModuleInfo { requires("com.google.protobuf") @@ -26,3 +34,8 @@ testModuleInfo { requires("org.mockito.junit.jupiter") requiresStatic("com.github.spotbugs.annotations") } + +// Define package name for code generated by ANTLR +tasks.generateGrammarSource { + arguments = arguments + listOf("-package", "com.hedera.pbj.runtime.jsonparser") +} diff --git a/pbj-core/pbj-runtime/src/main/java/module-info.java b/pbj-core/pbj-runtime/src/main/java/module-info.java index 73d414e8..b3229ff7 100644 --- a/pbj-core/pbj-runtime/src/main/java/module-info.java +++ b/pbj-core/pbj-runtime/src/main/java/module-info.java @@ -1,10 +1,8 @@ /** Runtime module of code needed by PBJ generated code at runtime. */ module com.hedera.pbj.runtime { - - requires jdk.unsupported; requires transitive org.antlr.antlr4.runtime; - - requires static com.github.spotbugs.annotations; + requires jdk.unsupported; + requires static transitive com.github.spotbugs.annotations; exports com.hedera.pbj.runtime; exports com.hedera.pbj.runtime.test; diff --git a/pbj-core/settings.gradle.kts b/pbj-core/settings.gradle.kts index 47fda821..22853c48 100644 --- a/pbj-core/settings.gradle.kts +++ b/pbj-core/settings.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Hedera Hashgraph, LLC + * Copyright (C) 2022-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,87 +14,11 @@ * limitations under the License. */ -pluginManagement { includeBuild("gradle/plugins") } +plugins { id("org.hiero.gradle.build") version "0.2.1" } -plugins { - id("com.gradle.enterprise").version("3.15.1") - id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" -} - -include(":pbj-runtime") -include(":pbj-compiler") -include(":pbj-grpc-helidon-config") -include(":pbj-grpc-helidon") - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} - -var helidonVersion = "4.1.6" -var grpcVersion = "1.65.1" -var protobufVersion = "4.28.2" - -dependencyResolutionManagement { - versionCatalogs { - create("libs") { - // The libs of this catalog are the **ONLY** ones that are authorized to be part of the runtime - // distribution. These libs can be depended on during compilation, or bundled as part of runtime. - version("org.antlr.antlr4.runtime", "4.11.1") - version("com.github.spotbugs.annotations", "4.8.6") - - // The libs of this catalog are used to compile but are not bundled. The user will select helidon - // which will have the set of these dependencies that are required. - version("io.helidon.webserver", helidonVersion) - version("io.helidon.webserver.http2", helidonVersion) - version("io.helidon.webserver.observe.metrics", helidonVersion) - version("io.helidon.metrics.api", helidonVersion) - version("io.helidon.common.features.api", helidonVersion) - version("io.helidon.common.features.processor", helidonVersion) // annotation processing - version("io.helidon.config.metadata.processor", helidonVersion) // annotation processing - version("io.helidon.codegen.apt", helidonVersion) // annotation processing - version("io.helidon.builder.codegen", helidonVersion) // annotation processing - - // Testing only versions - version("com.google.protobuf", protobufVersion) - version("com.google.protobuf.util", protobufVersion) - version("org.assertj.core", "3.23.1") - version("org.junit.jupiter.api", "5.8.2") - version("org.mockito", "4.6.1") - version("org.mockito.inline", "4.6.1") - version("org.mockito.junit.jupiter", "5.10.0") - version("io.grpc.netty", grpcVersion) - version("io.grpc.protobuf", grpcVersion) - version("io.grpc.stub", grpcVersion) - version("java.annotation", "1.3.2") - version("io.helidon.webclient", helidonVersion) - version("io.helidon.webclient.http2", helidonVersion) - } - } -} - -// Build cache configuration -val isCiServer = System.getenv().containsKey("CI") -val gradleCacheUsername: String? = System.getenv("GRADLE_CACHE_USERNAME") -val gradleCachePassword: String? = System.getenv("GRADLE_CACHE_PASSWORD") -val gradleCacheAuthorized = - (gradleCacheUsername?.isNotEmpty() ?: false) && (gradleCachePassword?.isNotEmpty() ?: false) - -buildCache { - remote { - url = uri("https://cache.gradle.hedera.svcs.eng.swirldslabs.io/cache/") - isPush = isCiServer && gradleCacheAuthorized - - isUseExpectContinue = true - isEnabled = !gradle.startParameter.isOffline - - if (isCiServer && gradleCacheAuthorized) { - credentials { - username = gradleCacheUsername - password = gradleCachePassword - } - } +javaModules { + directory(".") { + group = "com.hedera.pbj" + module("pbj-compiler") // no 'module-info.java' } } diff --git a/pbj-core/version.txt b/pbj-core/version.txt new file mode 100644 index 00000000..0ee8de92 --- /dev/null +++ b/pbj-core/version.txt @@ -0,0 +1 @@ +0.9.13-SNAPSHOT \ No newline at end of file diff --git a/pbj-integration-tests/build.gradle.kts b/pbj-integration-tests/build.gradle.kts index 2d3e2a8b..76b4b93e 100644 --- a/pbj-integration-tests/build.gradle.kts +++ b/pbj-integration-tests/build.gradle.kts @@ -1,64 +1,107 @@ +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.hiero.gradle.tasks.GitClone + plugins { - id("java") - id("jacoco") + id("org.hiero.gradle.module.application") + id("org.gradlex.java-module-dependencies") + // jmh for performance benchmarks + id("org.hiero.gradle.feature.benchmark") + // We depend on Google protobuf plugin as we generate protobuf code using it as well as pbj. + // Then use it in tests to compare output and parsing with pbj to make sure it matches. + id("org.hiero.gradle.feature.protobuf") + // The "plugin-under-test" id("com.hedera.pbj.pbj-compiler") - // We depend on Google protobuf plugin as we generate protobuf code using it as well as pbj. Then use it in tests to - // compare output and parsing with pbj to make sure it matches. - id("com.google.protobuf").version("0.9.4") - // add jmh for performance benchmarks - id("me.champeau.jmh").version("0.7.2") } -group = "com.hedera.pbj.integration-tests" - -dependencies { - implementation("com.hedera.pbj:pbj-runtime") - implementation("com.hedera.pbj:pbj-compiler") - implementation("com.google.protobuf:protobuf-java:4.28.2") - implementation("com.google.protobuf:protobuf-java-util:4.28.2") - implementation("io.grpc:grpc-protobuf:1.65.1") - implementation("io.grpc:grpc-stub:1.65.1") - implementation("javax.annotation:javax.annotation-api:1.3.2") - compileOnly("com.github.spotbugs:spotbugs-annotations:4.7.3") - - testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.0") - testImplementation("org.junit.jupiter:junit-jupiter-params") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") +// We use the dependency versions from the included main build, which we need to configure here +buildscript { + dependencies { classpath(platform("com.hedera.hashgraph:hiero-dependency-versions")) } } -java { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 - toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) - vendor.set(JvmVendorSpec.ADOPTIUM) - } +jvmDependencyConflicts.consistentResolution { + platform("com.hedera.hashgraph:hiero-dependency-versions") +} - // Enable JAR file generation required for publishing - withJavadocJar() - withSourcesJar() +mainModuleInfo { + requires("com.hedera.pbj.runtime") + + requires("com.google.common") + requires("com.google.protobuf") + requires("com.google.protobuf.util") + requires("io.grpc") + requires("io.grpc.protobuf") + requires("io.grpc.stub") + requires("org.antlr.antlr4.runtime") + requiresStatic("com.github.spotbugs.annotations") } +testModuleInfo { + requires("org.junit.jupiter.api") + requires("org.junit.jupiter.params") + runtimeOnly("org.junit.jupiter.engine") +} + +jmhModuleInfo { requires("com.hedera.pbj.runtime") } + +// IMPROVE: Disable module-info transform for 'testRuntimeClasspath' which leads to an error +// possible caused by a cycle produced by depending on 'pbj-compiler' in multiple ways which +// eventually leads to 'pbj-compiler' depending on itself in this context. +configurations.testRuntimeClasspath { + attributes { attribute(Attribute.of("javaModule", Boolean::class.javaObjectType), false) } +} + +// IMPROVE: Test code should not have a direct dependency to 'com.hedera.pbj.compiler' +dependencies { testImplementation("com.hedera.pbj:pbj-compiler") { isTransitive = false } } + +dependencyAnalysis { issues { all { onAny { exclude("com.hedera.pbj:pbj-compiler") } } } } + +// IMPROVE: JMH code should not depend on test code +jmh { includeTests = true } + // Add downloaded HAPI repo protobuf files into build directory and add to sources to build them +val cloneHederaProtobufs = + tasks.register("cloneHederaProtobufs") { + localCloneDirectory = layout.buildDirectory.dir("hedera-protobufs") + url = "https://github.com/hashgraph/hedera-protobufs.git" + // choose tag or branch of HAPI you would like to test with + // branch = "main" + tag = "v0.55.0" + } + sourceSets { main { pbj { - srcDir(layout.buildDirectory.dir("repos/hapi/block")) - srcDir(layout.buildDirectory.dir("repos/hapi/services")) - srcDir(layout.buildDirectory.dir("repos/hapi/streams")) - srcDir(layout.buildDirectory.dir("repos/hapi/platform")) + srcDir(cloneHederaProtobufs.flatMap { it.localCloneDirectory.dir("block") }) + srcDir(cloneHederaProtobufs.flatMap { it.localCloneDirectory.dir("platform") }) + srcDir(cloneHederaProtobufs.flatMap { it.localCloneDirectory.dir("services") }) + srcDir(cloneHederaProtobufs.flatMap { it.localCloneDirectory.dir("streams") }) } proto { - srcDir(layout.buildDirectory.dir("repos/hapi/block")) - srcDir(layout.buildDirectory.dir("repos/hapi/services")) - srcDir(layout.buildDirectory.dir("repos/hapi/streams")) - srcDir(layout.buildDirectory.dir("repos/hapi/platform")) + srcDir(cloneHederaProtobufs.flatMap { it.localCloneDirectory.dir("block") }) + srcDir(cloneHederaProtobufs.flatMap { it.localCloneDirectory.dir("platform") }) + srcDir(cloneHederaProtobufs.flatMap { it.localCloneDirectory.dir("services") }) + srcDir(cloneHederaProtobufs.flatMap { it.localCloneDirectory.dir("streams") }) } } } -/** Exclude protoc generated from docs, so we can see clear warnings and errors */ -tasks.withType { +// Exclude protoc generated from docs +tasks.javadoc { exclude("com/hederahashgraph/api/proto/**") exclude("com/hederahashgraph/service/proto/**") exclude("com/hedera/services/stream/proto/**") @@ -66,105 +109,39 @@ tasks.withType { exclude("pbj/**") } -protobuf { - // Configure the protoc executable - protoc { - // Download from repositories - artifact = "com.google.protobuf:protoc:4.28.2" - } - plugins { - create("grpc") { - artifact = "io.grpc:protoc-gen-grpc-java:1.65.1" - } - } - - generateProtoTasks { - all().forEach { - it.plugins { - create("grpc") - } - } - } -} - testing { @Suppress("UnstableApiUsage") - suites.getByName("test") { - useJUnitJupiter() - + suites.named("test") { tasks.register("fuzzTest") { testClassesDirs = sources.output.classesDirs classpath = sources.runtimeClasspath - useJUnitPlatform { includeTags("FUZZ_TEST") } enableAssertions = false } - tasks.register("randomFuzzTest") { testClassesDirs = sources.output.classesDirs classpath = sources.runtimeClasspath - useJUnitPlatform { includeTags("FUZZ_TEST") } enableAssertions = false systemProperties["com.hedera.pbj.intergration.test.fuzz.useRandomSeed"] = true } + targets.named("test") { + testTask { + useJUnitPlatform { excludeTags("FUZZ_TEST") } + dependsOn(tasks.named("fuzzTest")) + } + } } } -tasks.test { - useJUnitPlatform { excludeTags("FUZZ_TEST") } - dependsOn("fuzzTest") -} - tasks.withType().configureEach { // We are running a lot of tests 10s of thousands, so they need to run in parallel systemProperties["junit.jupiter.execution.parallel.enabled"] = true systemProperties["junit.jupiter.execution.parallel.mode.default"] = "concurrent" - // us parallel GC to keep up with high temporary garbage creation, and allow GC to use 40% of CPU if needed + // us parallel GC to keep up with high temporary garbage creation, and allow GC to use 40% of + // CPU if needed jvmArgs("-XX:+UseParallelGC", "-XX:GCTimeRatio=90") // Some also need more memory minHeapSize = "512m" maxHeapSize = "4096m" } - -jmh { - includes.add("SampleBlockBench") -// includes.add("JsonBench") -// includes.add("VarIntBench") -// includes.add("HashBench") -// includes.add("EqualsHashCodeBench"); - - jmhVersion.set("1.37") - includeTests.set(true) -// jvmArgsAppend.add("-XX:MaxInlineSize=100 -XX:MaxInlineLevel=20") -} - -tasks.jmhJar { - manifest { - attributes(mapOf("Multi-Release" to true)) - } - // I've no ideas why these classes are in the shadow jar, they seem redundant. If - // not excluded, they make jmhJar fail, complaining about too many jar entries - exclude("org/gradle/**") - exclude("groovy*/**") - exclude("**/groovy/**") - exclude("kotlin/**") -} - -// Ensure JaCoCo coverage is generated and aggregated -tasks.jacocoTestReport.configure { - reports { - xml.required.set(true) - html.required.set(true) - } - - val testExtension = tasks.test.get().extensions.getByType() - executionData.setFrom(testExtension.destinationFile) - - shouldRunAfter(tasks.named("check")) -} - -// Ensure the check task also runs the JaCoCo coverage report -tasks.named("check").configure { - dependsOn(tasks.named("jacocoTestReport")) -} diff --git a/pbj-integration-tests/gradle.properties b/pbj-integration-tests/gradle.properties index 0a77e57b..c2605b94 100644 --- a/pbj-integration-tests/gradle.properties +++ b/pbj-integration-tests/gradle.properties @@ -1,10 +1,6 @@ -# Need increased heap for running Gradle itself, or SonarQube will run the JVM out of metaspace -org.gradle.jvmargs=-Xmx2048m +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 -# Enable Gradle Caching +# Enable Gradle Caching and Parallelism org.gradle.caching=true - +org.gradle.configuration-cache=true org.gradle.parallel=true - -# Disable publish signing by default -publishSigningEnabled=false diff --git a/pbj-integration-tests/gradle/license-header.txt b/pbj-integration-tests/gradle/license-header.txt new file mode 100644 index 00000000..2e707c37 --- /dev/null +++ b/pbj-integration-tests/gradle/license-header.txt @@ -0,0 +1,13 @@ +Copyright (C) $YEAR Hedera Hashgraph, LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/pbj-integration-tests/gradle/toolchain-versions.properties b/pbj-integration-tests/gradle/toolchain-versions.properties new file mode 100644 index 00000000..04e458fa --- /dev/null +++ b/pbj-integration-tests/gradle/toolchain-versions.properties @@ -0,0 +1 @@ +jdk=21.0.4 diff --git a/pbj-integration-tests/gradle/wrapper/gradle-wrapper.jar b/pbj-integration-tests/gradle/wrapper/gradle-wrapper.jar index 7f93135c..a4b76b95 100644 Binary files a/pbj-integration-tests/gradle/wrapper/gradle-wrapper.jar and b/pbj-integration-tests/gradle/wrapper/gradle-wrapper.jar differ diff --git a/pbj-integration-tests/gradle/wrapper/gradle-wrapper.properties b/pbj-integration-tests/gradle/wrapper/gradle-wrapper.properties index 1af9e093..cea7a793 100644 --- a/pbj-integration-tests/gradle/wrapper/gradle-wrapper.properties +++ b/pbj-integration-tests/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/pbj-integration-tests/gradlew b/pbj-integration-tests/gradlew index 0adc8e1a..f3b75f3b 100755 --- a/pbj-integration-tests/gradlew +++ b/pbj-integration-tests/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# 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/. @@ -84,7 +86,7 @@ done # 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 "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +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 @@ -145,7 +147,7 @@ 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=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -153,7 +155,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -202,11 +204,11 @@ fi # 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"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_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" \ diff --git a/pbj-integration-tests/gradlew.bat b/pbj-integration-tests/gradlew.bat index 6689b85b..9b42019c 100644 --- a/pbj-integration-tests/gradlew.bat +++ b/pbj-integration-tests/gradlew.bat @@ -13,6 +13,8 @@ @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 @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 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 @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe 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 diff --git a/pbj-integration-tests/settings.gradle.kts b/pbj-integration-tests/settings.gradle.kts index e67b086c..cfa3ec27 100644 --- a/pbj-integration-tests/settings.gradle.kts +++ b/pbj-integration-tests/settings.gradle.kts @@ -1,64 +1,26 @@ -import me.champeau.gradle.igp.gitRepositories +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ pluginManagement { - repositories.gradlePluginPortal() - // To use locally built 'pbj-core' (Gradle plugin) - includeBuild("../pbj-core") + includeBuild("../pbj-core") // use locally built 'pbj-core' (Gradle plugin) } +plugins { id("org.hiero.gradle.build") version "0.2.1" } + dependencyResolutionManagement { - @Suppress("UnstableApiUsage") repositories.mavenCentral() // To use locally built 'pbj-runtime' includeBuild("../pbj-core") } - -// Use GIT plugin to clone HAPI protobuf files for testing -// See documentation https://melix.github.io/includegit-gradle-plugin/latest/index.html - -plugins { - id("com.gradle.enterprise").version("3.15.1") - id("me.champeau.includegit").version("0.1.5") - id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" -} - -gitRepositories { - checkoutsDirectory.set(file("./build/repos")) - include("hapi") { - uri.set("https://github.com/hashgraph/hedera-protobufs.git") - // choose tag or branch of HAPI you would like to test with - tag.set("main") - // do not load project from repo - autoInclude.set(false) - } -} - -gradleEnterprise { - buildScan { - termsOfServiceUrl = "https://gradle.com/terms-of-service" - termsOfServiceAgree = "yes" - } -} - -// Build cache configuration -val isCiServer = System.getenv().containsKey("CI") -val gradleCacheUsername: String? = System.getenv("GRADLE_CACHE_USERNAME") -val gradleCachePassword: String? = System.getenv("GRADLE_CACHE_PASSWORD") -val gradleCacheAuthorized = - (gradleCacheUsername?.isNotEmpty() ?: false) && (gradleCachePassword?.isNotEmpty() ?: false) - -buildCache { - remote { - url = uri("https://cache.gradle.hedera.svcs.eng.swirldslabs.io/cache/") - isPush = isCiServer && gradleCacheAuthorized - - isUseExpectContinue = true - isEnabled = !gradle.startParameter.isOffline - - if (isCiServer && gradleCacheAuthorized) { - credentials { - username = gradleCacheUsername - password = gradleCachePassword - } - } - } -} diff --git a/pbj-integration-tests/src/main/java/com/hedera/pbj/integration/NonSynchronizedByteArrayInputStream.java b/pbj-integration-tests/src/main/java/com/hedera/pbj/integration/NonSynchronizedByteArrayInputStream.java index a65d45f9..df25a400 100644 --- a/pbj-integration-tests/src/main/java/com/hedera/pbj/integration/NonSynchronizedByteArrayInputStream.java +++ b/pbj-integration-tests/src/main/java/com/hedera/pbj/integration/NonSynchronizedByteArrayInputStream.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hedera.pbj.integration; import java.io.IOException; @@ -68,7 +84,7 @@ public long skip(long n) { k = n < 0 ? 0 : n; } - pos += k; + pos += (int) k; return k; } diff --git a/pbj-integration-tests/src/test/java/com/hedera/pbj/intergration/test/CompareToNegativeTest.java b/pbj-integration-tests/src/test/java/com/hedera/pbj/intergration/test/CompareToNegativeTest.java index d51ca2c7..7cd13e59 100644 --- a/pbj-integration-tests/src/test/java/com/hedera/pbj/intergration/test/CompareToNegativeTest.java +++ b/pbj-integration-tests/src/test/java/com/hedera/pbj/intergration/test/CompareToNegativeTest.java @@ -1,15 +1,30 @@ +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hedera.pbj.intergration.test; -import static com.hedera.pbj.compiler.PbjCompilerTask.compileFilesIn; +import static com.hedera.pbj.compiler.PbjCompiler.compileFilesIn; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - import java.io.File; import java.net.URL; import java.util.List; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; class CompareToNegativeTest { @@ -18,25 +33,28 @@ class CompareToNegativeTest { @Test void testNonComparableSubObj() { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> - getCompileFilesIn("non_compilable_comparable_sub_obj.proto")); - assertEquals("Field NonComparableSubObj.subObject specified in `pbj.comparable` option must implement `Comparable` interface but it doesn't.", + IllegalArgumentException exception = assertThrows( + IllegalArgumentException.class, () -> getCompileFilesIn("non_compilable_comparable_sub_obj.proto")); + assertEquals( + "Field NonComparableSubObj.subObject specified in `pbj.comparable` option must implement `Comparable` interface but it doesn't.", exception.getMessage()); } @Test void testRepeatedField() { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> - getCompileFilesIn("non_compilable_comparable_repeated.proto")); - assertEquals("Field `int32List` specified in `pbj.comparable` option is repeated. Repeated fields are not supported by this option.", + IllegalArgumentException exception = assertThrows( + IllegalArgumentException.class, () -> getCompileFilesIn("non_compilable_comparable_repeated.proto")); + assertEquals( + "Field `int32List` specified in `pbj.comparable` option is repeated. Repeated fields are not supported by this option.", exception.getMessage()); } @Test void testNonComparableOneOfField() { - IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> - getCompileFilesIn("non_compilable_comparable_oneOf.proto")); - assertEquals("Field NonComparableSubObj.subObject specified in `pbj.comparable` option must implement `Comparable` interface but it doesn't.", + IllegalArgumentException exception = assertThrows( + IllegalArgumentException.class, () -> getCompileFilesIn("non_compilable_comparable_oneOf.proto")); + assertEquals( + "Field NonComparableSubObj.subObject specified in `pbj.comparable` option must implement `Comparable` interface but it doesn't.", exception.getMessage()); } diff --git a/pbj-integration-tests/src/test/java/com/hedera/pbj/intergration/test/TestHashFunctions.java b/pbj-integration-tests/src/test/java/com/hedera/pbj/intergration/test/TestHashFunctions.java index 46751c57..fafd6c7c 100644 --- a/pbj-integration-tests/src/test/java/com/hedera/pbj/intergration/test/TestHashFunctions.java +++ b/pbj-integration-tests/src/test/java/com/hedera/pbj/intergration/test/TestHashFunctions.java @@ -1,9 +1,23 @@ +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hedera.pbj.intergration.test; import com.hedera.pbj.test.proto.pbj.Hasheval; import com.hedera.pbj.test.proto.pbj.TimestampTest; -import org.junit.jupiter.params.ParameterizedTest; -import java.nio.ByteBuffer; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -13,8 +27,8 @@ public final class TestHashFunctions { public static int hash1(Hasheval hashEval) { try { - byte[] hash = MessageDigest.getInstance("SHA-256").digest( - Hasheval.PROTOBUF.toBytes(hashEval).toByteArray()); + byte[] hash = MessageDigest.getInstance("SHA-256") + .digest(Hasheval.PROTOBUF.toBytes(hashEval).toByteArray()); int res = hash[0] << 24 | hash[1] << 16 | hash[2] << 8 | hash[3]; return processForBetterDistribution(res); } catch (NoSuchAlgorithmException e) { @@ -70,10 +84,10 @@ public static int hash2(Hasheval hashEval) { } if (hashEval.subObject() != Hasheval.DEFAULT.subObject()) { TimestampTest sub = hashEval.subObject(); - if (sub.nanos() != sub.DEFAULT.nanos()) { + if (sub.nanos() != TimestampTest.DEFAULT.nanos()) { result = 31 * result + Integer.hashCode(sub.nanos()); } - if (sub.seconds() != sub.DEFAULT.seconds()) { + if (sub.seconds() != TimestampTest.DEFAULT.seconds()) { result = 31 * result + Long.hashCode(sub.seconds()); } } @@ -81,7 +95,8 @@ public static int hash2(Hasheval hashEval) { result = 31 * result + hashEval.text().hashCode(); } if (hashEval.bytesField() != Hasheval.DEFAULT.bytesField()) { - result = 31 * result + (hashEval.bytesField() == null ? 0 : hashEval.bytesField().hashCode()); + result = 31 * result + + (hashEval.bytesField() == null ? 0 : hashEval.bytesField().hashCode()); } return processForBetterDistribution(result); @@ -99,4 +114,4 @@ private static int processForBetterDistribution(int val) { val += val << 30; return val; } -} \ No newline at end of file +}