From 0a2c4869ae55843273b73d1dc9a33f099fb3d162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Garc=C3=ADa=20M=C3=A1rquez?= Date: Mon, 29 Dec 2025 08:09:26 +0100 Subject: [PATCH 1/7] Android libraries to build to maven --- gradle/libs.versions.toml | 8 ++- lib/build.gradle.kts | 100 +++++++++++++++++++++---------- lib/src/main/AndroidManifest.xml | 2 + settings.gradle.kts | 15 +++++ 4 files changed, 91 insertions(+), 34 deletions(-) create mode 100644 lib/src/main/AndroidManifest.xml diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f120df7..befbae3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,14 +2,18 @@ # https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format [versions] +android-gradle-plugin = "8.7.3" commons-math3 = "3.6.1" guava = "33.4.6-jre" junit-jupiter-engine = "5.12.1" +kotlin = "2.2.20" [libraries] -commons-math3 = { module = "org.apache.commons:commons-math3", version.ref = "commons-math3" } +commons-math = { module = "org.apache.commons:commons-math3", version.ref = "commons-math3" } guava = { module = "com.google.guava:guava", version.ref = "guava" } junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit-jupiter-engine" } [plugins] -kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version = "2.2.20" } +android-library = { id = "com.android.library", version.ref = "android-gradle-plugin" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 3cc3a8a..522ad77 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -6,21 +6,52 @@ */ plugins { - // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin. - alias(libs.plugins.kotlin.jvm) - - // Apply the java-library plugin for API and implementation separation. - `java-library` + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.android) id("com.squareup.wire") version "5.4.0" // JaCoCo for code coverage jacoco + + `maven-publish` } -repositories { - // Use Maven Central for resolving dependencies. - mavenCentral() +android { + namespace = "org.flex" + compileSdk = 35 + + defaultConfig { + minSdk = 21 + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlin { + compilerOptions { + jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17) + } + } + + publishing { + singleVariant("release") { + withSourcesJar() + } + } } wire { @@ -39,6 +70,7 @@ val coroutinesVersion = "1.7.3" dependencies { // Kotlin Coroutines - Android compatible api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion") testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion") // Use the Kotlin Test integration. @@ -53,7 +85,7 @@ dependencies { testImplementation("io.mockk:mockk:1.13.8") // This dependency is exported to consumers, that is to say found on their compile classpath. - api(libs.commons.math3) + api(libs.commons.math) // This dependency is used internally, and not exposed to consumers on their own compile classpath. implementation(libs.guava) @@ -63,36 +95,40 @@ dependencies { implementation("com.squareup.wire:wire-grpc-client:5.4.0") } -// Apply a specific Java toolchain to ease working on different environments. -java { - toolchain { - languageVersion = JavaLanguageVersion.of(21) - } -} - -tasks.named("test") { - // Use JUnit Platform for unit tests. - useJUnitPlatform() - - // Generate JaCoCo coverage data - finalizedBy(tasks.jacocoTestReport) -} - // Configure JaCoCo code coverage jacoco { toolVersion = "0.8.10" } -tasks.jacocoTestReport { - dependsOn(tasks.test) +tasks.register("jacocoTestReport") { + dependsOn(tasks.named("testDebugUnitTest")) reports { - xml.required = true - html.required = true - csv.required = false + xml.required.set(true) + html.required.set(true) } - classDirectories.setFrom(files("${layout.buildDirectory.get()}/classes/kotlin/main")) - sourceDirectories.setFrom(files("src/main/kotlin")) - executionData.setFrom(files("${layout.buildDirectory.get()}/jacoco/test.exec")) + val debugTree = fileTree("${layout.buildDirectory.get()}/tmp/kotlin-classes/debug") + val mainSrc = "src/main/kotlin" + + sourceDirectories.setFrom(files(mainSrc)) + classDirectories.setFrom(debugTree) + executionData.setFrom(fileTree(layout.buildDirectory).include("/jacoco/*.exec")) +} + +publishing { + publications { + register("release") { + groupId = "org.flex" + artifactId = "flexible" + version = "0.0.1" + + afterEvaluate { + from(components["release"]) + } + } + } + repositories { + mavenLocal() + } } diff --git a/lib/src/main/AndroidManifest.xml b/lib/src/main/AndroidManifest.xml new file mode 100644 index 0000000..8072ee0 --- /dev/null +++ b/lib/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/settings.gradle.kts b/settings.gradle.kts index a9e0463..150106d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,6 +5,21 @@ * For more detailed information on multi-project builds, please refer to https://docs.gradle.org/9.2.0/userguide/multi_project_builds.html in the Gradle documentation. */ +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} + plugins { // Apply the foojay-resolver plugin to allow automatic download of JDKs id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" From b43a98e7cc2deaed93d75402916804282edbe744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Garc=C3=ADa=20M=C3=A1rquez?= Date: Mon, 29 Dec 2025 08:13:43 +0100 Subject: [PATCH 2/7] fix: enable JUnit 5 for Android unit tests --- lib/build.gradle.kts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 522ad77..ed27e59 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -27,6 +27,12 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } + testOptions { + unitTests.all { + it.useJUnitPlatform() + } + } + buildTypes { release { isMinifyEnabled = false From 4477f142eb6164fa9156614748dffefd444eb7f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Garc=C3=ADa=20M=C3=A1rquez?= Date: Mon, 29 Dec 2025 08:13:43 +0100 Subject: [PATCH 3/7] feat: force Java 21 toolchain and target compatibility --- lib/build.gradle.kts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index ed27e59..1309e4b 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -43,13 +43,13 @@ android { } } compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } kotlin { compilerOptions { - jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17) + jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21) } } @@ -62,6 +62,11 @@ android { wire { sourcePath { +// Apply a specific Java toolchain to ensure we use Java 21 +kotlin { + jvmToolchain(21) +} + srcDir("src/main/proto") include("org/flex/tensor.proto") include("org/flex/transport.proto") From b5e98502a3cc7462641e1a7b247e3278369f7590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Garc=C3=ADa=20M=C3=A1rquez?= Date: Mon, 29 Dec 2025 08:13:43 +0100 Subject: [PATCH 4/7] chore: update JaCoCo to 0.8.12 for Java 21 compatibility --- lib/build.gradle.kts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 1309e4b..e695654 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -60,13 +60,13 @@ android { } } -wire { - sourcePath { // Apply a specific Java toolchain to ensure we use Java 21 kotlin { jvmToolchain(21) } +wire { + sourcePath { srcDir("src/main/proto") include("org/flex/tensor.proto") include("org/flex/transport.proto") @@ -108,7 +108,7 @@ dependencies { // Configure JaCoCo code coverage jacoco { - toolVersion = "0.8.10" + toolVersion = "0.8.12" } tasks.register("jacocoTestReport") { From 72abc54b2526c5e7588249363d58c6d25b522fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Garc=C3=ADa=20M=C3=A1rquez?= Date: Mon, 29 Dec 2025 08:30:45 +0100 Subject: [PATCH 5/7] Fix test bug and task call --- .github/workflows/code-quality.yml | 2 +- lib/src/main/kotlin/org/flex/FlexClient.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 3c6b1dd..001ee3f 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -31,7 +31,7 @@ jobs: continue-on-error: true - name: Check for compilation warnings - run: ./gradlew compileKotlin --no-daemon -Dorg.gradle.warning.mode=all + run: ./gradlew compileDebugKotlin --no-daemon -Dorg.gradle.warning.mode=all - name: Run dependency check run: ./gradlew dependencyCheck --no-daemon diff --git a/lib/src/main/kotlin/org/flex/FlexClient.kt b/lib/src/main/kotlin/org/flex/FlexClient.kt index e497b9a..f843546 100644 --- a/lib/src/main/kotlin/org/flex/FlexClient.kt +++ b/lib/src/main/kotlin/org/flex/FlexClient.kt @@ -558,7 +558,7 @@ abstract class FlexClient( } private fun updateStats(update: (SessionStats) -> SessionStats) { - _stats.updateAndGet(update) + _stats.set(update(_stats.get())) listener.onStatsUpdated(_stats.get()) } } From 7a8711ae27ef208bc2835c389ca04375b4fefbea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Garc=C3=ADa=20M=C3=A1rquez?= Date: Mon, 29 Dec 2025 16:12:51 +0100 Subject: [PATCH 6/7] fix service name in android services --- lib/src/main/proto/org/flex/tensor.proto | 5 +++-- lib/src/main/proto/org/flex/transport.proto | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/src/main/proto/org/flex/tensor.proto b/lib/src/main/proto/org/flex/tensor.proto index eedf36b..c5a768f 100644 --- a/lib/src/main/proto/org/flex/tensor.proto +++ b/lib/src/main/proto/org/flex/tensor.proto @@ -1,7 +1,8 @@ syntax = "proto3"; +package flexible; -package org.flex.flexible; - +option java_package = "org.flex.flexible"; +option java_multiple_files = true; message Tensor { repeated int32 shape = 1; bytes data = 2; diff --git a/lib/src/main/proto/org/flex/transport.proto b/lib/src/main/proto/org/flex/transport.proto index ce48274..900c9a3 100644 --- a/lib/src/main/proto/org/flex/transport.proto +++ b/lib/src/main/proto/org/flex/transport.proto @@ -1,6 +1,10 @@ syntax = "proto3"; +package flexible; + +// This defines where the generated Java classes will live +option java_package = "org.flex.flexible"; +option java_multiple_files = true; -package org.flex.flexible; import "org/flex/tensor.proto"; From fa9028faa06c31e1fa986555c7bb38ea410ab4d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Garc=C3=ADa=20M=C3=A1rquez?= Date: Mon, 29 Dec 2025 16:16:11 +0100 Subject: [PATCH 7/7] fixed jacoco explicit dependency problem --- lib/build.gradle.kts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index e695654..04c6320 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -113,18 +113,19 @@ jacoco { tasks.register("jacocoTestReport") { dependsOn(tasks.named("testDebugUnitTest")) + dependsOn(tasks.named("testReleaseUnitTest")) reports { xml.required.set(true) html.required.set(true) } - val debugTree = fileTree("${layout.buildDirectory.get()}/tmp/kotlin-classes/debug") + val debugTree = fileTree(layout.buildDirectory.dir("tmp/kotlin-classes/debug")) val mainSrc = "src/main/kotlin" sourceDirectories.setFrom(files(mainSrc)) classDirectories.setFrom(debugTree) - executionData.setFrom(fileTree(layout.buildDirectory).include("/jacoco/*.exec")) + executionData.setFrom(fileTree(layout.buildDirectory.dir("jacoco")).include("*.exec")) } publishing {