diff --git a/.github/workflows/publish_jar.yaml b/.github/workflows/publish_jar.yaml new file mode 100644 index 00000000..70630dab --- /dev/null +++ b/.github/workflows/publish_jar.yaml @@ -0,0 +1,48 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +# GitHub recommends pinning actions to a commit SHA. +# To get a newer version, you will need to update the SHA. +# You can also reference a tag or branch, but the action may change without warning. + +name: Publish java client to GitHub Packages + +on: + pull_request: + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: java setup + uses: actions/setup-java@v4 + with: + java-version: '11' + distribution: 'corretto' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 + + - name: Publish cac client + run: | + cd clients/java/cac-client + ./gradlew build + ./gradlew publish + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Publish exp client + run: | + cd clients/java/exp-client + ./gradlew build + ./gradlew publish + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index bc5abd1f..ebb8f467 100644 --- a/.gitignore +++ b/.gitignore @@ -36,8 +36,7 @@ test_logs .pre-commit-config.yaml .cargo -#java client -clients/java/cac-client/.gradle -clients/java/cac-client/build -clients/java/exp-client/.gradle -clients/java/exp-client/build \ No newline at end of file +#gradle files +.gradle +build +.java~ diff --git a/clients/java/README.md b/clients/java/README.md index 972ee796..675ed9aa 100644 --- a/clients/java/README.md +++ b/clients/java/README.md @@ -19,9 +19,78 @@ To run the application: ./gradlew run ``` +## Publishing the clients locally and using it + +Publish cac-client +``` +cd clients/java/cac-client +./gradlew publishToMavenLocal +``` + +Publish exp-client +``` +cd clients/java/exp-client +./gradlew publishToMavenLocal +``` + +### Use the clients in another project + +build.gradle +``` +plugins { + id 'java' + id 'application' +} + +repositories { + mavenLocal() // if using local Maven repository + mavenCentral() + // maven { + // url = uri('https://your-repo-url/maven') // if using a remote repository + // } +} + +dependencies { + implementation 'com.github.jnr:jnr-ffi:2.2.16' + implementation 'com.github.jnr:jffi:1.3.13' + implementation 'cac-client:CacClient:1.0.0' + implementation 'exp-client:ExpClient:1.0.0' +} + +application { + mainClassName = 'Client' // main class name +} +``` + +Client.java +``` +import cac_client.CacClient; +import exp_client.ExperimentationClient; +import cac_client.CACClientException; +import exp_client.EXPClientException; + +public class Client { + public static void main(String[] args) { + CountDownLatch latch = new CountDownLatch(1); + try { + CacClient cac_wrapper = new CacClient(); + // Use cac-client's functions + ExperimentationClient exp_wrapper = new ExperimentationClient(); + // Use exp-client's functions + latch.await(); // This will keep the main thread alive + } catch (InterruptedException e) { + System.err.println("Main thread interrupted: " + e.getMessage()); + } finally { + System.out.println("Application stopped."); + } + } +} +``` + ## If having issues Try exporting these ``` +export SUPERPOSITION_LIB_PATH=".../superposition/target/debug" export PATH=$JAVA_HOME/bin:$PATH export JAVA_HOME=/opt/homebrew/opt/openjdk ``` \ No newline at end of file diff --git a/clients/java/cac-client/bin/main/cac_client/CACClientException.class b/clients/java/cac-client/bin/main/cac_client/CACClientException.class new file mode 100644 index 00000000..6390e14e Binary files /dev/null and b/clients/java/cac-client/bin/main/cac_client/CACClientException.class differ diff --git a/clients/java/cac-client/bin/main/cac_client/CacClient$RustLib.class b/clients/java/cac-client/bin/main/cac_client/CacClient$RustLib.class new file mode 100644 index 00000000..98b610ff Binary files /dev/null and b/clients/java/cac-client/bin/main/cac_client/CacClient$RustLib.class differ diff --git a/clients/java/cac-client/bin/main/cac_client/CacClient.class b/clients/java/cac-client/bin/main/cac_client/CacClient.class new file mode 100644 index 00000000..adc51668 Binary files /dev/null and b/clients/java/cac-client/bin/main/cac_client/CacClient.class differ diff --git a/clients/java/cac-client/bin/main/example/Demo.class b/clients/java/cac-client/bin/main/example/Demo.class new file mode 100644 index 00000000..2faabe37 Binary files /dev/null and b/clients/java/cac-client/bin/main/example/Demo.class differ diff --git a/clients/java/cac-client/build.gradle b/clients/java/cac-client/build.gradle index 826e5698..955951fc 100644 --- a/clients/java/cac-client/build.gradle +++ b/clients/java/cac-client/build.gradle @@ -1,42 +1,42 @@ plugins { id 'java-library' id 'maven-publish' + id 'java' + id 'application' } +group 'superposition' +version '1.0.1' + repositories { - mavenLocal() mavenCentral() } dependencies { implementation 'com.github.jnr:jnr-ffi:2.2.16' implementation 'com.github.jnr:jffi:1.3.13' + // Add other dependencies your library needs } -// Task to create a fat JAR -tasks.register('fatJar', Jar) { - archiveClassifier.set('fat') - from sourceSets.main.output - dependsOn configurations.runtimeClasspath - from { - configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) } - } - manifest { - attributes 'Main-Class': 'CAC.Client' - } - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -// Make the fatJar task run as part of the build -build.dependsOn fatJar - -group = 'com.yourdomain' -version = '1.0-SNAPSHOT' - publishing { - publications { - mavenJava(MavenPublication) { - from components.java + // publications { + // myLib(MavenPublication) { + // from (components.java) + // artifactId = 'CacClient' + // } + // } + repositories { + maven { + name = "GitHubPackages" + url = uri('https://maven.pkg.github.com/juspay/superposition') + credentials { + username = "Superposition Bot" + password = System.getenv("GITHUB_TOKEN") + } } } +} + +application { + mainClassName = 'example.Demo' } \ No newline at end of file diff --git a/clients/java/cac-client/gradle/libs.versions.toml b/clients/java/cac-client/gradle/libs.versions.toml deleted file mode 100644 index dec9eee1..00000000 --- a/clients/java/cac-client/gradle/libs.versions.toml +++ /dev/null @@ -1,10 +0,0 @@ -# This file was generated by the Gradle 'init' task. -# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format - -[versions] -guava = "33.1.0-jre" -junit-jupiter = "5.10.2" - -[libraries] -guava = { module = "com.google.guava:guava", version.ref = "guava" } -junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" } diff --git a/clients/java/cac-client/settings.gradle.kts b/clients/java/cac-client/settings.gradle similarity index 93% rename from clients/java/cac-client/settings.gradle.kts rename to clients/java/cac-client/settings.gradle index 5af1ed09..6f4099e1 100644 --- a/clients/java/cac-client/settings.gradle.kts +++ b/clients/java/cac-client/settings.gradle @@ -10,4 +10,4 @@ plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } -rootProject.name = "superposition" +rootProject.name = 'cac-client' diff --git a/clients/java/cac-client/src/main/java/cac_client/CACClientException.java b/clients/java/cac-client/src/main/java/cac_client/CACClientException.java new file mode 100644 index 00000000..420200a5 --- /dev/null +++ b/clients/java/cac-client/src/main/java/cac_client/CACClientException.java @@ -0,0 +1,7 @@ +package cac_client; + +public class CACClientException extends Exception { + public CACClientException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/clients/java/cac-client/src/main/java/CAC/CacClient.java b/clients/java/cac-client/src/main/java/cac_client/CacClient.java similarity index 92% rename from clients/java/cac-client/src/main/java/CAC/CacClient.java rename to clients/java/cac-client/src/main/java/cac_client/CacClient.java index 559de8a8..3a8ac76e 100644 --- a/clients/java/cac-client/src/main/java/CAC/CacClient.java +++ b/clients/java/cac-client/src/main/java/cac_client/CacClient.java @@ -1,4 +1,4 @@ -package CAC; +package cac_client; import java.io.IOException; @@ -31,18 +31,19 @@ public interface RustLib { public static RustLib rustLib; - public CacClient(String libraryPath, String libraryName) { + public CacClient() { + String libraryName = "cac_client"; + String libraryPath = System.getenv("SUPERPOSITION_LIB_PATH"); + System.out.println("libraryPath" + libraryPath); System.setProperty("jnr.ffi.library.path", libraryPath); - - // Load the Rust library CacClient.rustLib = LibraryLoader.create(RustLib.class).load(libraryName); } - public int cacNewClient(String tenant, long updateFrequency, String hostName) throws IOException { + public int cacNewClient(String tenant, long updateFrequency, String hostName) throws CACClientException { int result = rustLib.cac_new_client(tenant, updateFrequency, hostName); if (result > 0) { String errorMessage = rustLib.cac_last_error_message(); - throw new IOException("Failed to create new CAC client: " + errorMessage); + throw new CACClientException("Failed to create new CAC client: " + errorMessage); } return result; } diff --git a/clients/java/cac-client/src/main/java/CAC/Client.java b/clients/java/cac-client/src/main/java/example/Demo.java similarity index 87% rename from clients/java/cac-client/src/main/java/CAC/Client.java rename to clients/java/cac-client/src/main/java/example/Demo.java index 00d57e74..16c26783 100644 --- a/clients/java/cac-client/src/main/java/CAC/Client.java +++ b/clients/java/cac-client/src/main/java/example/Demo.java @@ -1,32 +1,26 @@ -package CAC; - -import java.io.File; +package example; import java.io.IOException; import java.util.concurrent.CountDownLatch; +import cac_client.CacClient; import jnr.ffi.Pointer; -public class Client { +public class Demo { private static void callCacClient() { - String dylib = "cac_client"; - File currentDir = new File(System.getProperty("user.dir")); - String libraryPath = currentDir.getParentFile().getParentFile().getParentFile() + "/target/debug"; String tenant = "dev"; - System.out.println("------------------------------------------"); - System.out.println("CAC Client"); System.out.println("---------------------"); - CacClient wrapper = new CacClient(libraryPath, dylib); + CacClient wrapper = new CacClient(); int newClient; try { newClient = wrapper.cacNewClient(tenant, 1, "http://localhost:8080"); System.out.println("New client created successfully. Client ID: " + newClient); - } catch (IOException e) { + } catch (cac_client.CACClientException e) { System.err.println(e.getMessage()); } diff --git a/clients/java/exp-client/bin/main/example/Demo.class b/clients/java/exp-client/bin/main/example/Demo.class new file mode 100644 index 00000000..b810ba50 Binary files /dev/null and b/clients/java/exp-client/bin/main/example/Demo.class differ diff --git a/clients/java/exp-client/bin/main/exp_client/EXPClientException.class b/clients/java/exp-client/bin/main/exp_client/EXPClientException.class new file mode 100644 index 00000000..16274135 Binary files /dev/null and b/clients/java/exp-client/bin/main/exp_client/EXPClientException.class differ diff --git a/clients/java/exp-client/bin/main/exp_client/ExperimentationClient$RustLib.class b/clients/java/exp-client/bin/main/exp_client/ExperimentationClient$RustLib.class new file mode 100644 index 00000000..a9a6e37f Binary files /dev/null and b/clients/java/exp-client/bin/main/exp_client/ExperimentationClient$RustLib.class differ diff --git a/clients/java/exp-client/bin/main/exp_client/ExperimentationClient.class b/clients/java/exp-client/bin/main/exp_client/ExperimentationClient.class new file mode 100644 index 00000000..f0d7766d Binary files /dev/null and b/clients/java/exp-client/bin/main/exp_client/ExperimentationClient.class differ diff --git a/clients/java/exp-client/build.gradle b/clients/java/exp-client/build.gradle index 6cfbdcd1..3bf9b0f2 100644 --- a/clients/java/exp-client/build.gradle +++ b/clients/java/exp-client/build.gradle @@ -1,8 +1,13 @@ plugins { + id 'java-library' + id 'maven-publish' id 'java' id 'application' } +group 'superposition' +version '1.0.1' + repositories { mavenCentral() } @@ -10,13 +15,28 @@ repositories { dependencies { implementation 'com.github.jnr:jnr-ffi:2.2.16' implementation 'com.github.jnr:jffi:1.3.13' + // Add other dependencies your library needs } -application { - mainClassName = 'CAC.Client' +publishing { + // publications { + // myLib(MavenPublication) { + // from (components.java) + // artifactId = 'ExpClient' + // } + // } + repositories { + maven { + name = "GitHubPackages" + url = uri('https://maven.pkg.github.com/juspay/superposition') + credentials { + username = "Superposition Bot" + password = System.getenv("GITHUB_TOKEN") + } + } + } } -run { - standardInput = System.in +application { + mainClassName = 'example.Demo' } - diff --git a/clients/java/exp-client/settings.gradle.kts b/clients/java/exp-client/settings.gradle similarity index 93% rename from clients/java/exp-client/settings.gradle.kts rename to clients/java/exp-client/settings.gradle index 5af1ed09..178e0252 100644 --- a/clients/java/exp-client/settings.gradle.kts +++ b/clients/java/exp-client/settings.gradle @@ -10,4 +10,4 @@ plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } -rootProject.name = "superposition" +rootProject.name = "exp-client" diff --git a/clients/java/exp-client/src/main/java/CAC/Client.java b/clients/java/exp-client/src/main/java/example/Demo.java similarity index 90% rename from clients/java/exp-client/src/main/java/CAC/Client.java rename to clients/java/exp-client/src/main/java/example/Demo.java index b32e7007..20f56fbd 100644 --- a/clients/java/exp-client/src/main/java/CAC/Client.java +++ b/clients/java/exp-client/src/main/java/example/Demo.java @@ -1,32 +1,28 @@ -package CAC; +package example; -import java.io.File; import java.io.IOException; import java.util.concurrent.CountDownLatch; +import exp_client.EXPClientException; +import exp_client.ExperimentationClient; import jnr.ffi.Pointer; -public class Client { +public class Demo { private static void callExperimentationClient() { - String dylib = "experimentation_client"; - File currentDir = new File(System.getProperty("user.dir")); - String libraryPath = currentDir.getParentFile().getParentFile().getParentFile() + "/target/debug"; String tenant = "dev"; - - System.out.println("------------------------------------------"); - + System.out.println("Experimentation Client"); System.out.println("---------------------"); - ExperimentationClient wrapper = new ExperimentationClient(libraryPath, dylib); + ExperimentationClient wrapper = new ExperimentationClient(); int newClient; try { newClient = wrapper.exptNewClient(tenant, 1, "http://localhost:8080"); System.out.println("New Experimentation client created successfully. Client ID: " + newClient); - } catch (IOException e) { + } catch (EXPClientException e) { System.err.println(e.getMessage()); } diff --git a/clients/java/exp-client/src/main/java/exp_client/EXPClientException.java b/clients/java/exp-client/src/main/java/exp_client/EXPClientException.java new file mode 100644 index 00000000..a27bce4d --- /dev/null +++ b/clients/java/exp-client/src/main/java/exp_client/EXPClientException.java @@ -0,0 +1,7 @@ +package exp_client; + +public class EXPClientException extends Exception { + public EXPClientException(String message) { + super(message); + } +} diff --git a/clients/java/exp-client/src/main/java/CAC/ExperimentationClient.java b/clients/java/exp-client/src/main/java/exp_client/ExperimentationClient.java similarity index 91% rename from clients/java/exp-client/src/main/java/CAC/ExperimentationClient.java rename to clients/java/exp-client/src/main/java/exp_client/ExperimentationClient.java index ebb1b651..1ae50a80 100644 --- a/clients/java/exp-client/src/main/java/CAC/ExperimentationClient.java +++ b/clients/java/exp-client/src/main/java/exp_client/ExperimentationClient.java @@ -1,4 +1,4 @@ -package CAC; +package exp_client; import java.io.IOException; @@ -31,16 +31,19 @@ public interface RustLib { public static RustLib rustLib; - public ExperimentationClient(String libraryPath, String libraryName) { + public ExperimentationClient() { + String libraryName = "experimentation_client"; + String libraryPath = System.getenv("SUPERPOSITION_LIB_PATH"); + System.out.println("libraryPath" + libraryPath); System.setProperty("jnr.ffi.library.path", libraryPath); ExperimentationClient.rustLib = LibraryLoader.create(RustLib.class).load(libraryName); } - public int exptNewClient(String tenant, long updateFrequency, String hostName) throws IOException { + public int exptNewClient(String tenant, long updateFrequency, String hostName) throws EXPClientException { int result = rustLib.expt_new_client(tenant, updateFrequency, hostName); if (result > 0) { String errorMessage = rustLib.expt_last_error_message(); - throw new IOException("Failed to create new Experimentation client: " + errorMessage); + throw new EXPClientException("Failed to create new Experimentation client: " + errorMessage); } return result; }