diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1dc6e57..f717dfe 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -54,19 +54,14 @@ jobs:
working-directory: log/native
run: cargo build --release
- - name: Set up Java 17
+ - name: Set up Java 24
uses: actions/setup-java@v4
with:
- java-version: '17'
+ java-version: '24'
distribution: 'temurin'
- - name: Cache Maven local repository
- uses: actions/cache@v4
- with:
- path: ~/.m2/repository
- key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
- restore-keys: |
- ${{ runner.os }}-maven-
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v4
- - name: Maven build and test
- run: mvn verify -Djava.library.path=log/native/target/release
+ - name: Gradle build and test
+ run: ./gradlew build
diff --git a/.gitignore b/.gitignore
index bd9fc00..73b2490 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,13 +6,16 @@
# Rust build artifacts
target/
+# Gradle
+.gradle/
+build/
+
# Java build artifacts
*.class
*.jar
+!gradle/wrapper/gradle-wrapper.jar
*.war
*.ear
-log/target/
-benchmark-driver/target/
# Benchmark results
*.json
diff --git a/AGENTS.md b/AGENTS.md
index c44f587..c88c783 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -31,7 +31,8 @@ opendata-java/
│ ├── LogDbReader.java # Read-only API
│ ├── LogDbConfig.java # Configuration record
│ └── ...
-└── pom.xml # Maven multi-module build
+├── build.gradle # Gradle multi-module build
+└── settings.gradle
```
## JNI Architecture
@@ -92,8 +93,7 @@ The JNI layer prepends an 8-byte timestamp to values for latency measurement:
### Prerequisites
- Rust stable toolchain
-- Java 17+
-- Maven 3.8+
+- Java 24+
- Sibling clone of `opendata` repository
### Building
@@ -103,9 +103,9 @@ The JNI layer prepends an 8-byte timestamp to values for latency measurement:
cd log/native
cargo build --release
-# Build and install Java modules
+# Build Java modules
cd ../..
-mvn clean install
+./gradlew build
```
### Testing
@@ -116,7 +116,7 @@ cd log/native
cargo test
# Java tests (requires native library)
-mvn test -Djava.library.path=log/native/target/release
+./gradlew test
```
### Formatting and Linting
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index cbe6c7c..3a003af 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -50,8 +50,7 @@ Open an issue describing:
### Prerequisites
- Rust stable toolchain ([rustup](https://rustup.rs/))
-- Java 17+ ([SDKMAN](https://sdkman.io/) recommended)
-- Maven 3.8+
+- Java 24+ ([SDKMAN](https://sdkman.io/) recommended)
- Git
- Local clone of [opendata](https://github.com/opendata-oss/opendata) as sibling directory
@@ -72,7 +71,7 @@ cargo build --release
# Build Java modules
cd ../..
-mvn clean install -DskipTests
+./gradlew build
```
## Code Style
@@ -154,7 +153,7 @@ cd log/native
cargo test
# Java tests (requires native library built)
-mvn test -Djava.library.path=log/native/target/release
+./gradlew test
```
## Pull Request Process
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..e8e7424
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,38 @@
+subprojects {
+ apply plugin: 'java-library'
+
+ group = 'dev.opendata'
+ version = '0.1.0-SNAPSHOT'
+
+ def minimumJava = 24
+ def currentJava = JavaVersion.current()
+ def toolchainVersion = currentJava.isCompatibleWith(JavaVersion.toVersion(minimumJava))
+ ? Integer.parseInt(currentJava.majorVersion)
+ : minimumJava
+
+ java {
+ toolchain {
+ languageVersion = JavaLanguageVersion.of(toolchainVersion)
+ }
+ sourceCompatibility = JavaVersion.toVersion(minimumJava)
+ targetCompatibility = JavaVersion.toVersion(minimumJava)
+ }
+
+ tasks.withType(JavaCompile).configureEach {
+ options.release = minimumJava
+ }
+
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2'
+ testImplementation 'org.assertj:assertj-core:3.25.3'
+ testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.10.2'
+ }
+
+ test {
+ useJUnitPlatform()
+ }
+}
diff --git a/common/build.gradle b/common/build.gradle
new file mode 100644
index 0000000..7aedabc
--- /dev/null
+++ b/common/build.gradle
@@ -0,0 +1,2 @@
+// Common utilities for OpenData Java bindings
+// Dependencies are configured in the root build.gradle
diff --git a/common/pom.xml b/common/pom.xml
deleted file mode 100644
index ce5bf47..0000000
--- a/common/pom.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
- 4.0.0
-
-
- dev.opendata
- opendata-java
- 0.1.0-SNAPSHOT
- ../pom.xml
-
-
- common
- OpenData Common
- Common utilities for OpenData Java bindings
-
-
-
- org.junit.jupiter
- junit-jupiter
- 5.10.2
- test
-
-
- org.assertj
- assertj-core
- 3.25.3
- test
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.11.0
-
-
-
-
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..61285a6
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..37f78a6
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..f0f1576
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,18 @@
+#!/usr/bin/env sh
+set -e
+
+APP_HOME="$(cd "$(dirname "$0")" && pwd)"
+APP_BASE_NAME="$(basename "$0")"
+
+DEFAULT_JVM_OPTS="-Xmx64m -Xms64m"
+
+if [ -n "$JAVA_HOME" ] ; then
+ JAVA_EXEC="$JAVA_HOME/bin/java"
+else
+ JAVA_EXEC="java"
+fi
+
+exec "$JAVA_EXEC" $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \
+ -Dorg.gradle.appname="$APP_BASE_NAME" \
+ -classpath "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
+ org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..5c4fc32
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,13 @@
+@echo off
+setlocal
+set APP_HOME=%~dp0
+set DEFAULT_JVM_OPTS=-Xmx64m -Xms64m
+
+if defined JAVA_HOME (
+ set "JAVA_EXE=%JAVA_HOME%\bin\java.exe"
+) else (
+ set "JAVA_EXE=java"
+)
+
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% -Dorg.gradle.appname=%~n0 -classpath "%APP_HOME%gradle\wrapper\gradle-wrapper.jar" org.gradle.wrapper.GradleWrapperMain %*
+endlocal
diff --git a/log/build.gradle b/log/build.gradle
new file mode 100644
index 0000000..746d6be
--- /dev/null
+++ b/log/build.gradle
@@ -0,0 +1,8 @@
+dependencies {
+ implementation project(':common')
+}
+
+test {
+ jvmArgs "-Djava.library.path=${project.projectDir}/native/target/release"
+ jvmArgs '--enable-native-access=ALL-UNNAMED'
+}
diff --git a/log/pom.xml b/log/pom.xml
deleted file mode 100644
index c7827e5..0000000
--- a/log/pom.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
- 4.0.0
-
-
- dev.opendata
- opendata-java
- 0.1.0-SNAPSHOT
- ../pom.xml
-
-
- log
- OpenData Log
- Java bindings for OpenData Log
-
-
- ${project.basedir}/native/target/release
-
-
-
-
- dev.opendata
- common
- ${project.version}
-
-
- org.junit.jupiter
- junit-jupiter
- 5.10.2
- test
-
-
- org.assertj
- assertj-core
- 3.25.3
- test
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.11.0
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- 3.2.5
-
- -Djava.library.path=${native.library.path}
-
-
-
-
-
diff --git a/pom.xml b/pom.xml
deleted file mode 100644
index 354c0d2..0000000
--- a/pom.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
- 4.0.0
-
- dev.opendata
- opendata-java
- 0.1.0-SNAPSHOT
- pom
-
- OpenData Java
- Java bindings for OpenData systems
-
-
- common
- log
-
-
-
- 17
- 17
- UTF-8
-
-
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..a9ad188
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,6 @@
+plugins {
+ id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0'
+}
+
+rootProject.name = 'opendata-java'
+include 'common', 'log'