From 1a95f2913cb2408a03549b35c38b635f1255597d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jari-Matti=20M=C3=A4kel=C3=A4?= <jmjmak@utu.fi>
Date: Tue, 6 May 2025 10:54:16 +0300
Subject: [PATCH] Switch to JPMS + Junit5 + Maven + JDK collections

---
 .gitignore                                    |   3 +-
 .gitlab-ci.yml                                |  34 +++++
 build.sh                                      |   4 +
 ci_settings.xml                               |  16 ++
 pom.xml                                       | 138 ++++++++++++++++++
 src/main/java/module-info.java                |   5 +
 .../niouring/AbstractIoUringChannel.java      |  11 +-
 src/main/java/sh/blake/niouring/IoUring.java  |   5 +-
 .../blake/niouring/util/ByteBufferUtil.java   |   6 +-
 .../niouring/util/NativeLibraryLoader.java    |  22 ++-
 .../niouring/util/Linux/amd64/libnio_uring.so | Bin 0 -> 17416 bytes
 .../sh/blake/niouring/IoUringFileTest.java    |   8 +-
 .../sh/blake/niouring/IoUringSocketTest.java  |  40 ++---
 13 files changed, 244 insertions(+), 48 deletions(-)
 create mode 100644 .gitlab-ci.yml
 create mode 100644 build.sh
 create mode 100644 ci_settings.xml
 create mode 100644 pom.xml
 create mode 100644 src/main/java/module-info.java
 create mode 100755 src/main/resources/sh/blake/niouring/util/Linux/amd64/libnio_uring.so

diff --git a/.gitignore b/.gitignore
index 73884b9..de25edb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 build/
 .idea/
 .gradle/
-gradle.properties
\ No newline at end of file
+gradle.properties
+target/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..157b878
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,34 @@
+image: maven:3-eclipse-temurin-17
+
+variables:
+  MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true"
+  MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version"
+
+cache:
+  key: "$CI_JOB_NAME"
+  paths:
+    - .m2/repository
+
+stages:
+  - build
+  - deploy
+  
+build:
+  stage: build
+  script:
+    - mkdir -p src/main/resources/sh/blake/niouring/util/Linux/amd64/
+# disabled because compiling the drivers requires a c compiler toolchain
+#    - mvn -P jni compile native:compile native:link
+#    - cp target/libnio_uring.so src/main/resources/sh/blake/niouring/util/Linux/amd64/
+    - mvn install -s ci_settings.xml -DskipTests
+  artifacts:
+    paths:
+      - target/
+
+# build the docker image for the tool, see the Dockerfile for details
+deploy:
+  stage: deploy
+  rules:
+    - if: $CI_COMMIT_TAG
+  script:
+    - mvn deploy -s ci_settings.xml -DskipTests
diff --git a/build.sh b/build.sh
new file mode 100644
index 0000000..6fbce0c
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,4 @@
+mvn -P jni compile native:compile native:link
+mkdir -p src/main/resources/sh/blake/niouring/util/Linux/amd64/
+cp target/libnio_uring.so src/main/resources/sh/blake/niouring/util/Linux/amd64/
+mvn package
diff --git a/ci_settings.xml b/ci_settings.xml
new file mode 100644
index 0000000..59c8c27
--- /dev/null
+++ b/ci_settings.xml
@@ -0,0 +1,16 @@
+<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
+  <servers>
+    <server>
+      <id>gitlab-maven</id>
+      <configuration>
+        <httpHeaders>
+          <property>
+            <name>Job-Token</name>
+            <value>${env.CI_JOB_TOKEN}</value>
+          </property>
+        </httpHeaders>
+      </configuration>
+    </server>
+  </servers>
+</settings>
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..16446a9
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,138 @@
+<project>
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>sh.blake.niouring</groupId>
+    <artifactId>nio_uring-jpms</artifactId>
+    <version>0.1.4</version>
+    <packaging>jar</packaging>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <jdk.version>17</jdk.version>
+        <junit.version>5.10.1</junit.version>
+        <junitplatform.version>1.10.1</junitplatform.version>
+    </properties>
+    <repositories>
+        <repository>
+            <id>central</id>
+            <name>Central Repository</name>
+            <url>https://repo.maven.apache.org/maven2</url>
+        </repository>
+    </repositories>
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-commons</artifactId>
+            <version>${junitplatform.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <profiles>
+        <profile>
+            <id>default</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-compiler-plugin</artifactId>
+                        <version>3.12.1</version>
+                        <configuration>
+                            <release>${jdk.version}</release>
+                            <source>${jdk.version}</source>
+                            <target>${jdk.version}</target>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-jar-plugin</artifactId>
+                        <version>3.3.0</version>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>jni</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-compiler-plugin</artifactId>
+                        <version>3.10.1</version>
+                        <executions>
+                            <execution>
+                                <phase>generate-sources</phase>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <compilerArgs>
+                                <arg>-h</arg>
+                                <arg>${project.build.directory}/include</arg>
+                            </compilerArgs>
+                            <compileSourceRoots>src/main/native</compileSourceRoots>
+                            <outputDirectory>${project.build.directory}/include</outputDirectory>
+                            <release>${jdk.version}</release>
+                            <source>${jdk.version}</source>
+                            <target>${jdk.version}</target>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>native-maven-plugin</artifactId>
+                        <version>1.0-M1</version>
+                        <extensions>true</extensions>
+                        <configuration>
+                            <sources>
+                                <source>
+                                    <directory>src/main/c</directory>
+                                    <includes>
+                                        <include>**/*.c</include>
+                                    </includes>
+                                </source>
+                            </sources>
+                            <linkerFinalName>libnio_uring</linkerFinalName>
+                            <linkerFinalNameExt>so</linkerFinalNameExt>
+                            <compilerStartOptions>
+                                <compilerStartOption>-Os -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux -I${project.build.directory}/include</compilerStartOption>
+                            </compilerStartOptions>
+                            <linkerStartOptions>
+                                <linkerStartOption>-shared</linkerStartOption>
+                            </linkerStartOptions>
+                            <linkerEndOptions>
+                                <linkerEndOption>-luring</linkerEndOption>
+                            </linkerEndOptions>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+    <distributionManagement>
+        <repository>
+            <id>gitlab-maven</id>
+            <url>${env.CI_API_V4_URL}/projects/${env.CI_PROJECT_ID}/packages/maven</url>
+        </repository>
+        <snapshotRepository>
+            <id>gitlab-maven</id>
+            <url>${env.CI_API_V4_URL}/projects/${env.CI_PROJECT_ID}/packages/maven</url>
+        </snapshotRepository>
+    </distributionManagement>
+</project>
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
new file mode 100644
index 0000000..7402204
--- /dev/null
+++ b/src/main/java/module-info.java
@@ -0,0 +1,5 @@
+module sh.blake.niouring {
+    opens sh.blake.niouring;
+    exports sh.blake.niouring;
+    exports sh.blake.niouring.util;
+}
diff --git a/src/main/java/sh/blake/niouring/AbstractIoUringChannel.java b/src/main/java/sh/blake/niouring/AbstractIoUringChannel.java
index 1fcc327..01b4f71 100644
--- a/src/main/java/sh/blake/niouring/AbstractIoUringChannel.java
+++ b/src/main/java/sh/blake/niouring/AbstractIoUringChannel.java
@@ -1,10 +1,11 @@
 package sh.blake.niouring;
 
-import org.eclipse.collections.impl.map.mutable.primitive.LongObjectHashMap;
 import sh.blake.niouring.util.NativeLibraryLoader;
 import sh.blake.niouring.util.ReferenceCounter;
 
 import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.function.Consumer;
 
 /**
@@ -12,8 +13,8 @@ import java.util.function.Consumer;
  */
 public abstract class AbstractIoUringChannel {
     private final int fd;
-    private final LongObjectHashMap<ReferenceCounter<ByteBuffer>> readBufferMap = new LongObjectHashMap<>();
-    private final LongObjectHashMap<ReferenceCounter<ByteBuffer>> writeBufferMap = new LongObjectHashMap<>();
+    private final Map<Long,ReferenceCounter<ByteBuffer>> readBufferMap = new HashMap<>();
+    private final Map<Long,ReferenceCounter<ByteBuffer>> writeBufferMap = new HashMap<>();
     private boolean closed = false;
     private Consumer<ByteBuffer> readHandler;
     private Consumer<ByteBuffer> writeHandler;
@@ -146,7 +147,7 @@ public abstract class AbstractIoUringChannel {
      *
      * @return the read buffer map
      */
-    LongObjectHashMap<ReferenceCounter<ByteBuffer>> readBufferMap() {
+    Map<Long,ReferenceCounter<ByteBuffer>> readBufferMap() {
         return readBufferMap;
     }
 
@@ -155,7 +156,7 @@ public abstract class AbstractIoUringChannel {
      *
      * @return the write buffer map
      */
-    LongObjectHashMap<ReferenceCounter<ByteBuffer>> writeBufferMap() {
+    Map<Long,ReferenceCounter<ByteBuffer>> writeBufferMap() {
         return writeBufferMap;
     }
 
diff --git a/src/main/java/sh/blake/niouring/IoUring.java b/src/main/java/sh/blake/niouring/IoUring.java
index e69cda3..8d12432 100644
--- a/src/main/java/sh/blake/niouring/IoUring.java
+++ b/src/main/java/sh/blake/niouring/IoUring.java
@@ -1,10 +1,11 @@
 package sh.blake.niouring;
 
-import org.eclipse.collections.impl.map.mutable.primitive.IntObjectHashMap;
 import sh.blake.niouring.util.ReferenceCounter;
 import sh.blake.niouring.util.NativeLibraryLoader;
 
 import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.function.Consumer;
 
 /**
@@ -20,7 +21,7 @@ public class IoUring {
 
     private final long ring;
     private final int ringSize;
-    private final IntObjectHashMap<AbstractIoUringChannel> fdToSocket = new IntObjectHashMap<>();
+    private final Map<Integer,AbstractIoUringChannel> fdToSocket = new HashMap<>();
     private Consumer<Exception> exceptionHandler;
     private boolean closed = false;
     private final long cqes;
diff --git a/src/main/java/sh/blake/niouring/util/ByteBufferUtil.java b/src/main/java/sh/blake/niouring/util/ByteBufferUtil.java
index bbad33a..fe5b6e8 100644
--- a/src/main/java/sh/blake/niouring/util/ByteBufferUtil.java
+++ b/src/main/java/sh/blake/niouring/util/ByteBufferUtil.java
@@ -15,7 +15,7 @@ public class ByteBufferUtil {
      * @return the byte buffer
      */
     public static ByteBuffer wrapDirect(byte[] data) {
-        return (ByteBuffer) ByteBuffer.allocateDirect(data.length).put(data).flip();
+        return ByteBuffer.allocateDirect(data.length).put(data).flip();
     }
 
     /**
@@ -26,7 +26,7 @@ public class ByteBufferUtil {
      */
     public static ByteBuffer wrapDirect(String utf8) {
         byte[] data = utf8.getBytes(StandardCharsets.UTF_8);
-        return (ByteBuffer) ByteBuffer.allocateDirect(data.length).put(data).flip();
+        return ByteBuffer.allocateDirect(data.length).put(data).flip();
     }
 
     /**
@@ -41,6 +41,6 @@ public class ByteBufferUtil {
             return buffer;
         }
         buffer.flip();
-        return (ByteBuffer) ByteBuffer.allocateDirect(buffer.remaining()).put(buffer).flip();
+        return ByteBuffer.allocateDirect(buffer.remaining()).put(buffer).flip();
     }
 }
diff --git a/src/main/java/sh/blake/niouring/util/NativeLibraryLoader.java b/src/main/java/sh/blake/niouring/util/NativeLibraryLoader.java
index dbf1617..6f8d849 100644
--- a/src/main/java/sh/blake/niouring/util/NativeLibraryLoader.java
+++ b/src/main/java/sh/blake/niouring/util/NativeLibraryLoader.java
@@ -1,9 +1,9 @@
 package sh.blake.niouring.util;
 
 import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
 
 public class NativeLibraryLoader {
     private static boolean loadAttempted = false;
@@ -16,20 +16,16 @@ public class NativeLibraryLoader {
             }
             loadAttempted = true;
 
-            try (InputStream inputStream = NativeLibraryLoader.class.getResourceAsStream("/libnio_uring.so")) {
-                if (inputStream == null) {
-                    throw new IOException("Native library not found");
-                }
-                File tempFile = File.createTempFile("libnio_uring", ".tmp");
+            var arch = System.getProperty("os.arch");
+            var os = System.getProperty("os.name");
 
-                byte[] buffer = new byte[8192];
-                try (FileOutputStream fileOutputStream = new FileOutputStream(tempFile)) {
-                    while (inputStream.available() > 0) {
-                        int bytesRead = inputStream.read(buffer);
-                        fileOutputStream.write(buffer, 0, bytesRead);
-                    }
-                }
+            try (InputStream inputStream =
+                         NativeLibraryLoader.class.getResourceAsStream(os + "/" + arch + "/libnio_uring.so")) {
+                if (inputStream == null)
+                    throw new IOException("Native library not found");
 
+                File tempFile = File.createTempFile("libnio_uring", ".tmp");
+                Files.write(tempFile.toPath(), inputStream.readAllBytes());
                 System.load(tempFile.getAbsolutePath());
             }
         } catch (IOException ex) {
diff --git a/src/main/resources/sh/blake/niouring/util/Linux/amd64/libnio_uring.so b/src/main/resources/sh/blake/niouring/util/Linux/amd64/libnio_uring.so
new file mode 100755
index 0000000000000000000000000000000000000000..46b8eb9ca5613d86d0af0156d6e80d10f9cc3bdf
GIT binary patch
literal 17416
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
GFaQ9wxVWbP

literal 0
HcmV?d00001

diff --git a/src/test/java/sh/blake/niouring/IoUringFileTest.java b/src/test/java/sh/blake/niouring/IoUringFileTest.java
index 7dcc2d1..ce35f2b 100644
--- a/src/test/java/sh/blake/niouring/IoUringFileTest.java
+++ b/src/test/java/sh/blake/niouring/IoUringFileTest.java
@@ -1,7 +1,7 @@
 package sh.blake.niouring;
 
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
 
 import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
@@ -31,7 +31,7 @@ public class IoUringFileTest extends TestBase {
 
         attemptUntil(ioUring::execute, readSuccessfully::get);
 
-        Assert.assertTrue("File read successfully", readSuccessfully.get());
+        Assertions.assertTrue(readSuccessfully.get(), "File read successfully");
     }
 
     @Test
@@ -62,6 +62,6 @@ public class IoUringFileTest extends TestBase {
         ioUring.queueRead(file, buffer);
         attemptUntil(ioUring::execute, seekSuccessfully::get);
 
-        Assert.assertTrue("File seek successfully", seekSuccessfully.get());
+        Assertions.assertTrue(seekSuccessfully.get(), "File seek successfully");
     }
 }
diff --git a/src/test/java/sh/blake/niouring/IoUringSocketTest.java b/src/test/java/sh/blake/niouring/IoUringSocketTest.java
index 18a5802..f361b3a 100644
--- a/src/test/java/sh/blake/niouring/IoUringSocketTest.java
+++ b/src/test/java/sh/blake/niouring/IoUringSocketTest.java
@@ -1,7 +1,7 @@
 package sh.blake.niouring;
 
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
 import sh.blake.niouring.util.ByteBufferUtil;
 
 import java.nio.ByteBuffer;
@@ -31,16 +31,16 @@ public class IoUringSocketTest extends TestBase {
         });
 
         IoUring ioUring = new IoUring(TEST_RING_SIZE)
-            .onException(Exception::printStackTrace)
-            .queueAccept(serverSocket)
-            .queueConnect(socket);
+                .onException(Exception::printStackTrace)
+                .queueAccept(serverSocket)
+                .queueConnect(socket);
 
         attemptUntil(ioUring::execute, () -> accepted.get() && connected.get());
 
         ioUring.close();
 
-        Assert.assertTrue("Server accepted connection", accepted.get());
-        Assert.assertTrue("Client connected", connected.get());
+        Assertions.assertTrue(accepted.get(), "Server accepted connection");
+        Assertions.assertTrue(connected.get(), "Client connected");
     }
 
     @Test
@@ -58,9 +58,9 @@ public class IoUringSocketTest extends TestBase {
         socket.onException(ex -> exceptionProduced.set(true));
 
         IoUring ioUring = new IoUring(TEST_RING_SIZE)
-            .onException(Exception::printStackTrace)
-            .queueAccept(serverSocket)
-            .queueConnect(socket);
+                .onException(Exception::printStackTrace)
+                .queueAccept(serverSocket)
+                .queueConnect(socket);
 
         attemptUntil(ioUring::execute, exceptionProduced::get);
 
@@ -68,8 +68,8 @@ public class IoUringSocketTest extends TestBase {
         serverSocket.close();
         socket.close();
 
-        Assert.assertFalse("Server accepted connection", accepted.get());
-        Assert.assertTrue("Client to connect (wrong port)", exceptionProduced.get());
+        Assertions.assertFalse(accepted.get(), "Server accepted connection");
+        Assertions.assertTrue(exceptionProduced.get(), "Client to connect (wrong port)");
     }
 
     @Test
@@ -108,18 +108,18 @@ public class IoUringSocketTest extends TestBase {
         });
 
         IoUring ioUring = new IoUring(TEST_RING_SIZE)
-            .onException(Exception::printStackTrace)
-            .queueAccept(serverSocket)
-            .queueConnect(socket);
+                .onException(Exception::printStackTrace)
+                .queueAccept(serverSocket)
+                .queueConnect(socket);
 
         attemptUntil(ioUring::execute, () ->
-            serverAccepted.get() && clientConnected.get() && serverSent.get() && clientReceived.get());
+                serverAccepted.get() && clientConnected.get() && serverSent.get() && clientReceived.get());
 
         ioUring.close();
 
-        Assert.assertTrue("Server accepted connection", serverAccepted.get());
-        Assert.assertTrue("Server sent data", serverSent.get());
-        Assert.assertTrue("Client connected", clientConnected.get());
-        Assert.assertTrue("Client received data", clientReceived.get());
+        Assertions.assertTrue(serverAccepted.get(), "Server accepted connection");
+        Assertions.assertTrue(serverSent.get(), "Server sent data");
+        Assertions.assertTrue(clientConnected.get(), "Client connected");
+        Assertions.assertTrue(clientReceived.get(), "Client received data");
     }
 }
-- 
GitLab