New Upstream Release - junixsocket

Ready changes

Summary

Merged new upstream version: 2.6.2 (was: 2.6.1).

Diff

diff --git a/.github/workflows/codeql-analysis-c.yml b/.github/workflows/codeql-analysis-c.yml
deleted file mode 100644
index a5e642a..0000000
--- a/.github/workflows/codeql-analysis-c.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-# For most projects, this workflow file will not need changing; you simply need
-# to commit it to your repository.
-#
-# You may wish to alter this file to override the set of languages analyzed,
-# or to provide custom queries or build logic.
-#
-# ******** NOTE ********
-# We have attempted to detect the languages in your repository. Please check
-# the `language` matrix defined below to confirm you have the correct set of
-# supported CodeQL languages.
-#
-name: "CodeQL C"
-
-on:
-  push:
-    branches: [ "main", "dev", "wip" ]
-  pull_request:
-    # The branches below must be a subset of the branches above
-    branches: [ "main", "dev", "wip" ]
-  schedule:
-    - cron: '39 16 * * 3'
-
-jobs:
-  analyze:
-    name: Analyze C
-    runs-on: ubuntu-latest
-    permissions:
-      actions: read
-      contents: read
-      security-events: write
-
-    strategy:
-      fail-fast: true
-      matrix:
-        language: [ 'cpp' ]
-        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
-        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
-
-    steps:
-    - name: Checkout repository
-      uses: actions/checkout@v3
-
-    # Initializes the CodeQL tools for scanning.
-    - name: Initialize CodeQL
-      uses: github/codeql-action/init@v2
-      with:
-        languages: ${{ matrix.language }}
-        # If you wish to specify custom queries, you can do so here or in a config file.
-        # By default, queries listed here will override any specified in a config file.
-        # Prefix the list here with "+" to use these queries and those in the config file.
-
-        # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
-        # queries: security-extended,security-and-quality
-
-    - run: |
-       echo "Build junixsocket-native with Maven (no tests)"
-       mvn clean install -Pcodeql -pl junixsocket-native -Dignorant
-
-    - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@v2
diff --git a/.github/workflows/codeql-analysis-java.yml b/.github/workflows/codeql-analysis.yml
similarity index 93%
rename from .github/workflows/codeql-analysis-java.yml
rename to .github/workflows/codeql-analysis.yml
index 94cee34..c0b3873 100644
--- a/.github/workflows/codeql-analysis-java.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -9,7 +9,7 @@
 # the `language` matrix defined below to confirm you have the correct set of
 # supported CodeQL languages.
 #
-name: "CodeQL Java"
+name: "CodeQL"
 
 on:
   push:
@@ -22,7 +22,7 @@ on:
 
 jobs:
   analyze:
-    name: Analyze Java
+    name: Analyze
     runs-on: ubuntu-latest
     permissions:
       actions: read
@@ -32,7 +32,7 @@ jobs:
     strategy:
       fail-fast: true
       matrix:
-        language: [ 'java' ]
+        language: [ 'cpp', 'java' ]
         # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
         # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
 
@@ -54,7 +54,7 @@ jobs:
 
     - run: |
        echo "Build junixsocket with Maven (no tests)"
-       mvn clean install -Pcodeql -Pcodeql-skip-c
+       mvn clean install -Pcodeql -Pstrict -Puse-snapshots
 
     - name: Perform CodeQL Analysis
       uses: github/codeql-action/analyze@v2
diff --git a/README.md b/README.md
index 9c63074..5e9c9a6 100644
--- a/README.md
+++ b/README.md
@@ -72,7 +72,7 @@ To include the core junixsocket functionality in your project, add the following
 <dependency>
   <groupId>com.kohlschutter.junixsocket</groupId>
   <artifactId>junixsocket-core</artifactId>
-  <version>2.6.1</version>
+  <version>2.6.2</version>
   <type>pom</type>
 </dependency>
 ```
diff --git a/debian/changelog b/debian/changelog
index 32ecc9d..d84892e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+junixsocket (2.6.2-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Sat, 11 Mar 2023 22:29:53 -0000
+
 junixsocket (2.6.1-1) unstable; urgency=medium
 
   * Team upload.
diff --git a/debian/patches/0001-Use-jni-headers-from-system.patch b/debian/patches/0001-Use-jni-headers-from-system.patch
index 76b06a5..b871831 100644
--- a/debian/patches/0001-Use-jni-headers-from-system.patch
+++ b/debian/patches/0001-Use-jni-headers-from-system.patch
@@ -7,10 +7,10 @@ Forwarded: not-needed
  junixsocket-native/src/main/c/config.h | 4 ----
  1 file changed, 4 deletions(-)
 
-diff --git a/junixsocket-native/src/main/c/config.h b/junixsocket-native/src/main/c/config.h
-index 777db64..982065c 100644
---- a/junixsocket-native/src/main/c/config.h
-+++ b/junixsocket-native/src/main/c/config.h
+Index: junixsocket.git/junixsocket-native/src/main/c/config.h
+===================================================================
+--- junixsocket.git.orig/junixsocket-native/src/main/c/config.h
++++ junixsocket.git/junixsocket-native/src/main/c/config.h
 @@ -33,10 +33,6 @@ CK_IGNORE_UNUSED_MACROS_END
  #  define _NETBSD_SOURCE
  #endif
diff --git a/debian/patches/0002-Native-library-loading.patch b/debian/patches/0002-Native-library-loading.patch
index 39639eb..7d684c0 100644
--- a/debian/patches/0002-Native-library-loading.patch
+++ b/debian/patches/0002-Native-library-loading.patch
@@ -10,19 +10,19 @@ Forwarded: not-needed
  .../src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java     | 5 +++++
  1 file changed, 5 insertions(+)
 
-diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
-index eb225b1..c089030 100644
---- a/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
-+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
-@@ -329,6 +329,11 @@ final class NativeLibraryLoader implements Closeable {
- 
+Index: junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
++++ junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
+@@ -330,6 +330,11 @@ final class NativeLibraryLoader implemen
    private List<LibraryCandidate> initLibraryCandidates(List<Throwable> suppressedThrowables) {
      List<LibraryCandidate> candidates = new ArrayList<>();
-+    try {
+     try {
 +      candidates.add(new StandardLibraryCandidate("system"));
 +    } catch (Exception e) {
 +      suppressedThrowables.add(e);
 +    }
-     try {
++    try {
        candidates.add(new StandardLibraryCandidate(getArtifactVersion(getClass(),
            "junixsocket-common", "junixsocket-core")));
+     } catch (Exception e) {
diff --git a/debian/patches/0003-Fix-compiletime-annotations-requirement.patch b/debian/patches/0003-Fix-compiletime-annotations-requirement.patch
index c1393eb..fcc0c33 100644
--- a/debian/patches/0003-Fix-compiletime-annotations-requirement.patch
+++ b/debian/patches/0003-Fix-compiletime-annotations-requirement.patch
@@ -38,10 +38,10 @@ Forwarded: not-needed
  27 files changed, 39 insertions(+), 28 deletions(-)
  create mode 100644 junixsocket-common/src/main/java/org/newsclub/net/unix/SuppressFBWarnings.java
 
-diff --git a/junixsocket-common/pom.xml b/junixsocket-common/pom.xml
-index 7d4bd17..15db4ac 100644
---- a/junixsocket-common/pom.xml
-+++ b/junixsocket-common/pom.xml
+Index: junixsocket.git/junixsocket-common/pom.xml
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/pom.xml
++++ junixsocket.git/junixsocket-common/pom.xml
 @@ -70,5 +70,9 @@
              <classifier>default</classifier>
              <optional>true</optional>
@@ -52,10 +52,10 @@ index 7d4bd17..15db4ac 100644
 +        </dependency>
      </dependencies>
  </project>
-diff --git a/junixsocket-common/src/main/java/module-info.java b/junixsocket-common/src/main/java/module-info.java
-index 849cfa9..ba2d8dc 100644
---- a/junixsocket-common/src/main/java/module-info.java
-+++ b/junixsocket-common/src/main/java/module-info.java
+Index: junixsocket.git/junixsocket-common/src/main/java/module-info.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/src/main/java/module-info.java
++++ junixsocket.git/junixsocket-common/src/main/java/module-info.java
 @@ -6,6 +6,5 @@ module org.newsclub.net.unix {
  
    requires java.base;
@@ -63,10 +63,10 @@ index 849cfa9..ba2d8dc 100644
 -  requires static com.kohlschutter.annotations.compiletime;
    requires static org.eclipse.jdt.annotation;
  }
-diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramChannel.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramChannel.java
-index 6655800..d420834 100644
---- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramChannel.java
-+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramChannel.java
+Index: junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramChannel.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramChannel.java
++++ junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramChannel.java
 @@ -33,7 +33,6 @@ import java.util.Set;
  
  import org.eclipse.jdt.annotation.Nullable;
@@ -75,11 +75,11 @@ index 6655800..d420834 100644
  
  /**
   * A {@link DatagramChannel} implementation that works with junixsocket.
-diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocket.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocket.java
-index d35194d..6d34e92 100644
---- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocket.java
-+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocket.java
-@@ -32,7 +32,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
+Index: junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocket.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocket.java
++++ junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocket.java
+@@ -32,7 +32,6 @@ import java.util.concurrent.atomic.Atomi
  
  import org.eclipse.jdt.annotation.Nullable;
  
@@ -87,10 +87,10 @@ index d35194d..6d34e92 100644
  
  /**
   * A {@link DatagramSocket} implementation that works with junixsocket.
-diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFPipe.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFPipe.java
-index 15f733e..5755ad8 100644
---- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFPipe.java
-+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFPipe.java
+Index: junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFPipe.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/src/main/java/org/newsclub/net/unix/AFPipe.java
++++ junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFPipe.java
 @@ -24,7 +24,6 @@ import java.nio.ByteBuffer;
  import java.nio.channels.Pipe;
  import java.nio.channels.spi.SelectorProvider;
@@ -99,11 +99,11 @@ index 15f733e..5755ad8 100644
  
  /**
   * A {@link Pipe}, natively implemented.
-diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocket.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocket.java
-index d99fb10..b448553 100644
---- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocket.java
-+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocket.java
-@@ -30,7 +30,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
+Index: junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocket.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocket.java
++++ junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocket.java
+@@ -30,7 +30,6 @@ import java.util.concurrent.atomic.Atomi
  import org.eclipse.jdt.annotation.NonNull;
  import org.eclipse.jdt.annotation.Nullable;
  
@@ -111,10 +111,10 @@ index d99fb10..b448553 100644
  
  /**
   * The server part of a junixsocket socket.
-diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocketChannel.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocketChannel.java
-index 87dd4c5..f5446c6 100644
---- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocketChannel.java
-+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocketChannel.java
+Index: junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocketChannel.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocketChannel.java
++++ junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocketChannel.java
 @@ -29,7 +29,6 @@ import java.util.Set;
  
  import org.eclipse.jdt.annotation.NonNull;
@@ -123,11 +123,11 @@ index 87dd4c5..f5446c6 100644
  
  /**
   * A selectable channel for stream-oriented listening sockets.
-diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocket.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocket.java
-index 6df312e..0a92d34 100644
---- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocket.java
-+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocket.java
-@@ -29,7 +29,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
+Index: junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocket.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocket.java
++++ junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocket.java
+@@ -29,7 +29,6 @@ import java.util.concurrent.atomic.Atomi
  import org.eclipse.jdt.annotation.NonNull;
  import org.eclipse.jdt.annotation.Nullable;
  
@@ -135,11 +135,11 @@ index 6df312e..0a92d34 100644
  
  /**
   * junixsocket's base implementation of a {@link Socket}.
-diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketChannel.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketChannel.java
-index 5c05353..563f2b1 100644
---- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketChannel.java
-+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketChannel.java
-@@ -30,7 +30,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
+Index: junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketChannel.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketChannel.java
++++ junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketChannel.java
+@@ -30,7 +30,6 @@ import java.util.concurrent.atomic.Atomi
  
  import org.eclipse.jdt.annotation.NonNull;
  
@@ -147,10 +147,10 @@ index 5c05353..563f2b1 100644
  
  /**
   * A selectable channel for stream-oriented connecting sockets.
-diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSelectorProvider.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSelectorProvider.java
-index 9dbf834..076482a 100644
---- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSelectorProvider.java
-+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSelectorProvider.java
+Index: junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSelectorProvider.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSelectorProvider.java
++++ junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSelectorProvider.java
 @@ -23,7 +23,6 @@ import java.net.SocketAddress;
  
  import org.eclipse.jdt.annotation.NonNull;
@@ -159,10 +159,10 @@ index 9dbf834..076482a 100644
  
  /**
   * Service-provider class for junixsocket selectors and selectable channels.
-diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AncillaryDataSupport.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AncillaryDataSupport.java
-index e6c6376..f04a38c 100644
---- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AncillaryDataSupport.java
-+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AncillaryDataSupport.java
+Index: junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AncillaryDataSupport.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/src/main/java/org/newsclub/net/unix/AncillaryDataSupport.java
++++ junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/AncillaryDataSupport.java
 @@ -28,7 +28,6 @@ import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
@@ -171,10 +171,10 @@ index e6c6376..f04a38c 100644
  
  final class AncillaryDataSupport implements Closeable {
    private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0);
-diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorCast.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorCast.java
-index e77caa5..cfe0136 100644
---- a/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorCast.java
-+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorCast.java
+Index: junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorCast.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorCast.java
++++ junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorCast.java
 @@ -36,7 +36,6 @@ import java.util.function.Function;
  
  import org.eclipse.jdt.annotation.NonNull;
@@ -183,10 +183,10 @@ index e77caa5..cfe0136 100644
  
  /**
   * Provides object-oriented access to file descriptors via {@link InputStream}, {@link Socket},
-diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
-index c089030..be1bfaa 100644
---- a/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
-+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
+Index: junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
++++ junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
 @@ -30,7 +30,6 @@ import java.util.List;
  import java.util.Objects;
  import java.util.Properties;
@@ -195,11 +195,11 @@ index c089030..be1bfaa 100644
  
  @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE")
  final class NativeLibraryLoader implements Closeable {
-diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeUnixSocket.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeUnixSocket.java
-index 18ef5de..d28cde7 100644
---- a/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeUnixSocket.java
-+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeUnixSocket.java
-@@ -31,8 +31,6 @@ import java.nio.channels.spi.AbstractSelectableChannel;
+Index: junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeUnixSocket.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeUnixSocket.java
++++ junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeUnixSocket.java
+@@ -31,8 +31,6 @@ import java.nio.channels.spi.AbstractSel
  
  import org.newsclub.net.unix.AFSelector.PollFd;
  
@@ -216,11 +216,10 @@ index 18ef5de..d28cde7 100644
    private NativeUnixSocket() {
      throw new UnsupportedOperationException("No instances");
    }
-diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/SuppressFBWarnings.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/SuppressFBWarnings.java
-new file mode 100644
-index 0000000..fc5171a
+Index: junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/SuppressFBWarnings.java
+===================================================================
 --- /dev/null
-+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/SuppressFBWarnings.java
++++ junixsocket.git/junixsocket-common/src/main/java/org/newsclub/net/unix/SuppressFBWarnings.java
 @@ -0,0 +1,26 @@
 +/*
 + * junixsocket
@@ -248,10 +247,10 @@ index 0000000..fc5171a
 +public @interface SuppressFBWarnings {
 +  String[] value() default {};
 +}
-diff --git a/junixsocket-rmi/src/main/java/module-info.java b/junixsocket-rmi/src/main/java/module-info.java
-index acac404..90e03bd 100644
---- a/junixsocket-rmi/src/main/java/module-info.java
-+++ b/junixsocket-rmi/src/main/java/module-info.java
+Index: junixsocket.git/junixsocket-rmi/src/main/java/module-info.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-rmi/src/main/java/module-info.java
++++ junixsocket.git/junixsocket-rmi/src/main/java/module-info.java
 @@ -8,6 +8,5 @@ module org.newsclub.net.unix.rmi {
  
    exports org.newsclub.net.unix.rmi;
@@ -259,11 +258,11 @@ index acac404..90e03bd 100644
 -  requires static com.kohlschutter.annotations.compiletime;
    requires static org.eclipse.jdt.annotation;
  }
-diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNaming.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNaming.java
-index 9bb43c1..36f7764 100644
---- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNaming.java
-+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNaming.java
-@@ -43,7 +43,7 @@ import org.eclipse.jdt.annotation.NonNull;
+Index: junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNaming.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNaming.java
++++ junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNaming.java
+@@ -43,7 +43,7 @@ import org.eclipse.jdt.annotation.NonNul
  import org.newsclub.net.unix.AFSocket;
  import org.newsclub.net.unix.rmi.ShutdownHookSupport.ShutdownHook;
  
@@ -272,10 +271,10 @@ index 9bb43c1..36f7764 100644
  
  /**
   * The {@link AFSocket}-compatible equivalent of {@link Naming}. Use this class for accessing RMI
-diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIServiceImpl.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIServiceImpl.java
-index 01d5083..46ab824 100644
---- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIServiceImpl.java
-+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIServiceImpl.java
+Index: junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIServiceImpl.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIServiceImpl.java
++++ junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIServiceImpl.java
 @@ -34,7 +34,7 @@ import java.util.concurrent.Executors;
  import java.util.concurrent.ThreadLocalRandom;
  import java.util.stream.IntStream;
@@ -285,10 +284,10 @@ index 01d5083..46ab824 100644
  
  /**
   * A very simple implementation of a {@link AFRMIService}.
-diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMISocketFactory.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMISocketFactory.java
-index 820fdfa..cc91fac 100644
---- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMISocketFactory.java
-+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMISocketFactory.java
+Index: junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMISocketFactory.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMISocketFactory.java
++++ junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMISocketFactory.java
 @@ -38,7 +38,7 @@ import org.newsclub.net.unix.AFSocket;
  import org.newsclub.net.unix.AFSocketAddress;
  import org.newsclub.net.unix.rmi.ShutdownHookSupport.ShutdownHook;
@@ -298,10 +297,10 @@ index 820fdfa..cc91fac 100644
  
  /**
   * An {@link RMISocketFactory} that supports {@link AFSocket}s.
-diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistry.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistry.java
-index c2402bb..f003356 100644
---- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistry.java
-+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistry.java
+Index: junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistry.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistry.java
++++ junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistry.java
 @@ -34,7 +34,7 @@ import java.util.concurrent.TimeUnit;
  
  import org.newsclub.net.unix.rmi.ShutdownHookSupport.ShutdownHook;
@@ -311,11 +310,11 @@ index c2402bb..f003356 100644
  
  /**
   * A wrapper for RMI registries, both remote and local, to allow for a clean removal of bound
-diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRMISocketFactory.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRMISocketFactory.java
-index 4f101db..94def2f 100644
---- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRMISocketFactory.java
-+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRMISocketFactory.java
-@@ -35,7 +35,7 @@ import org.newsclub.net.unix.AFUNIXSocketAddress;
+Index: junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRMISocketFactory.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRMISocketFactory.java
++++ junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRMISocketFactory.java
+@@ -35,7 +35,7 @@ import org.newsclub.net.unix.AFUNIXSocke
  import org.newsclub.net.unix.AFUNIXSocketCredentials;
  import org.newsclub.net.unix.HostAndPort;
  
@@ -324,10 +323,10 @@ index 4f101db..94def2f 100644
  
  /**
   * An {@link RMISocketFactory} that supports {@link AFUNIXSocket}s.
-diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RMIPorts.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RMIPorts.java
-index 246e302..79f5358 100644
---- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RMIPorts.java
-+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RMIPorts.java
+Index: junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RMIPorts.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RMIPorts.java
++++ junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RMIPorts.java
 @@ -19,7 +19,6 @@ package org.newsclub.net.unix.rmi;
  
  import org.newsclub.net.unix.AFSocket;
@@ -344,11 +343,11 @@ index 246e302..79f5358 100644
    private RMIPorts() {
      throw new UnsupportedOperationException("No instances");
    }
-diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptorBase.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptorBase.java
-index 32a4a12..0f94525 100644
---- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptorBase.java
-+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptorBase.java
-@@ -42,7 +42,7 @@ import org.newsclub.net.unix.AFUNIXSocket;
+Index: junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptorBase.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptorBase.java
++++ junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptorBase.java
+@@ -40,7 +40,7 @@ import org.newsclub.net.unix.AFUNIXSocke
  import org.newsclub.net.unix.FileDescriptorAccess;
  import org.newsclub.net.unix.server.AFSocketServer;
  
@@ -357,11 +356,11 @@ index 32a4a12..0f94525 100644
  
  /**
   * A wrapper that allows a {@link FileDescriptor} be sent via RMI over AF_UNIX sockets.
-diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemotePeerInfo.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemotePeerInfo.java
-index 4b7a7b7..cf889a8 100644
---- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemotePeerInfo.java
-+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemotePeerInfo.java
-@@ -27,7 +27,7 @@ import java.rmi.server.RemoteObjectInvocationHandler;
+Index: junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemotePeerInfo.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemotePeerInfo.java
++++ junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemotePeerInfo.java
+@@ -27,7 +27,7 @@ import java.rmi.server.RemoteObjectInvoc
  
  import org.newsclub.net.unix.AFUNIXSocketCredentials;
  
@@ -370,10 +369,10 @@ index 4b7a7b7..cf889a8 100644
  
  /**
   * Information about the remote connection.
-diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/ShutdownHookSupport.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/ShutdownHookSupport.java
-index be4500b..50ff2a2 100644
---- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/ShutdownHookSupport.java
-+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/ShutdownHookSupport.java
+Index: junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/ShutdownHookSupport.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/ShutdownHookSupport.java
++++ junixsocket.git/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/ShutdownHookSupport.java
 @@ -21,7 +21,7 @@ import java.lang.ref.WeakReference;
  import java.util.ArrayList;
  import java.util.List;
@@ -383,10 +382,10 @@ index be4500b..50ff2a2 100644
  
  /**
   * Simplifies handling shutdown hooks.
-diff --git a/junixsocket-server/src/main/java/module-info.java b/junixsocket-server/src/main/java/module-info.java
-index 2c826f8..10c0ce7 100644
---- a/junixsocket-server/src/main/java/module-info.java
-+++ b/junixsocket-server/src/main/java/module-info.java
+Index: junixsocket.git/junixsocket-server/src/main/java/module-info.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-server/src/main/java/module-info.java
++++ junixsocket.git/junixsocket-server/src/main/java/module-info.java
 @@ -5,6 +5,5 @@ module org.newsclub.net.unix.server {
    exports org.newsclub.net.unix.server;
  
@@ -394,11 +393,11 @@ index 2c826f8..10c0ce7 100644
 -  requires static com.kohlschutter.annotations.compiletime;
    requires org.eclipse.jdt.annotation;
  }
-diff --git a/junixsocket-server/src/main/java/org/newsclub/net/unix/server/SocketServer.java b/junixsocket-server/src/main/java/org/newsclub/net/unix/server/SocketServer.java
-index 7cea541..882669f 100644
---- a/junixsocket-server/src/main/java/org/newsclub/net/unix/server/SocketServer.java
-+++ b/junixsocket-server/src/main/java/org/newsclub/net/unix/server/SocketServer.java
-@@ -39,7 +39,7 @@ import org.eclipse.jdt.annotation.NonNull;
+Index: junixsocket.git/junixsocket-server/src/main/java/org/newsclub/net/unix/server/SocketServer.java
+===================================================================
+--- junixsocket.git.orig/junixsocket-server/src/main/java/org/newsclub/net/unix/server/SocketServer.java
++++ junixsocket.git/junixsocket-server/src/main/java/org/newsclub/net/unix/server/SocketServer.java
+@@ -39,7 +39,7 @@ import org.eclipse.jdt.annotation.NonNul
  import org.newsclub.net.unix.AFServerSocket;
  import org.newsclub.net.unix.AFSocketAddress;
  
diff --git a/junixsocket-codecoverage/pom.xml b/junixsocket-codecoverage/pom.xml
index 20ba3ea..a23509a 100644
--- a/junixsocket-codecoverage/pom.xml
+++ b/junixsocket-codecoverage/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-codecoverage</name>
diff --git a/junixsocket-common/pom.xml b/junixsocket-common/pom.xml
index 7d4bd17..e556b4c 100644
--- a/junixsocket-common/pom.xml
+++ b/junixsocket-common/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-common</name>
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFAddressFamily.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFAddressFamily.java
index 6164953..a1f0480 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFAddressFamily.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFAddressFamily.java
@@ -39,7 +39,7 @@ import org.newsclub.net.unix.AFSocketAddress.AFSocketAddressConstructor;
 
 /**
  * Describes an address family supported by junixsocket.
- * 
+ *
  * @param <A> The corresponding {@link AFSocketAddress} subclass.
  * @author Christian Kohlschütter
  */
@@ -179,7 +179,7 @@ public final class AFAddressFamily<A extends AFSocketAddress> {
 
   /**
    * Registers an address family.
-   * 
+   *
    * @param <A> The supported address type.
    * @param juxString The sockaddr_* identifier as registered in native code.
    * @param addressClass The supported address subclass.
@@ -226,7 +226,7 @@ public final class AFAddressFamily<A extends AFSocketAddress> {
 
   /**
    * Registers an implementation.
-   * 
+   *
    * @param <A> The supported address type.
    * @param juxString The sockaddr_* identifier as registered in native code.
    * @param addressFamily The supported address family as registered via
@@ -274,7 +274,7 @@ public final class AFAddressFamily<A extends AFSocketAddress> {
 
   /**
    * Creates a new, unconnected, unbound socket compatible with this socket address.
-   * 
+   *
    * @return The socket instance.
    * @throws IOException on error.
    */
@@ -288,7 +288,7 @@ public final class AFAddressFamily<A extends AFSocketAddress> {
 
   /**
    * Creates a new, unconnected, unbound server socket compatible with this socket address.
-   * 
+   *
    * @return The server socket instance.
    * @throws IOException on error.
    */
@@ -302,7 +302,7 @@ public final class AFAddressFamily<A extends AFSocketAddress> {
 
   /**
    * Creates a new, unconnected, unbound {@link SocketChannel} compatible with this socket address.
-   * 
+   *
    * @return The socket instance.
    * @throws IOException on error.
    */
@@ -313,7 +313,7 @@ public final class AFAddressFamily<A extends AFSocketAddress> {
   /**
    * Creates a new, unconnected, unbound {@link ServerSocketChannel} compatible with this socket
    * address.
-   * 
+   *
    * @return The socket instance.
    * @throws IOException on error.
    */
@@ -330,10 +330,10 @@ public final class AFAddressFamily<A extends AFSocketAddress> {
 
   /**
    * Returns the set of supported URI schemes that can be parsed to some {@link AFSocketAddress}.
-   * 
+   *
    * The set is dependent on which {@link AFSocketAddress} implementations are registered with
    * junixsocket.
-   * 
+   *
    * @return The set of supported URI schemes.
    */
   public static synchronized Set<String> uriSchemes() {
@@ -344,7 +344,7 @@ public final class AFAddressFamily<A extends AFSocketAddress> {
   /**
    * Returns the {@link SelectorProvider} associated with this address family, or {@code null} if no
    * such instance is registered.
-   * 
+   *
    * @return The {@link SelectorProvider}.
    * @throws IllegalStateException on error.
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFAddressFamilyConfig.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFAddressFamilyConfig.java
index 88f4a52..24ee4a9 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFAddressFamilyConfig.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFAddressFamilyConfig.java
@@ -26,7 +26,7 @@ import java.nio.channels.SocketChannel;
 
 /**
  * The implementation-specifics for a given address family implementation.
- * 
+ *
  * @param <A> The supported address type.
  * @author Christian Kohlschütter
  * @see AFSocketAddressConfig
@@ -41,63 +41,63 @@ public abstract class AFAddressFamilyConfig<A extends AFSocketAddress> {
 
   /**
    * Returns the implementation's {@link Socket} class.
-   * 
+   *
    * @return The implementation's {@link Socket} class.
    */
   protected abstract Class<? extends AFSocket<A>> socketClass();
 
   /**
    * Returns the implementation's {@link Socket} constructor.
-   * 
+   *
    * @return The implementation's {@link Socket} constructor.
    */
   protected abstract AFSocket.Constructor<A> socketConstructor();
 
   /**
    * Returns the implementation's {@link ServerSocket} class.
-   * 
+   *
    * @return The implementation's {@link ServerSocket} class.
    */
   protected abstract Class<? extends AFServerSocket<A>> serverSocketClass();
 
   /**
    * Returns the implementation's {@link ServerSocket} constructor.
-   * 
+   *
    * @return The implementation's {@link ServerSocket} constructor.
    */
   protected abstract AFServerSocket.Constructor<A> serverSocketConstructor();
 
   /**
    * Returns the implementation's {@link SocketChannel} class.
-   * 
+   *
    * @return The implementation's {@link SocketChannel} class..
    */
   protected abstract Class<? extends AFSocketChannel<A>> socketChannelClass();
 
   /**
    * Returns the implementation's {@link ServerSocketChannel} class.
-   * 
+   *
    * @return The implementation's {@link ServerSocketChannel} class.
    */
   protected abstract Class<? extends AFServerSocketChannel<A>> serverSocketChannelClass();
 
   /**
    * Returns the implementation's {@link DatagramSocket} class.
-   * 
+   *
    * @return The implementation's {@link DatagramSocket} class.
    */
   protected abstract Class<? extends AFDatagramSocket<A>> datagramSocketClass();
 
   /**
    * Returns the implementation's {@link DatagramSocket} constructor.
-   * 
+   *
    * @return The implementation's {@link DatagramSocket} constructor.
    */
   protected abstract AFDatagramSocket.Constructor<A> datagramSocketConstructor();
 
   /**
    * Returns the implementation's {@link DatagramChannel} class.
-   * 
+   *
    * @return The implementation's {@link DatagramChannel} class.
    */
   protected abstract Class<? extends AFDatagramChannel<A>> datagramChannelClass();
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFCore.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFCore.java
index 0b67705..84b9ac3 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFCore.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFCore.java
@@ -26,7 +26,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * The core functionality of file descriptor based I/O.
- * 
+ *
  * @author Christian Kohlschütter
  */
 class AFCore extends CleanableState {
@@ -176,16 +176,19 @@ class AFCore extends CleanableState {
     }
 
     int pos = src.position();
-
     boolean isDirect = src.isDirect();
     ByteBuffer buf;
+    int bufPos;
     if (isDirect) {
       buf = src;
+      bufPos = pos;
     } else {
       buf = getThreadLocalDirectByteBuffer(remaining);
       remaining = Math.min(remaining, buf.remaining());
 
-      // Java 16: buf.put(buf.position(), src, src.position(), Math.min(buf.limit(), src.limit()));
+      bufPos = buf.position();
+
+      // Java 16: buf.put(bufPos, src, src.position(), Math.min(buf.limit(), src.limit()));
       int limit = src.limit();
       if (limit > buf.limit()) {
         src.limit(buf.limit());
@@ -195,13 +198,13 @@ class AFCore extends CleanableState {
         buf.put(src);
       }
 
-      buf.position(0);
+      buf.position(bufPos);
     }
     if (datagramMode) {
       options |= NativeUnixSocket.OPT_DGRAM_MODE;
     }
 
-    int written = NativeUnixSocket.send(fdesc, buf, pos, remaining, addressTo, addressToLen,
+    int written = NativeUnixSocket.send(fdesc, buf, bufPos, remaining, addressTo, addressToLen,
         options, ancillaryDataSupport);
     src.position(pos + written);
 
@@ -210,11 +213,11 @@ class AFCore extends CleanableState {
 
   /**
    * Returns a per-thread reusable byte buffer for a given capacity.
-   * 
+   *
    * If a thread-local buffer currently uses a smaller capacity, the buffer is replaced by a larger
    * one. If the capacity exceeds a configurable maximum, a new direct buffer is allocated but not
    * cached (i.e., the previously cached one is kept but not immediately returned to the caller).
-   * 
+   *
    * @param capacity The desired capacity.
    * @return A byte buffer satisfying the requested capacity.
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramChannel.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramChannel.java
index 6655800..fec4b01 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramChannel.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramChannel.java
@@ -37,8 +37,9 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * A {@link DatagramChannel} implementation that works with junixsocket.
- * 
+ *
  * @author Christian Kohlschütter
+ * @param <A> The supported address type.
  */
 public abstract class AFDatagramChannel<A extends AFSocketAddress> extends DatagramChannel
     implements AFSomeSocket, AFSocketExtensions {
@@ -46,7 +47,7 @@ public abstract class AFDatagramChannel<A extends AFSocketAddress> extends Datag
 
   /**
    * Creates a new {@link AFDatagramChannel} instance.
-   * 
+   *
    * @param selectorProvider The corresponding {@link SelectorProvider}.
    * @param socket The corresponding {@link Socket}.
    */
@@ -57,7 +58,7 @@ public abstract class AFDatagramChannel<A extends AFSocketAddress> extends Datag
 
   /**
    * Returns the corresponding {@link Socket}.
-   * 
+   *
    * @return The socket.
    */
   protected final AFDatagramSocket<A> getAFSocket() {
@@ -91,7 +92,7 @@ public abstract class AFDatagramChannel<A extends AFSocketAddress> extends Datag
 
   /**
    * Returns the binding state of the socket.
-   * 
+   *
    * @return true if the socket successfully bound to an address
    */
   public final boolean isBound() {
@@ -244,10 +245,10 @@ public abstract class AFDatagramChannel<A extends AFSocketAddress> extends Datag
 
   /**
    * Checks if this {@link DatagramSocket}'s bound filename should be removed upon {@link #close()}.
-   * 
+   *
    * Deletion is not guaranteed, especially when not supported (e.g., addresses in the abstract
    * namespace).
-   * 
+   *
    * @return {@code true} if an attempt is made to delete the socket file upon {@link #close()}.
    */
   public final boolean isDeleteOnClose() {
@@ -256,10 +257,10 @@ public abstract class AFDatagramChannel<A extends AFSocketAddress> extends Datag
 
   /**
    * Enables/disables deleting this {@link DatagramSocket}'s bound filename upon {@link #close()}.
-   * 
+   *
    * Deletion is not guaranteed, especially when not supported (e.g., addresses in the abstract
    * namespace).
-   * 
+   *
    * @param b Enabled if {@code true}.
    */
   public final void setDeleteOnClose(boolean b) {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocket.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocket.java
index d35194d..d2ad3ab 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocket.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocket.java
@@ -36,12 +36,12 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * A {@link DatagramSocket} implementation that works with junixsocket.
- * 
+ *
  * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
  * @author Christian Kohlschütter
  */
-public abstract class AFDatagramSocket<A extends AFSocketAddress> extends DatagramSocket implements
-    AFSomeSocket, AFSocketExtensions {
+public abstract class AFDatagramSocket<A extends AFSocketAddress> extends DatagramSocketShim
+    implements AFSomeSocket, AFSocketExtensions {
   private static final InetSocketAddress WILDCARD_ADDRESS = new InetSocketAddress(0);
 
   private final AFDatagramSocketImpl<A> impl;
@@ -52,7 +52,7 @@ public abstract class AFDatagramSocket<A extends AFSocketAddress> extends Datagr
 
   /**
    * Creates a new {@link AFDatagramSocket} instance.
-   * 
+   *
    * @param impl The corresponding {@link SocketImpl} class.
    * @throws IOException on error.
    */
@@ -64,14 +64,14 @@ public abstract class AFDatagramSocket<A extends AFSocketAddress> extends Datagr
 
   /**
    * Creates a new {@link DatagramChannel} that is associated with this socket.
-   * 
+   *
    * @return The channel.
    */
   protected abstract AFDatagramChannel<A> newChannel();
 
   /**
    * Returns the {@link AncillaryDataSupport} instance.
-   * 
+   *
    * @return The instance.
    */
   protected final AncillaryDataSupport getAncillaryDataSupport() {
@@ -80,14 +80,14 @@ public abstract class AFDatagramSocket<A extends AFSocketAddress> extends Datagr
 
   /**
    * A reference to the constructor of an {@link AFDatagramSocket} subclass.
-   * 
+   *
    * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
    */
   @FunctionalInterface
   public interface Constructor<A extends AFSocketAddress> {
     /**
      * Constructs a new {@link DatagramSocket} instance.
-     * 
+     *
      * @param fd The file descriptor.
      * @return The new instance.
      * @throws IOException on error.
@@ -97,7 +97,7 @@ public abstract class AFDatagramSocket<A extends AFSocketAddress> extends Datagr
 
   /**
    * Returns the {@link AFSocketAddress} type supported by this socket.
-   * 
+   *
    * @return The supported {@link AFSocketAddress}.
    */
   protected final Class<? extends AFSocketAddress> socketAddressClass() {
@@ -119,7 +119,7 @@ public abstract class AFDatagramSocket<A extends AFSocketAddress> extends Datagr
 
   /**
    * Creates a new {@link AFDatagramSocket}.
-   * 
+   *
    * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
    * @param constructor The supplying constructor.
    * @param fdObj The file descriptor.
@@ -169,12 +169,12 @@ public abstract class AFDatagramSocket<A extends AFSocketAddress> extends Datagr
 
   /**
    * Reads the next received packet without actually removing it from the queue.
-   * 
+   *
    * In other words, once a packet is received, calling this method multiple times in a row will not
    * have further effects on the packet contents.
-   * 
+   *
    * This call still blocks until at least one packet has been received and added to the queue.
-   * 
+   *
    * @param p The packet.
    * @throws IOException on error.
    */
@@ -328,10 +328,10 @@ public abstract class AFDatagramSocket<A extends AFSocketAddress> extends Datagr
   /**
    * Checks if this {@link AFDatagramSocket}'s bound filename should be removed upon
    * {@link #close()}.
-   * 
+   *
    * Deletion is not guaranteed, especially when not supported (e.g., addresses in the abstract
    * namespace).
-   * 
+   *
    * @return {@code true} if an attempt is made to delete the socket file upon {@link #close()}.
    */
   public final boolean isDeleteOnClose() {
@@ -340,10 +340,10 @@ public abstract class AFDatagramSocket<A extends AFSocketAddress> extends Datagr
 
   /**
    * Enables/disables deleting this {@link AFDatagramSocket}'s bound filename upon {@link #close()}.
-   * 
+   *
    * Deletion is not guaranteed, especially when not supported (e.g., addresses in the abstract
    * namespace).
-   * 
+   *
    * @param b Enabled if {@code true}.
    */
   public final void setDeleteOnClose(boolean b) {
@@ -407,7 +407,7 @@ public abstract class AFDatagramSocket<A extends AFSocketAddress> extends Datagr
 
   /**
    * Returns the address family supported by this implementation.
-   * 
+   *
    * @return The family.
    */
   protected final AFAddressFamily<A> addressFamily() {
@@ -416,7 +416,7 @@ public abstract class AFDatagramSocket<A extends AFSocketAddress> extends Datagr
 
   /**
    * Returns the internal helper instance for address-specific extensions.
-   * 
+   *
    * @return The helper instance.
    * @throws UnsupportedOperationException if such extensions are not supported for this address
    *           type.
@@ -424,4 +424,32 @@ public abstract class AFDatagramSocket<A extends AFSocketAddress> extends Datagr
   protected AFSocketImplExtensions<A> getImplExtensions() {
     return getAFImpl(false).getImplExtensions();
   }
+
+  /**
+   * Returns the value of a junixsocket socket option.
+   *
+   * @param <T> The type of the socket option value.
+   * @param name The socket option.
+   * @return The value of the socket option.
+   * @throws IOException on error.
+   */
+  @Override
+  public <T> T getOption(AFSocketOption<T> name) throws IOException {
+    return getAFImpl().getCore().getOption(name);
+  }
+
+  /**
+   * Sets the value of a socket option.
+   *
+   * @param <T> The type of the socket option value.
+   * @param name The socket option.
+   * @param value The value of the socket option.
+   * @return this DatagramSocket.
+   * @throws IOException on error.
+   */
+  @Override
+  public <T> DatagramSocket setOption(AFSocketOption<T> name, T value) throws IOException {
+    getAFImpl().getCore().setOption(name, value);
+    return this;
+  }
 }
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocketImpl.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocketImpl.java
index b132008..2ce8941 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocketImpl.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFDatagramSocketImpl.java
@@ -36,7 +36,7 @@ import org.eclipse.jdt.annotation.Nullable;
 
 /**
  * A {@link DatagramSocketImpl} implemented by junixsocket.
- * 
+ *
  * @param <A> The associated address type.
  * @author Christian Kohlschütter
  */
@@ -56,7 +56,7 @@ public abstract class AFDatagramSocketImpl<A extends AFSocketAddress> extends
   /**
    * Constructs a new {@link AFDatagramSocketImpl} using the given {@link FileDescriptor} (or null
    * to create a new one).
-   * 
+   *
    * @param addressFamily The address family.
    * @param fd The file descriptor, or {@code null}.
    * @param socketType The socket type.
@@ -375,7 +375,7 @@ public abstract class AFDatagramSocketImpl<A extends AFSocketAddress> extends
 
   /**
    * Returns the address family supported by this implementation.
-   * 
+   *
    * @return The family.
    */
   protected final AFAddressFamily<@NonNull A> getAddressFamily() {
@@ -384,7 +384,7 @@ public abstract class AFDatagramSocketImpl<A extends AFSocketAddress> extends
 
   /**
    * Returns the internal helper instance for address-specific extensions.
-   * 
+   *
    * @return The helper instance.
    * @throws UnsupportedOperationException if such extensions are not supported for this address
    *           type.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFInetAddress.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFInetAddress.java
index 311e428..b7ab0b5 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFInetAddress.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFInetAddress.java
@@ -36,17 +36,17 @@ import java.util.Objects;
 
 /**
  * A workaround to create an {@link InetAddress} for an {@link AFSocketAddress}.
- * 
+ *
  * {@link DatagramPacket} internally requires InetAddress compatibility. Even if it pretends to
  * accept {@link SocketAddress}es, it refuses anything other than {@link InetSocketAddress}
  * <em>and</em> then even stores host and port separately.
- * 
+ *
  * This implementation deserializes a specially crafted {@link InetAddress} with a hostname that
  * encodes the raw bytes of an {@link AFSocketAddress}. We do this because the deserialization code
  * path does not attempt DNS resolution (which would fail one way or another).
- * 
+ *
  * The hostnames we use end with ".junixsocket", to distinguish them from regular hostnames.
- * 
+ *
  * @author Christian Kohlschütter
  */
 class AFInetAddress {
@@ -94,12 +94,12 @@ class AFInetAddress {
   /**
    * Encodes a junixsocket socketAddress into a string that is (somewhat) guaranteed to not be
    * resolved by java.net code.
-   * 
+   *
    * Implementation detail: The "[" prefix (with the corresponding "]" suffix missing from the
    * input) should cause an early {@link UnknownHostException} be thrown, which is caught within
    * {@link InetSocketAddress#InetSocketAddress(String, int)}, causing the hostname be marked as
    * "unresolved" (without an address set).
-   * 
+   *
    * @param socketAddress The socket address.
    * @return A string, to be used when calling
    *         {@link InetSocketAddress#InetSocketAddress(String, int)}, etc.
@@ -141,7 +141,7 @@ class AFInetAddress {
    * address), without actually having to resolve the address via DNS, thus still carrying the
    * "hostname" field containing a hostname as returned by
    * {@link #createUnresolvedHostname(byte[])}.
-   * 
+   *
    * @param socketAddress The socket address.
    * @return The {@link InetAddress}.
    */
@@ -182,7 +182,7 @@ class AFInetAddress {
     try {
       return unwrapAddress(hostname, af);
     } catch (IllegalArgumentException e) {
-      throw (SocketException)new SocketException("Unsupported address").initCause(e);
+      throw (SocketException) new SocketException("Unsupported address").initCause(e);
     }
   }
 
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFInputStream.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFInputStream.java
index dc2423e..fc36095 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFInputStream.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFInputStream.java
@@ -21,7 +21,7 @@ import java.io.InputStream;
 
 /**
  * An {@link InputStream} for {@link AFSocket}, etc.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public abstract class AFInputStream extends InputStream implements FileDescriptorAccess {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFOutputStream.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFOutputStream.java
index 531cbbb..b91a7e3 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFOutputStream.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFOutputStream.java
@@ -23,7 +23,7 @@ import java.io.OutputStream;
 
 /**
  * An {@link OutputStream} for {@link AFSocket}, etc.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public abstract class AFOutputStream extends OutputStream implements FileDescriptorAccess {
@@ -37,11 +37,11 @@ public abstract class AFOutputStream extends OutputStream implements FileDescrip
    * Reads all bytes from the given input stream and writes the bytes to this output stream in the
    * order that they are read. On return, this input stream will be at end of stream. This method
    * does not close either stream.
-   * 
+   *
    * This method effectively is the reverse notation of
    * {@link InputStream#transferTo(OutputStream)}, which may or may not be optimized for
    * {@link AFSocket}s.
-   * 
+   *
    * @param in The {@link InputStream} to transfer from.
    * @return The number of bytes transferred.
    * @throws IOException on error.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFPipe.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFPipe.java
index 15f733e..ef1ca6e 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFPipe.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFPipe.java
@@ -28,7 +28,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * A {@link Pipe}, natively implemented.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFPipe extends Pipe implements Closeable {
@@ -172,7 +172,7 @@ public final class AFPipe extends Pipe implements Closeable {
 
   /**
    * Returns the options bitmask that is to be passed to native receive/send calls.
-   * 
+   *
    * @return The options.
    */
   int getOptions() {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSelectorProvider.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSelectorProvider.java
index 5fb4a4c..efc3bc6 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSelectorProvider.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSelectorProvider.java
@@ -27,7 +27,7 @@ import org.eclipse.jdt.annotation.NonNull;
 
 /**
  * Service-provider class for junixsocket selectors and selectable channels.
- * 
+ *
  * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
  */
 public abstract class AFSelectorProvider<A extends AFSocketAddress> extends SelectorProvider {
@@ -41,7 +41,7 @@ public abstract class AFSelectorProvider<A extends AFSocketAddress> extends Sele
 
   /**
    * Constructs a new pipe.
-   * 
+   *
    * @param selectable {@code true} if the pipe should be selectable.
    * @return The pipe.
    * @throws IOException on error.
@@ -52,7 +52,7 @@ public abstract class AFSelectorProvider<A extends AFSocketAddress> extends Sele
 
   /**
    * Constructs a new socket pair from two sockets.
-   * 
+   *
    * @param <Y> The type of the pair.
    * @param s1 Some socket, the first one.
    * @param s2 Some socket, the second one.
@@ -62,7 +62,7 @@ public abstract class AFSelectorProvider<A extends AFSocketAddress> extends Sele
 
   /**
    * Constructs a new socket.
-   * 
+   *
    * @return The socket instance.
    * @throws IOException on error.
    */
@@ -70,21 +70,21 @@ public abstract class AFSelectorProvider<A extends AFSocketAddress> extends Sele
 
   /**
    * Returns the protocol family supported by this implementation.
-   * 
+   *
    * @return The protocol family.
    */
   protected abstract ProtocolFamily protocolFamily();
 
   /**
    * Returns the address family supported by this implementation.
-   * 
+   *
    * @return The address family.
    */
   protected abstract AFAddressFamily<@NonNull A> addressFamily();
 
   /**
    * Returns the domain ID for the supported protocol, as specified by {@link NativeUnixSocket}.
-   * 
+   *
    * @return The domain ID.
    */
   protected final int domainId() {
@@ -93,7 +93,7 @@ public abstract class AFSelectorProvider<A extends AFSocketAddress> extends Sele
 
   /**
    * Opens a socket pair of interconnected channels.
-   * 
+   *
    * @return The new channel pair.
    * @throws IOException on error.
    */
@@ -113,7 +113,7 @@ public abstract class AFSelectorProvider<A extends AFSocketAddress> extends Sele
 
   /**
    * Opens a socket pair of interconnected datagram channels.
-   * 
+   *
    * @return The new channel pair.
    * @throws IOException on error.
    */
@@ -152,7 +152,7 @@ public abstract class AFSelectorProvider<A extends AFSocketAddress> extends Sele
 
   /**
    * Opens a pipe with support for selectors.
-   * 
+   *
    * @return The new pipe
    * @throws IOException on error.
    */
@@ -185,7 +185,7 @@ public abstract class AFSelectorProvider<A extends AFSocketAddress> extends Sele
 
   /**
    * Opens a socket channel connected to the given {@link SocketAddress}.
-   * 
+   *
    * @param sa The socket address to connect to.
    * @return The new channel
    * @throws IOException on error.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocket.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocket.java
index d99fb10..d37213b 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocket.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocket.java
@@ -34,7 +34,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * The server part of a junixsocket socket.
- * 
+ *
  * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
  * @author Christian Kohlschütter
  */
@@ -50,13 +50,13 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * The constructor of the concrete subclass.
-   * 
+   *
    * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
    */
   public interface Constructor<A extends AFSocketAddress> {
     /**
      * Creates a new {@link AFServerSocket} instance.
-     * 
+     *
      * @param fd The file descriptor.
      * @return The new instance.
      * @throws IOException on error.
@@ -67,7 +67,7 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * Constructs a new, unconnected instance.
-   * 
+   *
    * @throws IOException if the operation fails.
    */
   protected AFServerSocket() throws IOException {
@@ -76,7 +76,7 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * Constructs a new instance, optionally associated with the given file descriptor.
-   * 
+   *
    * @param fdObj The file descriptor, or {@code null}.
    * @throws IOException if the operation fails.
    */
@@ -90,14 +90,14 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * Creates a new AFServerSocketChannel for this socket.
-   * 
+   *
    * @return The new instance.
    */
   protected abstract AFServerSocketChannel<?> newChannel();
 
   /**
    * Creates a new AFSocketImpl.
-   * 
+   *
    * @param fdObj The file descriptor.
    * @return The new instance.
    * @throws IOException on error.
@@ -106,7 +106,7 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * Creates a new AFServerSocket instance, using the given subclass constructor.
-   * 
+   *
    * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
    * @param instanceSupplier The subclass constructor.
    * @return The new instance.
@@ -119,7 +119,7 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * Creates a new AFServerSocket instance, using the given subclass constructor.
-   * 
+   *
    * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
    * @param instanceSupplier The subclass constructor.
    * @param fdObj The file descriptor.
@@ -163,7 +163,7 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * Returns a new {@link ServerSocket} that is bound to the given {@link AFSocketAddress}.
-   * 
+   *
    * @param instanceSupplier The constructor of the concrete subclass.
    * @param addr The socket file to bind to.
    * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
@@ -179,7 +179,7 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * Returns a new {@link ServerSocket} that is bound to the given {@link AFSocketAddress}.
-   * 
+   *
    * @param instanceSupplier The constructor of the concrete subclass.
    * @param addr The socket file to bind to.
    * @param deleteOnClose If {@code true}, the socket file (if the address points to a file) will be
@@ -199,7 +199,7 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
   /**
    * Returns a new, <em>unbound</em> {@link ServerSocket} that will always bind to the given
    * address, regardless of any socket address used in a call to <code>bind</code>.
-   * 
+   *
    * @param instanceSupplier The constructor of the concrete subclass.
    * @param forceAddr The address to use.
    * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
@@ -216,7 +216,7 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
    * Forces the address to be used for any subsequent call to {@link #bind(SocketAddress)} to be the
    * given one, regardless of what'll be passed to {@link #bind(SocketAddress, int)}, but doesn't
    * bind yet.
-   * 
+   *
    * @param endpoint The forced endpoint address.
    * @return This {@link AFServerSocket}.
    */
@@ -323,7 +323,7 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * Returns a new {@link AFSocket} instance.
-   * 
+   *
    * @return The new instance.
    * @throws IOException on error.
    */
@@ -381,7 +381,7 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * Registers a {@link Closeable} that should be closed when this socket is closed.
-   * 
+   *
    * @param closeable The closeable.
    */
   public final void addCloseable(Closeable closeable) {
@@ -390,7 +390,7 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * Unregisters a previously registered {@link Closeable}.
-   * 
+   *
    * @param closeable The closeable.
    */
   public final void removeCloseable(Closeable closeable) {
@@ -399,7 +399,7 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * Checks whether everything is setup to support junixsocket sockets.
-   * 
+   *
    * @return {@code true} if supported.
    */
   public static boolean isSupported() {
@@ -417,10 +417,10 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * Checks if the local socket address returned by {@link #getLocalSocketAddress()} is still valid.
-   * 
+   *
    * The address is no longer valid if the server socket has been closed, {@code null}, or another
    * server socket has been bound on that address.
-   * 
+   *
    * @return {@code true} iff still valid.
    */
   public boolean isLocalSocketAddressValid() {
@@ -460,10 +460,10 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * Checks if this {@link AFServerSocket}'s file should be removed upon {@link #close()}.
-   * 
+   *
    * Deletion is not guaranteed, especially when not supported (e.g., addresses in the abstract
    * namespace).
-   * 
+   *
    * @return {@code true} if an attempt is made to delete the socket file upon {@link #close()}.
    */
   public final boolean isDeleteOnClose() {
@@ -473,10 +473,10 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
   /**
    * Enables/disables deleting this {@link AFServerSocket}'s file (or other resource type) upon
    * {@link #close()}.
-   * 
+   *
    * Deletion is not guaranteed, especially when not supported (e.g., addresses in the abstract
    * namespace).
-   * 
+   *
    * @param b Enabled if {@code true}.
    */
   public final void setDeleteOnClose(boolean b) {
@@ -507,7 +507,7 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
 
   /**
    * Returns the address family supported by this implementation.
-   * 
+   *
    * @return The family.
    */
   protected final AFAddressFamily<A> addressFamily() {
@@ -517,9 +517,9 @@ public abstract class AFServerSocket<A extends AFSocketAddress> extends ServerSo
   /**
    * Sets the hook for any subsequent call to {@link #bind(SocketAddress)} and
    * {@link #bind(SocketAddress, int)} to be the given function.
-   * 
+   *
    * The function can monitor calls or even alter the endpoint address.
-   * 
+   *
    * @param hook The function that gets called for each {@code bind} call.
    * @return This instance.
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocketChannel.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocketChannel.java
index 87dd4c5..cd774e1 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocketChannel.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocketChannel.java
@@ -33,7 +33,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * A selectable channel for stream-oriented listening sockets.
- * 
+ *
  * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
  * @author Christian Kohlschütter
  */
@@ -43,7 +43,7 @@ public abstract class AFServerSocketChannel<A extends AFSocketAddress> extends S
 
   /**
    * Creates a new {@link AFServerSocketChannel} instance.
-   * 
+   *
    * @param socket The corresponding {@link ServerSocket}.
    * @param sp The corresponding {@link SelectorProvider}.
    */
@@ -116,10 +116,10 @@ public abstract class AFServerSocketChannel<A extends AFSocketAddress> extends S
 
   /**
    * Checks if the local socket address returned by {@link #getLocalAddress()} is still valid.
-   * 
+   *
    * The address is no longer valid if the server socket has been closed, {@code null}, or another
    * server socket has been bound on that address.
-   * 
+   *
    * @return {@code true} iff still valid.
    */
   public final boolean isLocalSocketAddressValid() {
@@ -147,10 +147,10 @@ public abstract class AFServerSocketChannel<A extends AFSocketAddress> extends S
 
   /**
    * Checks if this {@link AFServerSocketChannel}'s file should be removed upon {@link #close()}.
-   * 
+   *
    * Deletion is not guaranteed, especially when not supported (e.g., addresses in the abstract
    * namespace).
-   * 
+   *
    * @return {@code true} if an attempt is made to delete the socket file upon {@link #close()}.
    */
   public final boolean isDeleteOnClose() {
@@ -160,10 +160,10 @@ public abstract class AFServerSocketChannel<A extends AFSocketAddress> extends S
   /**
    * Enables/disables deleting this {@link AFServerSocketChannel}'s file (or other resource type)
    * upon {@link #close()}.
-   * 
+   *
    * Deletion is not guaranteed, especially when not supported (e.g., addresses in the abstract
    * namespace).
-   * 
+   *
    * @param b Enabled if {@code true}.
    */
   public final void setDeleteOnClose(boolean b) {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocketConnector.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocketConnector.java
new file mode 100644
index 0000000..a8558dd
--- /dev/null
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFServerSocketConnector.java
@@ -0,0 +1,41 @@
+/*
+ * junixsocket
+ *
+ * Copyright 2009-2022 Christian Kohlschütter
+ *
+ * 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 org.newsclub.net.unix;
+
+import java.io.IOException;
+
+/**
+ * Some connector that is able to create {@link AFServerSocket}s bound to a given
+ * {@link AFSocketAddress}.
+ *
+ * @param <A> The address type to bind to.
+ * @param <T> The address type for the returned server socket (which should either be identical to
+ *          {@code A} or {@link AFSocketAddress} to indicate that this could be any socket).
+ * @author Christian Kohlschütter
+ * @see AFSocketConnector
+ */
+public interface AFServerSocketConnector<A extends AFSocketAddress, T extends AFSocketAddress> {
+  /**
+   * Creates an {@link AFServerSocket} bound to the given address.
+   *
+   * @param addr The address to bind to.
+   * @return The bound socket.
+   * @throws IOException on error.
+   */
+  AFServerSocket<? extends T> bind(A addr) throws IOException;
+}
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocket.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocket.java
index 6df312e..4e06ec5 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocket.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocket.java
@@ -33,7 +33,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * junixsocket's base implementation of a {@link Socket}.
- * 
+ *
  * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
  * @author Christian Kohlschütter
  */
@@ -60,7 +60,7 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
 
   /**
    * Creates a new {@link AFSocket} instance.
-   * 
+   *
    * @param impl The corresponding {@link SocketImpl} class.
    * @param afh The conversion helper to get a socket address from an encoded hostname.
    * @throws SocketException on error.
@@ -74,7 +74,7 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
 
   /**
    * Returns the {@link AFSocketAddress} type supported by this socket.
-   * 
+   *
    * @return The supported {@link AFSocketAddress}.
    */
   protected final Class<? extends AFSocketAddress> socketAddressClass() {
@@ -83,21 +83,21 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
 
   /**
    * Creates a new {@link AFSocketChannel} for this socket.
-   * 
+   *
    * @return The new instance.
    */
   protected abstract AFSocketChannel<A> newChannel();
 
   /**
    * The reference to the constructor of an {@link AFSocket} subclass.
-   * 
+   *
    * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
    */
   @FunctionalInterface
   public interface Constructor<A extends AFSocketAddress> {
     /**
      * Constructs a new {@link AFSocket} subclass instance.
-     * 
+     *
      * @param fdObj The file descriptor.
      * @param factory The socket factory instance.
      * @return The instance.
@@ -141,12 +141,12 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
 
   /**
    * Creates a new, unbound {@link AFSocket}.
-   * 
+   *
    * This "default" implementation is a bit "lenient" with respect to the specification.
-   * 
+   *
    * In particular, we may ignore calls to {@link Socket#getTcpNoDelay()} and
    * {@link Socket#setTcpNoDelay(boolean)}.
-   * 
+   *
    * @param <A> The corresponding address type.
    * @param constr The implementation's {@link AFSocket} constructor
    * @param factory The corresponding socket factory, or {@code null}.
@@ -166,7 +166,7 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
 
   /**
    * Creates a new {@link AFSocket} and connects it to the given {@link AFSocketAddress}.
-   * 
+   *
    * @param <A> The corresponding address type.
    * @param constr The implementation's {@link AFSocket} constructor
    * @param addr The address to connect to.
@@ -183,7 +183,7 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
   /**
    * Creates a new {@link AFSocket} and connects it to the given {@link AFSocketAddress} using the
    * default implementation suited for that address type.
-   * 
+   *
    * @param <A> The corresponding address type.
    * @param addr The address to connect to.
    * @return A new, connected socket.
@@ -198,7 +198,7 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
 
   /**
    * Not supported, since it's not necessary for client sockets.
-   * 
+   *
    * @see AFServerSocket
    */
   @Override
@@ -302,10 +302,10 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
 
   /**
    * Returns <code>true</code> iff {@link AFSocket}s are supported by the current Java VM.
-   * 
+   *
    * To support {@link AFSocket}s, a custom JNI library must be loaded that is supplied with
    * <em>junixsocket</em>.
-   * 
+   *
    * @return {@code true} iff supported.
    */
   public static boolean isSupported() {
@@ -314,9 +314,9 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
 
   /**
    * Checks if {@link AFSocket}s are supported by the current Java VM.
-   * 
+   *
    * If not, an {@link UnsupportedOperationException} is thrown.
-   * 
+   *
    * @throws UnsupportedOperationException if not supported.
    */
   public static void ensureSupported() throws UnsupportedOperationException {
@@ -325,9 +325,9 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
 
   /**
    * Returns the version of the junixsocket library, as a string, for debugging purposes.
-   * 
+   *
    * NOTE: Do not rely on the format of the version identifier, use socket capabilities instead.
-   * 
+   *
    * @return String The version identifier, or {@code null} if it could not be determined.
    * @see #supports(AFSocketCapability)
    */
@@ -342,9 +342,9 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
   /**
    * Returns an identifier of the loaded native library, or {@code null} if the library hasn't been
    * loaded yet.
-   * 
+   *
    * The identifier is useful mainly for debugging purposes.
-   * 
+   *
    * @return The identifier of the loaded junixsocket-native library, or {@code null}.
    */
   public static final String getLoadedLibrary() {
@@ -400,12 +400,12 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
   /**
    * Checks if the current environment (system platform, native library, etc.) supports a given
    * junixsocket capability.
-   * 
+   *
    * Deprecated. Please use {@link #supports(AFSocketCapability)} instead.
-   * 
+   *
    * NOTE: The result may or may not be cached from a previous call or from a check upon
    * initialization.
-   * 
+   *
    * @param capability The capability.
    * @return true if supported.
    * @see #supports(AFSocketCapability)
@@ -418,10 +418,10 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
   /**
    * Checks if the current environment (system platform, native library, etc.) supports a given
    * junixsocket capability.
-   * 
+   *
    * NOTE: The result may or may not be cached from a previous call or from a check upon
    * initialization.
-   * 
+   *
    * @param capability The capability.
    * @return true if supported.
    */
@@ -442,7 +442,7 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
 
   /**
    * Registers a {@link Closeable} that should be closed when this socket is closed.
-   * 
+   *
    * @param closeable The closeable.
    */
   public final void addCloseable(Closeable closeable) {
@@ -451,7 +451,7 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
 
   /**
    * Unregisters a previously registered {@link Closeable}.
-   * 
+   *
    * @param closeable The closeable.
    */
   public final void removeCloseable(Closeable closeable) {
@@ -514,7 +514,7 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
 
   /**
    * Returns the internal helper instance for address-specific extensions.
-   * 
+   *
    * @return The helper instance.
    * @throws UnsupportedOperationException if such extensions are not supported for this address
    *           type.
@@ -526,7 +526,7 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
   /**
    * Forces the address to be used for any subsequent call to {@link #connect(SocketAddress)} to be
    * the given one, regardless of what'll be passed there.
-   * 
+   *
    * @param endpoint The forced endpoint address.
    * @return This instance.
    */
@@ -539,9 +539,9 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
   /**
    * Sets the hook for any subsequent call to {@link #connect(SocketAddress)} or
    * {@link #connect(SocketAddress, int)} to be the given function.
-   * 
+   *
    * The function can monitor events or even alter the target address.
-   * 
+   *
    * @param hook The function that gets called for each connect call.
    * @return This instance.
    */
@@ -552,10 +552,10 @@ public abstract class AFSocket<A extends AFSocketAddress> extends Socket impleme
 
   /**
    * Probes the status of the socket connection.
-   * 
+   *
    * This usually involves checking for {@link #isConnected()}, and if assumed connected, also
    * sending a zero-length message to the remote.
-   * 
+   *
    * @return {@code true} if the connection is known to be closed, {@code false} if the connection
    *         is open/not closed or the condition is unknown.
    * @throws IOException on an unexpected error.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketAddress.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketAddress.java
index 13ff3a5..eea3cdb 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketAddress.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketAddress.java
@@ -21,6 +21,8 @@ import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
@@ -39,7 +41,7 @@ import org.eclipse.jdt.annotation.Nullable;
 
 /**
  * Some {@link SocketAddress} that is supported by junixsocket, such as {@link AFUNIXSocketAddress}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public abstract class AFSocketAddress extends InetSocketAddress {
@@ -87,16 +89,17 @@ public abstract class AFSocketAddress extends InetSocketAddress {
   /**
    * The system-native representation of this address, or {@code null}.
    */
-  private final ByteBuffer nativeAddress;
+  @SuppressWarnings("PMD.ImmutableField")
+  private transient ByteBuffer nativeAddress;
 
   /**
    * The address family.
    */
-  private final AFAddressFamily<?> addressFamily;
+  private transient AFAddressFamily<?> addressFamily;
 
   /**
    * Creates a new socket address.
-   * 
+   *
    * @param port The port.
    * @param socketAddress The socket address in junixsocket-specific byte-array representation.
    * @param nativeAddress The socket address in system-native representation.
@@ -108,7 +111,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
     /*
      * Initializing the superclass with an unresolved hostname helps us pass the #equals and
      * #hashCode checks, which unfortunately are declared final in InetSocketAddress.
-     * 
+     *
      * Using a resolved address (with the address bit initialized) would be ideal, but resolved
      * addresses can only be IPv4 or IPv6 (at least as of Java 16 and earlier).
      */
@@ -136,7 +139,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Only for {@link SentinelSocketAddress}.
-   * 
+   *
    * @param clazz The {@link SentinelSocketAddress} class.
    * @param port A sentinel port number.
    */
@@ -150,17 +153,17 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Checks if the address can be resolved to a {@link File}.
-   * 
+   *
    * @return {@code true} if the address has a filename.
    */
   public abstract boolean hasFilename();
 
   /**
    * Returns the {@link File} corresponding with this address, if possible.
-   * 
+   *
    * A {@link FileNotFoundException} is thrown if there is no filename associated with the address,
    * which applies to addresses in the abstract namespace, for example.
-   * 
+   *
    * @return The filename.
    * @throws FileNotFoundException if the address is not associated with a filename.
    */
@@ -168,7 +171,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Returns the corresponding {@link AFAddressFamily}.
-   * 
+   *
    * @return The address family instance.
    */
   public final AFAddressFamily<?> getAddressFamily() {
@@ -177,7 +180,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Wraps the socket name/peer name of a file descriptor as an {@link InetAddress}.
-   * 
+   *
    * @param fdesc The file descriptor.
    * @param peerName If {@code true}, the remote peer name (instead of the local name) is retrieved.
    * @param af The address family.
@@ -197,7 +200,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Gets the socket name/peer name of a file descriptor as an {@link AFSocketAddress}.
-   * 
+   *
    * @param <A> The corresponding address type.
    * @param fdesc The file descriptor.
    * @param peerName If {@code true}, the remote peer name (instead of the local name) is retrieved.
@@ -259,7 +262,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Returns the (non-native) byte-level representation of this address.
-   * 
+   *
    * @return The byte array.
    */
   protected final byte[] getBytes() {
@@ -269,12 +272,12 @@ public abstract class AFSocketAddress extends InetSocketAddress {
   /**
    * Returns a "special" {@link InetAddress} that contains information about this
    * {@link AFSocketAddress}.
-   * 
+   *
    * IMPORTANT: This {@link InetAddress} does not properly compare (using
    * {@link InetAddress#equals(Object)} and {@link InetAddress#hashCode()}). It should be used
    * exclusively to circumvent existing APIs like {@link DatagramSocket} that only accept/return
    * {@link InetAddress} and not arbitrary {@link SocketAddress} types.
-   * 
+   *
    * @return The "special" {@link InetAddress}.
    */
   public final InetAddress wrapAddress() {
@@ -283,7 +286,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * A reference to the constructor of an AFSocketAddress subclass.
-   * 
+   *
    * @param <T> The actual subclass.
    * @author Christian Kohlschütter
    */
@@ -291,7 +294,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
   protected interface AFSocketAddressConstructor<T extends AFSocketAddress> {
     /**
      * Constructs a new AFSocketAddress instance.
-     * 
+     *
      * @param port The port.
      * @param socketAddress The socket address in junixsocket-specific byte-array representation.
      * @param nativeAddress The socket address in system-native representation.
@@ -306,7 +309,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
   /**
    * Resolves a junixsocket-specific byte-array representation of an {@link AFSocketAddress} to an
    * actual {@link AFSocketAddress} instance, possibly reusing a cached instance.
-   * 
+   *
    * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
    * @param socketAddress The socket address in junixsocket-specific byte-array representation.
    * @param port The port.
@@ -408,7 +411,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Wraps an address as an {@link InetAddress}.
-   * 
+   *
    * @param af The address family.
    * @return The {@link InetAddress}.
    */
@@ -421,7 +424,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Wraps this address as an {@link InetAddress}.
-   * 
+   *
    * @return The {@link InetAddress}.
    */
   protected final InetAddress getInetAddress() {
@@ -439,7 +442,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
   /**
    * Returns an {@link AFSocketAddress} given a special {@link InetAddress} that encodes the byte
    * sequence of an AF_UNIX etc. socket address, like those returned by {@link #wrapAddress()}.
-   * 
+   *
    * @param <A> The corresponding address type.
    * @param address The "special" {@link InetAddress}.
    * @param port The port (use 0 for "none").
@@ -460,7 +463,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
    * Returns an {@link AFSocketAddress} given a special {@link InetAddress} hostname that encodes
    * the byte sequence of an AF_UNIX etc. socket address, like those returned by
    * {@link #wrapAddress()}.
-   * 
+   *
    * @param <A> The corresponding address type.
    * @param hostname The "special" hostname, as provided by {@link InetAddress#getHostName()}.
    * @param port The port (use 0 for "none").
@@ -498,13 +501,19 @@ public abstract class AFSocketAddress extends InetSocketAddress {
   /**
    * Returns a thread-local direct ByteBuffer containing the native socket address representation of
    * this {@link AFSocketAddress}.
-   * 
+   *
    * @return The direct {@link ByteBuffer}.
    */
-  final ByteBuffer getNativeAddressDirectBuffer() {
-    ByteBuffer direct = getNativeAddressDirectBuffer(nativeAddress.limit());
-    nativeAddress.position(0);
-    direct.put(nativeAddress);
+  final ByteBuffer getNativeAddressDirectBuffer() throws SocketException {
+    ByteBuffer address = nativeAddress;
+    if (address == null) {
+      throw (SocketException) new SocketException("Cannot access native address").initCause(
+          NativeUnixSocket.unsupportedException());
+    }
+
+    ByteBuffer direct = getNativeAddressDirectBuffer(address.limit());
+    address.position(0);
+    direct.put(address);
 
     return direct;
   }
@@ -518,7 +527,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Checks if the given address is supported by this address family.
-   * 
+   *
    * @param addr The address.
    * @param af The address family.
    * @return {@code true} if supported.
@@ -529,22 +538,23 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Writes the native (system-level) representation of this address to the given buffer.
-   * 
+   *
    * The position of the target buffer will be at the end (i.e., after) the written data.
-   * 
+   *
    * @param buf The target buffer.
    * @throws IOException on error.
    */
   public final void writeNativeAddressTo(ByteBuffer buf) throws IOException {
     if (nativeAddress == null) {
-      throw new IOException("Cannot access native address");
+      throw (SocketException) new SocketException("Cannot access native address").initCause(
+          NativeUnixSocket.unsupportedException());
     }
     buf.put(nativeAddress);
   }
 
   /**
    * Creates a new socket connected to this address.
-   * 
+   *
    * @return The socket instance.
    * @throws IOException on error.
    */
@@ -556,7 +566,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Creates a new server socket bound to this address.
-   * 
+   *
    * @return The server socket instance.
    * @throws IOException on error.
    */
@@ -570,7 +580,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
    * Creates a new server socket force-bound to this address (i.e., any additional call to
    * {@link ServerSocket#bind(SocketAddress)} will ignore the passed address and use this one
    * instead.
-   * 
+   *
    * @return The server socket instance.
    * @throws IOException on error.
    */
@@ -582,10 +592,10 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Tries to parse the given URI and return a corresponding {@link AFSocketAddress} for it.
-   * 
+   *
    * NOTE: Only certain URI schemes are supported, such as {@code unix://} (for
    * {@link AFUNIXSocketAddress}) and {@code tipc://} for {@link AFTIPCSocketAddress}.
-   * 
+   *
    * @param u The URI.
    * @return The address.
    * @throws SocketException on error.
@@ -598,10 +608,10 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Tries to parse the given URI and return a corresponding {@link AFSocketAddress} for it.
-   * 
+   *
    * NOTE: Only certain URI schemes are supported, such as {@code unix://} (for
    * {@link AFUNIXSocketAddress}) and {@code tipc://} for {@link AFTIPCSocketAddress}.
-   * 
+   *
    * @param u The URI.
    * @param overridePort The port to forcibly use, or {@code -1} for "don't override".
    * @return The address.
@@ -619,7 +629,7 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Tries to create a URI based on this {@link AFSocketAddress}.
-   * 
+   *
    * @param scheme The target scheme.
    * @param template An optional template to reuse certain parameters (e.g., the "path" component
    *          for an {@code http} request), or {@code null}.
@@ -634,14 +644,15 @@ public abstract class AFSocketAddress extends InetSocketAddress {
    * Returns a address string that can be used with {@code socat}'s {@code SOCKET-CONNECT},
    * {@code SOCKET-LISTEN}, {@code SOCKET-DATAGRAM}, etc., address types, or {@code null} if the
    * address type is not natively supported by this platform.
-   * 
+   *
    * This call is mostly suited for debugging purposes. The resulting string is specific to the
-   * platform the code is executed on, and thus may be different among platforms (or {@code null}).
-   * 
+   * platform the code is executed on, and thus may be different among platforms.
+   *
    * @param socketType The socket type, or {@code null} to omit from string.
    * @param socketProtocol The socket protocol, or {@code null} to omit from string.
-   * @return The string (such as 1:0:x2f746d702f796f), or {@code null} if unable to retrieve.
-   * @throws IOException on error.
+   * @return The string (such as 1:0:x2f746d702f796f).
+   * @throws IOException on error (a {@link SocketException} is thrown if the native address cannot
+   *           be accessed).
    */
   public @Nullable @SuppressWarnings("PMD.NPathComplexity") String toSocatAddressString(
       AFSocketType socketType, AFSocketProtocol socketProtocol) throws IOException {
@@ -650,7 +661,8 @@ public abstract class AFSocketAddress extends InetSocketAddress {
       return null;
     }
     if (nativeAddress == null) {
-      return null;
+      throw (SocketException) new SocketException("Cannot access native address").initCause(
+          NativeUnixSocket.unsupportedException());
     }
     if (socketProtocol != null && socketProtocol.getId() != 0) {
       throw new IOException("Protocol not (yet) supported"); // FIXME
@@ -682,17 +694,41 @@ public abstract class AFSocketAddress extends InetSocketAddress {
 
   /**
    * Checks if the given address could cover another address.
-   * 
+   *
    * By default, this is only true if both addresses are regarded equal using
    * {@link #equals(Object)}.
-   * 
+   *
    * However, implementations may support "wildcard" addresses, and this method would compare a
    * wildcard address against some non-wildcard address, for example.
-   * 
+   *
    * @param other The other address that could be covered by this address.
    * @return {@code true} if the other address could be covered.
    */
   public boolean covers(AFSocketAddress other) {
     return this.equals(other);
   }
+
+  /**
+   * Custom serialization: Reference {@link AFAddressFamily} instance by identifier string.
+   *
+   * @param in The {@link ObjectInputStream}.
+   * @throws ClassNotFoundException on error.
+   * @throws IOException on error.
+   */
+  private void readObject(ObjectInputStream in) throws ClassNotFoundException, IOException {
+    in.defaultReadObject();
+    this.addressFamily = Objects.requireNonNull(AFAddressFamily.getAddressFamily(in.readUTF()),
+        "address family");
+  }
+
+  /**
+   * Custom serialization: Reference {@link AFAddressFamily} instance by identifier string.
+   *
+   * @param out The {@link ObjectOutputStream}.
+   * @throws IOException on error.
+   */
+  private void writeObject(ObjectOutputStream out) throws IOException {
+    out.defaultWriteObject();
+    out.writeUTF(addressFamily.getJuxString());
+  }
 }
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketAddressConfig.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketAddressConfig.java
index f4b6bc1..84aaea7 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketAddressConfig.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketAddressConfig.java
@@ -25,7 +25,7 @@ import org.newsclub.net.unix.AFSocketAddress.AFSocketAddressConstructor;
 
 /**
  * The implementation-specifics for a given {@link AFSocketAddress} subclass implementation.
- * 
+ *
  * @param <A> The supported address type.
  * @author Christian Kohlschütter
  * @see AFAddressFamilyConfig
@@ -40,7 +40,7 @@ public abstract class AFSocketAddressConfig<A extends AFSocketAddress> {
 
   /**
    * Tries to parse the given address-specific URI.
-   * 
+   *
    * @param u The URI.
    * @param port The port to use, or {@code -1} for "unspecified".
    * @return The address.
@@ -50,23 +50,23 @@ public abstract class AFSocketAddressConfig<A extends AFSocketAddress> {
 
   /**
    * Returns the implementation's address constructor.
-   * 
+   *
    * @return The implementation's address constructor.
    */
   protected abstract AFSocketAddressConstructor<A> addressConstructor();
 
   /**
    * Returns the name of the implementation's selector provider class.
-   * 
+   *
    * @return The name of the implementation's selector provider class.
    */
   protected abstract String selectorProviderClassname();
 
   /**
    * Returns the set of supported URI schemes that can be parsed via {@link #parseURI(URI,int)}.
-   * 
+   *
    * These schemes must be unique to this {@link AFSocketAddress} type.
-   * 
+   *
    * @return The set of supported URI schemes.
    */
   protected abstract Set<String> uriSchemes();
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketAddressFromHostname.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketAddressFromHostname.java
index c7d67a8..7f6c464 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketAddressFromHostname.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketAddressFromHostname.java
@@ -22,13 +22,14 @@ import java.net.SocketException;
 
 /**
  * Helps converting an internet "hostname" to an {@link AFSocketAddress}.
- * 
+ *
  * @author Christian Kohlschütter
+ * @param <A> The supported address type.
  */
 public interface AFSocketAddressFromHostname<A extends AFSocketAddress> {
   /**
    * Translates a "host" string (and port) to an {@link AFSocketAddress}.
-   * 
+   *
    * @param host The hostname
    * @param port The port, or 0.
    * @return The {@link AFSocketAddress}
@@ -40,7 +41,7 @@ public interface AFSocketAddressFromHostname<A extends AFSocketAddress> {
   /**
    * Checks whether the given hostname is supported by this socket factory. If not, calls to
    * createSocket will cause a {@link SocketException}.
-   * 
+   *
    * @param host The host to check.
    * @return {@code true} if supported.
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketCapability.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketCapability.java
index 0fb7019..da16b2f 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketCapability.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketCapability.java
@@ -22,7 +22,7 @@ import java.lang.ProcessBuilder.Redirect;
 /**
  * Describes junixsocket capabilities the current environment (system platform, native library,
  * etc.) may or may not support.
- * 
+ *
  * You can check whether your environment supports a given capability by calling
  * {@link AFSocket#supports(AFSocketCapability)}.
  */
@@ -46,11 +46,11 @@ public enum AFSocketCapability {
 
   /**
    * A pair of interconnected sockets can be created natively as AF_UNIX sockets.
-   * 
+   *
    * This currently not possible on Windows, but instead emulated via anonymous AF_INET ports when
    * you use {@link AFSocketPair}. Other systems may provide partial implementations of pipe-based
    * (i.e., non-socket) pairs.
-   * 
+   *
    * This capability is specific to AF_UNIX sockets. Other sockets, such as AF_VSOCK, may not
    * implement socketpair natively even if this capability is set, but would work-around that
    * limitation in a similar fashion but maybe without resorting to AF_INET.
@@ -59,14 +59,14 @@ public enum AFSocketCapability {
 
   /**
    * A file descriptor can be converted to {@link Redirect}.
-   * 
+   *
    * This feature currently uses Java SDK internals that may change/disappear.
    */
   CAPABILITY_FD_AS_REDIRECT(6),
 
   /**
    * Support for AF_TIPC.
-   * 
+   *
    * Availability of this feature is checked upon launch and therefore loading the "tipc" kernel
    * module at a later point may not be properly reflected.
    */
@@ -74,10 +74,10 @@ public enum AFSocketCapability {
 
   /**
    * Support for AF_UNIX.
-   * 
+   *
    * Availability of this feature is checked upon launch and therefore, on systems adding support at
    * a later point, may not be properly reflected when checking at a later point.
-   * 
+   *
    * NOTE: While this capability is typically supported on most systems that can actually load a
    * junixsocket JNI library, it is unavailable for older Windows versions (such as 8.1, 10 before
    * AFUNIX.SYS was included, etc.) and on systems where support for UNIX domain sockets is actively
@@ -90,7 +90,7 @@ public enum AFSocketCapability {
    *
    * Availability of this feature is checked upon launch and therefore enabling vsock at a later
    * point may not be properly reflected.
-   * 
+   *
    * @see #CAPABILITY_VSOCK_DGRAM
    */
   CAPABILITY_VSOCK(9),
@@ -106,10 +106,10 @@ public enum AFSocketCapability {
 
   /**
    * Support for zero-length send(2).
-   * 
+   *
    * This can be used to perform a connection check, but not all operating systems support this or
    * behave correctly (particularly, IBM AIX, IBM i, and IBM z/OS) at the moment.
-   * 
+   *
    * If not supported, junixsocket will simply ignore writes of zero-length, and connection checking
    * with {@link AFSocket#checkConnectionClosed()} may return {@code false} regardless of the actual
    * condition.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketChannel.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketChannel.java
index 5c05353..65156f7 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketChannel.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketChannel.java
@@ -34,7 +34,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * A selectable channel for stream-oriented connecting sockets.
- * 
+ *
  * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
  * @author Christian Kohlschütter
  */
@@ -45,7 +45,7 @@ public abstract class AFSocketChannel<A extends AFSocketAddress> extends SocketC
 
   /**
    * Creates a new socket channel for the given socket, using the given {@link SelectorProvider}.
-   * 
+   *
    * @param socket The socket.
    * @param sp The {@link SelectorProvider}.
    */
@@ -57,7 +57,7 @@ public abstract class AFSocketChannel<A extends AFSocketAddress> extends SocketC
 
   /**
    * Returns the corresponding {@link AFSocket}.
-   * 
+   *
    * @return The corresponding socket.
    */
   protected final AFSocket<A> getAFSocket() {
@@ -66,14 +66,14 @@ public abstract class AFSocketChannel<A extends AFSocketAddress> extends SocketC
 
   /**
    * A reference to a method that provides an {@link AFSocket} instance.
-   * 
+   *
    * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
    */
   @FunctionalInterface
   protected interface AFSocketSupplier<A extends AFSocketAddress> {
     /**
      * Returns a new {@link AFSocket} instance.
-     * 
+     *
      * @return The instance.
      * @throws IOException on error.
      */
@@ -85,7 +85,7 @@ public abstract class AFSocketChannel<A extends AFSocketAddress> extends SocketC
    *
    * @param <A> The concrete {@link AFSocketAddress} that is supported by this type.
    * @param supplier The AFSocketChannel constructor.
-   * 
+   *
    * @return The new channel
    * @throws IOException on error.
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketConnector.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketConnector.java
new file mode 100644
index 0000000..ca3482c
--- /dev/null
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketConnector.java
@@ -0,0 +1,40 @@
+/*
+ * junixsocket
+ *
+ * Copyright 2009-2022 Christian Kohlschütter
+ *
+ * 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 org.newsclub.net.unix;
+
+import java.io.IOException;
+
+/**
+ * Some connector that is able to connect to a given {@link AFSocketAddress}.
+ *
+ * @param <A> The address type to connect to.
+ * @param <T> The address type for the returned socket (which should either be identical to
+ *          {@code A} or {@link AFSocketAddress} to indicate that this could be any socket).
+ * @author Christian Kohlschütter
+ * @see AFServerSocketConnector
+ */
+public interface AFSocketConnector<A extends AFSocketAddress, T extends AFSocketAddress> {
+  /**
+   * Connect to the socket at the given address.
+   *
+   * @param addr The address to connect to.
+   * @return The connected socket.
+   * @throws IOException on error.
+   */
+  AFSocket<? extends T> connect(A addr) throws IOException;
+}
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketCore.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketCore.java
index 9fa3276..f19e182 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketCore.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketCore.java
@@ -25,7 +25,7 @@ import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * A shared core that is common for all AF* sockets (datagrams, streams).
- * 
+ *
  * @author Christian Kohlschütter
  */
 class AFSocketCore extends AFCore {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketExtensions.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketExtensions.java
index 5ea9f9d..15cb476 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketExtensions.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketExtensions.java
@@ -20,35 +20,35 @@ package org.newsclub.net.unix;
 /**
  * Defines certain methods that all junixsocket socket implementations share and extend beyond the
  * standard socket API.
- * 
+ *
  * The set of features include methods to support working with ancillary messages (such as file
  * descriptors) as well as socket credentials.
- * 
+ *
  * Keep in mind that the platform this code runs on may not support these features, and exceptions
  * may be thrown when not checking for the corresponding {@link AFSocketCapability} first.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public interface AFSocketExtensions {
   /**
    * Returns the size of the receive buffer for ancillary messages (in bytes).
-   * 
+   *
    * @return The size.
    */
   int getAncillaryReceiveBufferSize();
 
   /**
    * Sets the size of the receive buffer for ancillary messages (in bytes).
-   * 
+   *
    * To disable handling ancillary messages, set it to 0 (default).
-   * 
+   *
    * @param size The size.
    */
   void setAncillaryReceiveBufferSize(int size);
 
   /**
    * Ensures a minimum ancillary receive buffer size.
-   * 
+   *
    * @param minSize The minimum size (in bytes).
    */
   void ensureAncillaryReceiveBufferSize(int minSize);
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketFactory.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketFactory.java
index e4aba2f..20a9c12 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketFactory.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketFactory.java
@@ -28,11 +28,12 @@ import javax.net.SocketFactory;
 
 /**
  * The base for a SocketFactory that connects to UNIX sockets.
- * 
+ *
  * Typically, the "hostname" is used as a reference to a socketFile on the file system. The actual
  * mapping is left to the implementor.
- * 
+ *
  * @see AFUNIXSocketFactory
+ * @param <A> The supported address type.
  */
 public abstract class AFSocketFactory<A extends AFSocketAddress> extends SocketFactory implements
     AFSocketAddressFromHostname<A> {
@@ -47,10 +48,10 @@ public abstract class AFSocketFactory<A extends AFSocketAddress> extends SocketF
   /**
    * Checks whether the given {@link InetAddress} is supported by this socket factory. If not, calls
    * to createSocket will cause a {@link SocketException}.
-   * 
+   *
    * By default, this only checks the hostname part of the address via
    * {@link #isHostnameSupported(String)}.
-   * 
+   *
    * @param address The address to check.
    * @return {@code true} if supported.
    */
@@ -63,7 +64,7 @@ public abstract class AFSocketFactory<A extends AFSocketAddress> extends SocketF
 
   /**
    * Creates a new {@link AFSocket}, connected to the given address.
-   * 
+   *
    * @param addr The address to connect to.
    * @return The socket instance.
    * @throws IOException on error.
@@ -140,7 +141,7 @@ public abstract class AFSocketFactory<A extends AFSocketAddress> extends SocketF
 
     /**
      * Creates a {@link FixedAddressSocketFactory}.
-     * 
+     *
      * @param address The address to use for all connections.
      */
     public FixedAddressSocketFactory(SocketAddress address) {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketImpl.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketImpl.java
index 9b9d596..4341db5 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketImpl.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketImpl.java
@@ -40,8 +40,9 @@ import org.eclipse.jdt.annotation.Nullable;
 
 /**
  * junixsocket-based {@link SocketImpl}.
- * 
+ *
  * @author Christian Kohlschütter
+ * @param <A> The supported address type.
  */
 @SuppressWarnings({"PMD.CyclomaticComplexity"})
 public abstract class AFSocketImpl<A extends AFSocketAddress> extends SocketImplShim {
@@ -133,7 +134,7 @@ public abstract class AFSocketImpl<A extends AFSocketAddress> extends SocketImpl
           } catch (Exception e) {
             // ignore
           }
-        } catch (Exception e) {
+        } catch (RuntimeException e) {
           // ignore
         }
 
@@ -149,7 +150,7 @@ public abstract class AFSocketImpl<A extends AFSocketAddress> extends SocketImpl
 
   /**
    * Creates a new {@link AFSocketImpl} instance.
-   * 
+   *
    * @param addressFamily The address family.
    * @param fdObj The socket's {@link FileDescriptor}.
    * @throws SocketException on error.
@@ -167,7 +168,7 @@ public abstract class AFSocketImpl<A extends AFSocketAddress> extends SocketImpl
 
   /**
    * Creates a new {@link InputStream} for this socket.
-   * 
+   *
    * @return The new stream.
    */
   protected final AFInputStream newInputStream() {
@@ -176,7 +177,7 @@ public abstract class AFSocketImpl<A extends AFSocketAddress> extends SocketImpl
 
   /**
    * Creates a new {@link OutputStream} for this socket.
-   * 
+   *
    * @return The new stream.
    */
   protected final AFOutputStream newOutputStream() {
@@ -747,7 +748,7 @@ public abstract class AFSocketImpl<A extends AFSocketAddress> extends SocketImpl
 
   /**
    * Like {@link #getOption(int)}, but ignores exceptions for certain option IDs.
-   * 
+   *
    * @param optID The option ID.
    * @return The value.
    * @throws SocketException on error.
@@ -768,7 +769,7 @@ public abstract class AFSocketImpl<A extends AFSocketAddress> extends SocketImpl
 
   /**
    * Like {@link #setOption(int, Object)}, but ignores exceptions for certain option IDs.
-   * 
+   *
    * @param optID The option ID.
    * @param value The value.
    * @throws SocketException on error.
@@ -844,7 +845,7 @@ public abstract class AFSocketImpl<A extends AFSocketAddress> extends SocketImpl
   /**
    * Shuts down both input and output at once. Equivalent to calling {@link #shutdownInput()} and
    * {@link #shutdownOutput()}.
-   * 
+   *
    * @throws IOException on error.
    */
   protected final void shutdown() throws IOException {
@@ -995,7 +996,7 @@ public abstract class AFSocketImpl<A extends AFSocketAddress> extends SocketImpl
 
   /**
    * Returns the internal helper instance for address-specific extensions.
-   * 
+   *
    * @return The helper instance.
    * @throws UnsupportedOperationException if such extensions are not supported for this address
    *           type.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketImplExtensions.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketImplExtensions.java
index 8e9ae88..966ac3b 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketImplExtensions.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketImplExtensions.java
@@ -19,7 +19,7 @@ package org.newsclub.net.unix;
 
 /**
  * Placeholder for protocol-specific code that resides in the native library.
- * 
+ *
  * @param <A> The corresponding address type.
  * @author Christian Kohlschütter
  * @see AFTIPCSocketImplExtensions
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketOption.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketOption.java
index d69ef55..670afdf 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketOption.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketOption.java
@@ -21,7 +21,7 @@ import java.net.SocketOption;
 
 /**
  * A special socket option supported by some junixsocket-based implementation.
- * 
+ *
  * @param <T> The option's value type.
  * @author Christian Kohlschütter
  */
@@ -33,7 +33,7 @@ public final class AFSocketOption<T> implements SocketOption<T> {
 
   /**
    * Creates a new socket option. This should only be called by {@link AFSocket} implementations.
-   * 
+   *
    * @param name The name of the option.
    * @param type The value type.
    * @param level The socket level (as defined in junixsocket-native).
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketPair.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketPair.java
index 051ee7f..c0bffd6 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketPair.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketPair.java
@@ -23,14 +23,14 @@ import org.eclipse.jdt.annotation.NonNull;
 
 /**
  * A pair of sockets.
- * 
+ *
  * @param <T> The socket type.
  * @author Christian Kohlschütter
  */
 public abstract class AFSocketPair<T extends AFSomeSocket> extends CloseablePair<T> {
   /**
    * Creates a socket pair.
-   * 
+   *
    * @param a The first socket.
    * @param b The second socket.
    */
@@ -40,7 +40,7 @@ public abstract class AFSocketPair<T extends AFSomeSocket> extends CloseablePair
 
   /**
    * Creates a socket pair.
-   * 
+   *
    * @param a The first socket.
    * @param b The second socket.
    * @param alsoClose Some closeable that is also closed upon {@link #close()}, or {@code null}.
@@ -51,7 +51,7 @@ public abstract class AFSocketPair<T extends AFSomeSocket> extends CloseablePair
 
   /**
    * Returns the first socket of the pair.
-   * 
+   *
    * @return The first socket.
    */
   public final @NonNull T getSocket1() {
@@ -60,7 +60,7 @@ public abstract class AFSocketPair<T extends AFSomeSocket> extends CloseablePair
 
   /**
    * Returns the second socket of the pair.
-   * 
+   *
    * @return The second socket.
    */
   public final @NonNull T getSocket2() {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketProtocol.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketProtocol.java
index f64fce6..b458ed6 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketProtocol.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketProtocol.java
@@ -19,7 +19,7 @@ package org.newsclub.net.unix;
 
 /**
  * Describes the "protocol" part of a socket.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public enum AFSocketProtocol {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketType.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketType.java
index c0f65de..158ceb2 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketType.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketType.java
@@ -19,7 +19,7 @@ package org.newsclub.net.unix;
 
 /**
  * Describes the "type" of a socket.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public enum AFSocketType {
@@ -40,7 +40,7 @@ public enum AFSocketType {
 
   /**
    * Reliably-delivered datagram messages.
-   * 
+   *
    * Used by {@code AFTIPCDatagramSocket} to differentiate between datagram connects that may or may
    * not permit package loss.
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSomeSocket.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSomeSocket.java
index 7315c12..08d98c5 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSomeSocket.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFSomeSocket.java
@@ -29,7 +29,7 @@ import org.eclipse.jdt.annotation.Nullable;
 /**
  * Marker interface that combines junixsocket-based {@link SocketChannel}s, {@link Socket}s,
  * {@link DatagramChannel}s and {@link DatagramSocket}s.
- * 
+ *
  * @author Christian Kohlschütter
  * @see AFSocketPair
  * @see AFSocket
@@ -41,7 +41,7 @@ public interface AFSomeSocket extends Closeable, FileDescriptorAccess {
   /**
    * Returns the socket's local socket address, or {@code null} if unavailable or if there was a
    * problem retrieving it.
-   * 
+   *
    * @return The local socket address, or {@code null}.
    */
   @Nullable
@@ -50,7 +50,7 @@ public interface AFSomeSocket extends Closeable, FileDescriptorAccess {
   /**
    * Returns the socket's remote socket address, or {@code null} if unavailable/not connected, or if
    * there was a problem retrieving it.
-   * 
+   *
    * @return The remote socket address, or {@code null}.
    */
   @Nullable
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFTIPCSocketAddress.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFTIPCSocketAddress.java
index 5efcb28..8d85652 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFTIPCSocketAddress.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFTIPCSocketAddress.java
@@ -40,7 +40,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 
 /**
  * An {@link AFSocketAddress} for TIPC sockets.
- * 
+ *
  * The TIPC socket API provides three different address types:
  * <ul>
  * <li><em>Service Address.</em>
@@ -106,7 +106,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
  * indicated node. If this value is zero, all matching sockets in the whole cluster, as visible from
  * the source node, are eligible.
  * </p>
- * 
+ *
  * @author Christian Kohlschütter (documentation credits to Jon Maloy and the TIPC team).
  */
 public final class AFTIPCSocketAddress extends AFSocketAddress {
@@ -131,7 +131,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * The TIPC address type.
-   * 
+   *
    * @author Christian Kohlschütter
    */
   @NonNullByDefault
@@ -191,7 +191,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
     /**
      * Formats an integer as an unsigned, zero-padded 32-bit hexadecimal number.
-     * 
+     *
      * @param i The number.
      * @return The string.
      */
@@ -211,7 +211,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * The TIPC visibility scope.
-   * 
+   *
    * @author Christian Kohlschütter
    */
   @NonNullByDefault
@@ -249,7 +249,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
     /**
      * Returns a {@link Scope} instance given an integer value.
-     * 
+     *
      * @param v The scope value.
      * @return The {@link Scope} instance.
      */
@@ -294,7 +294,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFTIPCSocketAddress} that refers to a given service type and instance, using
    * the given scope and the given lookup domain.
-   * 
+   *
    * @param scope The address scope.
    * @param type The service type (0-63 are reserved).
    * @param instance The service instance ID.
@@ -434,7 +434,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFTIPCSocketAddress} given a special {@link InetAddress} that encodes the
    * byte sequence of an AF_TIPC socket address, like those returned by {@link #wrapAddress()}.
-   * 
+   *
    * @param address The "special" {@link InetAddress}.
    * @param port The port (use 0 for "none").
    * @return The {@link AFTIPCSocketAddress} instance.
@@ -449,7 +449,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
    * Returns an {@link AFTIPCSocketAddress} given a special {@link InetAddress} hostname that
    * encodes the byte sequence of an AF_TIPC socket address, like those returned by
    * {@link #wrapAddress()}.
-   * 
+   *
    * @param hostname The "special" hostname, as provided by {@link InetAddress#getHostName()}.
    * @param port The port (use 0 for "none").
    * @return The {@link AFTIPCSocketAddress} instance.
@@ -462,7 +462,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * Returns an {@link AFTIPCSocketAddress} given a generic {@link SocketAddress}.
-   * 
+   *
    * @param address The address to unwrap.
    * @return The {@link AFTIPCSocketAddress} instance.
    * @throws SocketException if the operation fails, for example when an unsupported address is
@@ -478,7 +478,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the scope of this address.
-   * 
+   *
    * @return The scope.
    */
   public Scope getScope() {
@@ -491,7 +491,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the TIPC type part of this address.
-   * 
+   *
    * @return The type identifier
    */
   public int getTIPCType() {
@@ -502,7 +502,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the TIPC instance part of this address.
-   * 
+   *
    * @return The instance identifier.
    */
   public int getTIPCInstance() {
@@ -513,7 +513,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the TIPC domain part of this address.
-   * 
+   *
    * @return The domain identifier.
    */
   public int getTIPCDomain() {
@@ -524,7 +524,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the TIPC lower instance of this address.
-   * 
+   *
    * @return The lower instance identifier.
    */
   public int getTIPCLower() {
@@ -535,7 +535,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the TIPC upper instance of this address.
-   * 
+   *
    * @return The lower instance identifier.
    */
   public int getTIPCUpper() {
@@ -546,7 +546,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the TIPC ref of this address.
-   * 
+   *
    * @return The ref identifier.
    */
   public int getTIPCRef() {
@@ -557,7 +557,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the TIPC node hash of this address.
-   * 
+   *
    * @return The node hash.
    */
   public int getTIPCNodeHash() {
@@ -602,7 +602,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * Checks if an {@link InetAddress} can be unwrapped to an {@link AFTIPCSocketAddress}.
-   * 
+   *
    * @param addr The instance to check.
    * @return {@code true} if so.
    * @see #wrapAddress()
@@ -614,7 +614,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * Checks if a {@link SocketAddress} can be unwrapped to an {@link AFTIPCSocketAddress}.
-   * 
+   *
    * @param addr The instance to check.
    * @return {@code true} if so.
    * @see #unwrap(InetAddress, int)
@@ -636,7 +636,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the corresponding {@link AFAddressFamily}.
-   * 
+   *
    * @return The address family instance.
    */
   @SuppressWarnings("null")
@@ -684,7 +684,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * Returns an {@link AFTIPCSocketAddress} for the given URI, if possible.
-   * 
+   *
    * @param uri The URI.
    * @return The address.
    * @throws SocketException if the operation fails.
@@ -696,7 +696,7 @@ public final class AFTIPCSocketAddress extends AFSocketAddress {
 
   /**
    * Returns an {@link AFTIPCSocketAddress} for the given URI, if possible.
-   * 
+   *
    * @param uri The URI.
    * @param overridePort The port to forcibly use, or {@code -1} for "don't override".
    * @return The address.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFTIPCSocketImplExtensions.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFTIPCSocketImplExtensions.java
index 4a4268d..7f9fd9f 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFTIPCSocketImplExtensions.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFTIPCSocketImplExtensions.java
@@ -23,7 +23,7 @@ import java.nio.charset.StandardCharsets;
 /**
  * TIPC-specific code that resides in the native library. To be used by {@code AFTIPCSocket} and
  * {@code AFTIPCDatagramSocket} only.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFTIPCSocketImplExtensions implements
@@ -36,9 +36,9 @@ public final class AFTIPCSocketImplExtensions implements
 
   /**
    * Returns the TIPC "ErrInfo" data from the ancillary receive buffer.
-   * 
+   *
    * Invalid for any other use.
-   * 
+   *
    * @return The errinfo.
    */
   public int[] getTIPCErrInfo() {
@@ -47,9 +47,9 @@ public final class AFTIPCSocketImplExtensions implements
 
   /**
    * Returns the TIPC "DestName" data from the ancillary receive buffer.
-   * 
+   *
    * Invalid for any other use.
-   * 
+   *
    * @return The DestName.
    */
   public int[] getTIPCDestName() {
@@ -58,7 +58,7 @@ public final class AFTIPCSocketImplExtensions implements
 
   /**
    * Retrieves the 16-byte TIPC node identity given a node hash.
-   * 
+   *
    * @param peer The node hash.
    * @return The node identity, or {@code  null} if unsupported.
    * @throws IOException on error.
@@ -69,7 +69,7 @@ public final class AFTIPCSocketImplExtensions implements
 
   /**
    * Retrieves the TIPC link name given a node hash and bearer Id.
-   * 
+   *
    * @param peer The node hash.
    * @param bearerId The bearer Id.
    * @return The link name, or {@code  null} if unsupported.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXDatagramChannel.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXDatagramChannel.java
index 79e2369..459be37 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXDatagramChannel.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXDatagramChannel.java
@@ -25,7 +25,7 @@ import java.nio.channels.DatagramChannel;
 
 /**
  * A {@link DatagramChannel} implementation that works with AF_UNIX Unix domain sockets.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFUNIXDatagramChannel extends AFDatagramChannel<AFUNIXSocketAddress> implements
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXDatagramSocket.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXDatagramSocket.java
index ab3329d..2381f65 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXDatagramSocket.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXDatagramSocket.java
@@ -24,7 +24,7 @@ import java.net.SocketException;
 
 /**
  * A {@link DatagramSocket} implementation that works with AF_UNIX Unix domain sockets.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFUNIXDatagramSocket extends AFDatagramSocket<AFUNIXSocketAddress> implements
@@ -41,7 +41,7 @@ public final class AFUNIXDatagramSocket extends AFDatagramSocket<AFUNIXSocketAdd
 
   /**
    * Returns a new {@link AFUNIXDatagramSocket} instance.
-   * 
+   *
    * @return The new instance.
    * @throws IOException on error.
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXProtocolFamily.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXProtocolFamily.java
index 5e8411b..81351eb 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXProtocolFamily.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXProtocolFamily.java
@@ -21,7 +21,7 @@ import java.net.ProtocolFamily;
 
 /**
  * Describes the protocol family supported by {@link AFUNIXSocketAddress} etc.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public enum AFUNIXProtocolFamily implements ProtocolFamily {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSelectorProvider.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSelectorProvider.java
index 9dbf834..7ca8582 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSelectorProvider.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSelectorProvider.java
@@ -88,7 +88,7 @@ public final class AFUNIXSelectorProvider extends AFSelectorProvider<AFUNIXSocke
 
   /**
    * Returns the singleton instance.
-   * 
+   *
    * @return The instance.
    */
   @SuppressFBWarnings("MS_EXPOSE_REP")
@@ -98,7 +98,7 @@ public final class AFUNIXSelectorProvider extends AFSelectorProvider<AFUNIXSocke
 
   /**
    * Returns the singleton instance.
-   * 
+   *
    * @return The instance.
    */
   public static AFUNIXSelectorProvider provider() {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXServerSocket.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXServerSocket.java
index d2d75fe..2d2ad36 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXServerSocket.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXServerSocket.java
@@ -26,13 +26,13 @@ import java.nio.file.Path;
 
 /**
  * The server part of an AF_UNIX domain socket.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class AFUNIXServerSocket extends AFServerSocket<AFUNIXSocketAddress> {
   /**
    * Constructs a new, unconnected instance.
-   * 
+   *
    * @throws IOException if the operation fails.
    */
   protected AFUNIXServerSocket() throws IOException {
@@ -41,7 +41,7 @@ public class AFUNIXServerSocket extends AFServerSocket<AFUNIXSocketAddress> {
 
   /**
    * Constructs a new instance, optionally associated with the given file descriptor.
-   * 
+   *
    * @param fdObj The file descriptor, or {@code null}.
    * @throws IOException if the operation fails.
    */
@@ -61,7 +61,7 @@ public class AFUNIXServerSocket extends AFServerSocket<AFUNIXSocketAddress> {
 
   /**
    * Returns a new, unbound AF_UNIX {@link ServerSocket}.
-   * 
+   *
    * @return The new, unbound {@link AFServerSocket}.
    * @throws IOException if the operation fails.
    */
@@ -78,7 +78,7 @@ public class AFUNIXServerSocket extends AFServerSocket<AFUNIXSocketAddress> {
   /**
    * Returns a new AF_UNIX {@link ServerSocket} that is bound to the given
    * {@link AFUNIXSocketAddress}.
-   * 
+   *
    * @param addr The socket file to bind to.
    * @return The new, bound {@link AFServerSocket}.
    * @throws IOException if the operation fails.
@@ -89,7 +89,7 @@ public class AFUNIXServerSocket extends AFServerSocket<AFUNIXSocketAddress> {
 
   /**
    * Returns a new AF_UNIX {@link ServerSocket} that is bound to the given {@link AFSocketAddress}.
-   * 
+   *
    * @param addr The socket file to bind to.
    * @param deleteOnClose If {@code true}, the socket file (if the address points to a file) will be
    *          deleted upon {@link #close}.
@@ -103,7 +103,7 @@ public class AFUNIXServerSocket extends AFServerSocket<AFUNIXSocketAddress> {
 
   /**
    * Returns a new AF_UNIX {@link ServerSocket} that is bound to the given path.
-   * 
+   *
    * @param path The path to bind to.
    * @param deleteOnClose If {@code true}, the socket file will be deleted upon {@link #close}.
    * @return The new, bound {@link AFServerSocket}.
@@ -116,7 +116,7 @@ public class AFUNIXServerSocket extends AFServerSocket<AFUNIXSocketAddress> {
 
   /**
    * Returns a new AF_UNIX {@link ServerSocket} that is bound to the given path.
-   * 
+   *
    * @param path The path to bind to.
    * @param deleteOnClose If {@code true}, the socket file will be deleted upon {@link #close}.
    * @return The new, bound {@link AFServerSocket}.
@@ -131,7 +131,7 @@ public class AFUNIXServerSocket extends AFServerSocket<AFUNIXSocketAddress> {
   /**
    * Returns a new, <em>unbound</em> AF_UNIX {@link ServerSocket} that will always bind to the given
    * address, regardless of any socket address used in a call to <code>bind</code>.
-   * 
+   *
    * @param forceAddr The address to use.
    * @return The new, yet unbound {@link AFServerSocket}.
    * @throws IOException if an exception occurs.
@@ -148,7 +148,7 @@ public class AFUNIXServerSocket extends AFServerSocket<AFUNIXSocketAddress> {
 
   /**
    * Returns a new {@link AFSocket} instance.
-   * 
+   *
    * @return The new instance.
    * @throws IOException on error.
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXServerSocketChannel.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXServerSocketChannel.java
index be58f5b..5275152 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXServerSocketChannel.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXServerSocketChannel.java
@@ -21,7 +21,7 @@ import java.io.IOException;
 
 /**
  * A selectable channel for stream-oriented listening sockets.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFUNIXServerSocketChannel extends AFServerSocketChannel<AFUNIXSocketAddress> {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocket.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocket.java
index a431340..91f06e0 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocket.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocket.java
@@ -26,7 +26,7 @@ import org.eclipse.jdt.annotation.NonNull;
 
 /**
  * Implementation of an AF_UNIX domain socket.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFUNIXSocket extends AFSocket<AFUNIXSocketAddress> implements
@@ -58,12 +58,12 @@ public final class AFUNIXSocket extends AFSocket<AFUNIXSocketAddress> implements
 
   /**
    * Creates a new, unbound {@link AFSocket}.
-   * 
+   *
    * This "default" implementation is a bit "lenient" with respect to the specification.
-   * 
+   *
    * In particular, we ignore calls to {@link Socket#getTcpNoDelay()} and
    * {@link Socket#setTcpNoDelay(boolean)}.
-   * 
+   *
    * @return A new, unbound socket.
    * @throws IOException if the operation fails.
    */
@@ -87,10 +87,10 @@ public final class AFUNIXSocket extends AFSocket<AFUNIXSocketAddress> implements
 
   /**
    * Creates a new, unbound, "strict" {@link AFSocket}.
-   * 
+   *
    * This call uses an implementation that tries to be closer to the specification than
    * {@link #newInstance()}, at least for some cases.
-   * 
+   *
    * @return A new, unbound socket.
    * @throws IOException if the operation fails.
    */
@@ -100,7 +100,7 @@ public final class AFUNIXSocket extends AFSocket<AFUNIXSocketAddress> implements
 
   /**
    * Creates a new {@link AFSocket} and connects it to the given {@link AFUNIXSocketAddress}.
-   * 
+   *
    * @param addr The address to connect to.
    * @return A new, connected socket.
    * @throws IOException if the operation fails.
@@ -147,14 +147,14 @@ public final class AFUNIXSocket extends AFSocket<AFUNIXSocketAddress> implements
 
   /**
    * Returns <code>true</code> iff {@link AFUNIXSocket}s are supported by the current Java VM.
-   * 
+   *
    * To support {@link AFSocket}s, a custom JNI library must be loaded that is supplied with
    * <em>junixsocket</em>, and the system must support AF_UNIX sockets.
-   * 
+   *
    * This call is equivalent to checking {@link AFSocket#isSupported()} and
    * {@link AFSocket#supports(AFSocketCapability)} with
    * {@link AFSocketCapability#CAPABILITY_UNIX_DOMAIN}.
-   * 
+   *
    * @return {@code true} iff supported.
    */
   public static boolean isSupported() {
@@ -163,9 +163,9 @@ public final class AFUNIXSocket extends AFSocket<AFUNIXSocketAddress> implements
 
   /**
    * Very basic self-test function.
-   * 
+   *
    * Prints "supported" and "capabilities" status to System.out.
-   * 
+   *
    * @param args ignored.
    */
   public static void main(String[] args) {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketAddress.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketAddress.java
index 4325b2a..136d06f 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketAddress.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketAddress.java
@@ -40,10 +40,10 @@ import org.eclipse.jdt.annotation.NonNull;
 
 /**
  * Describes an {@link InetSocketAddress} that actually uses AF_UNIX sockets instead of AF_INET.
- * 
+ *
  * The ability to specify a port number is not specified by AF_UNIX sockets, but we need it
  * sometimes, for example for RMI-over-AF_UNIX.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @SuppressWarnings("PMD.ShortMethodName")
@@ -86,7 +86,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFUNIXSocketAddress} that points to the AF_UNIX socket specified by the given
    * file and port. <b>Legacy constructor, do not use!</b>
-   * 
+   *
    * @param socketFile The socket to connect to.
    * @throws SocketException if the operation fails.
    * @deprecated Use {@link #of(File)} instead.
@@ -99,7 +99,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFUNIXSocketAddress} that points to the AF_UNIX socket specified by the given
    * file. <b>Legacy constructor, do not use!</b>
-   * 
+   *
    * @param socketFile The socket to connect to.
    * @param port The port associated with this socket, or {@code 0} when no port should be assigned.
    * @throws SocketException if the operation fails.
@@ -114,7 +114,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFUNIXSocketAddress} that points to the AF_UNIX socket specified by the given
    * file.
-   * 
+   *
    * @param socketFile The socket to connect to.
    * @return A corresponding {@link AFUNIXSocketAddress} instance.
    * @throws SocketException if the operation fails.
@@ -126,7 +126,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFUNIXSocketAddress} that points to the AF_UNIX socket specified by the given
    * file, assigning the given port to it.
-   * 
+   *
    * @param socketFile The socket to connect to.
    * @param port The port associated with this socket, or {@code 0} when no port should be assigned.
    * @return A corresponding {@link AFUNIXSocketAddress} instance.
@@ -139,10 +139,10 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFUNIXSocketAddress} that points to the AF_UNIX socket specified by the given
    * byte sequence.
-   * 
+   *
    * NOTE: By specifying a byte array that starts with a zero byte, you indicate that the abstract
    * namespace is to be used. This feature is not available on all target platforms.
-   * 
+   *
    * @param socketAddress The socket address (as bytes).
    * @return A corresponding {@link AFUNIXSocketAddress} instance.
    * @throws SocketException if the operation fails.
@@ -155,7 +155,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFUNIXSocketAddress} that points to the AF_UNIX socket specified by the given
    * byte sequence, assigning the given port to it.
-   * 
+   *
    * NOTE: By specifying a byte array that starts with a zero byte, you indicate that the abstract
    * namespace is to be used. This feature is not available on all target platforms.
    *
@@ -173,7 +173,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFUNIXSocketAddress} that points to the AF_UNIX socket specified by the given
    * path.
-   * 
+   *
    * @param socketPath The socket to connect to.
    * @return A corresponding {@link AFUNIXSocketAddress} instance.
    * @throws SocketException if the operation fails.
@@ -185,7 +185,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFUNIXSocketAddress} that points to the AF_UNIX socket specified by the given
    * path, assigning the given port to it.
-   * 
+   *
    * @param socketPath The socket to connect to.
    * @param port The port associated with this socket, or {@code 0} when no port should be assigned.
    * @return A corresponding {@link AFUNIXSocketAddress} instance.
@@ -197,7 +197,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
 
   /**
    * Returns an {@link AFUNIXSocketAddress} for the given URI, if possible.
-   * 
+   *
    * @param u The URI.
    * @return The address.
    * @throws SocketException if the operation fails.
@@ -208,7 +208,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
 
   /**
    * Returns an {@link AFUNIXSocketAddress} for the given URI, if possible.
-   * 
+   *
    * @param u The URI.
    * @param overridePort The port to forcibly use, or {@code -1} for "don't override".
    * @return The address.
@@ -240,7 +240,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFUNIXSocketAddress} that points to a temporary, non-existent but accessible
    * path in the file system.
-   * 
+   *
    * @return A corresponding {@link AFUNIXSocketAddress} instance.
    * @throws IOException if the operation fails.
    */
@@ -251,7 +251,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFUNIXSocketAddress} that points to a temporary, non-existent but accessible
    * path in the file system, assigning the given port to it.
-   * 
+   *
    * @param port The port associated with this socket, or {@code 0} when no port should be assigned.
    * @return A corresponding {@link AFUNIXSocketAddress} instance.
    * @throws IOException if the operation fails.
@@ -274,7 +274,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFUNIXSocketAddress} given a special {@link InetAddress} that encodes the
    * byte sequence of an AF_UNIX socket address, like those returned by {@link #wrapAddress()}.
-   * 
+   *
    * @param address The "special" {@link InetAddress}.
    * @param port The port (use 0 for "none").
    * @return The {@link AFUNIXSocketAddress} instance.
@@ -287,7 +287,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
 
   /**
    * Returns an {@link AFUNIXSocketAddress} given a generic {@link SocketAddress}.
-   * 
+   *
    * @param address The address to unwrap.
    * @return The {@link AFUNIXSocketAddress} instance.
    * @throws SocketException if the operation fails, for example when an unsupported address is
@@ -306,7 +306,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
    * Returns an {@link AFUNIXSocketAddress} given a special {@link InetAddress} hostname that
    * encodes the byte sequence of an AF_UNIX socket address, like those returned by
    * {@link #wrapAddress()}.
-   * 
+   *
    * @param hostname The "special" hostname, as provided by {@link InetAddress#getHostName()}.
    * @param port The port (use 0 for "none").
    * @return The {@link AFUNIXSocketAddress} instance.
@@ -319,11 +319,11 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
 
   /**
    * Convenience method to create an {@link AFUNIXSocketAddress} in the abstract namespace.
-   * 
+   *
    * The returned socket address will use the byte representation of this identifier (using the
    * system's default character encoding), prefixed with a null byte (to indicate the abstract
    * namespace is used).
-   * 
+   *
    * @param name The identifier in the abstract namespace, without trailing zero or @.
    * @return The address.
    * @throws SocketException if the operation fails.
@@ -334,11 +334,11 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
 
   /**
    * Convenience method to create an {@link AFUNIXSocketAddress} in the abstract namespace.
-   * 
+   *
    * The returned socket address will use the byte representation of this identifier (using the
    * system's default character encoding), prefixed with a null byte (to indicate the abstract
    * namespace is used).
-   * 
+   *
    * @param name The identifier in the abstract namespace, without trailing zero or @.
    * @param port The port associated with this socket, or {@code 0} when no port should be assigned.
    * @return The address.
@@ -380,10 +380,10 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
   /**
    * Returns the path to the UNIX domain socket, as a human-readable string using the default
    * encoding.
-   * 
+   *
    * For addresses in the abstract namespace, the US_ASCII encoding is used; zero-bytes are
    * converted to '@', other non-printable bytes are converted to '.'
-   * 
+   *
    * @return The path.
    * @see #getPathAsBytes()
    */
@@ -411,10 +411,10 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the {@link Charset} used to encode/decode {@link AFUNIXSocketAddress}es.
-   * 
+   *
    * This is usually the system default charset, unless that is {@link StandardCharsets#US_ASCII}
    * (7-bit), in which case {@link StandardCharsets#ISO_8859_1} is used instead.
-   * 
+   *
    * @return The charset.
    */
   public static Charset addressCharset() {
@@ -423,7 +423,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the path to the UNIX domain socket, as bytes.
-   * 
+   *
    * @return The path.
    * @see #getPath()
    */
@@ -433,7 +433,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
 
   /**
    * Checks if the address is in the abstract namespace.
-   * 
+   *
    * @return {@code true} if the address is in the abstract namespace.
    */
   public boolean isInAbstractNamespace() {
@@ -462,7 +462,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
 
   /**
    * Checks if an {@link InetAddress} can be unwrapped to an {@link AFUNIXSocketAddress}.
-   * 
+   *
    * @param addr The instance to check.
    * @return {@code true} if so.
    * @see #wrapAddress()
@@ -474,7 +474,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
 
   /**
    * Checks if a {@link SocketAddress} can be unwrapped to an {@link AFUNIXSocketAddress}.
-   * 
+   *
    * @param addr The instance to check.
    * @return {@code true} if so.
    * @see #unwrap(InetAddress, int)
@@ -485,7 +485,7 @@ public final class AFUNIXSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the corresponding {@link AFAddressFamily}.
-   * 
+   *
    * @return The address family instance.
    */
   @SuppressWarnings("null")
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketCapability.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketCapability.java
index 8e56621..5caeb6c 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketCapability.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketCapability.java
@@ -20,12 +20,12 @@ package org.newsclub.net.unix;
 /**
  * Describes junixsocket capabilities the current environment (system platform, native library,
  * etc.) may or may not support.
- * 
+ *
  * You can check whether your environment supports a given capability by calling
  * {@link AFUNIXSocket#supports(AFUNIXSocketCapability)}.
- * 
+ *
  * This enum is deprecated. Use {@link AFSocketCapability} instead.
- * 
+ *
  * @see AFSocketCapability
  */
 @Deprecated
@@ -49,7 +49,7 @@ public enum AFUNIXSocketCapability {
 
   /**
    * A pair of interconnected sockets can be created natively.
-   * 
+   *
    * This currently not possible on Windows, but instead emulated via anonymous AF_INET ports when
    * you use {@link AFUNIXSocketPair}.
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketChannel.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketChannel.java
index a5f2758..18d61f8 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketChannel.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketChannel.java
@@ -24,7 +24,7 @@ import java.net.SocketException;
 
 /**
  * A selectable channel for stream-oriented connecting sockets.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFUNIXSocketChannel extends AFSocketChannel<AFUNIXSocketAddress> implements
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketCredentials.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketCredentials.java
index 28b7f7c..9f0787c 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketCredentials.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketCredentials.java
@@ -63,7 +63,7 @@ public final class AFUNIXSocketCredentials implements Serializable {
 
   /**
    * Returns the "pid" (process ID), or {@code -1} if it could not be retrieved.
-   * 
+   *
    * @return The pid, or -1.
    */
   public long getPid() {
@@ -72,7 +72,7 @@ public final class AFUNIXSocketCredentials implements Serializable {
 
   /**
    * Returns the "uid" (user ID), or {@code -1} if it could not be retrieved.
-   * 
+   *
    * @return The uid, or -1.
    */
   public long getUid() {
@@ -81,7 +81,7 @@ public final class AFUNIXSocketCredentials implements Serializable {
 
   /**
    * Returns the primary "gid" (group ID), or {@code -1} if it could not be retrieved.
-   * 
+   *
    * @return The gid, or -1.
    */
   public long getGid() {
@@ -90,10 +90,10 @@ public final class AFUNIXSocketCredentials implements Serializable {
 
   /**
    * Returns all "gid" values (group IDs), or {@code null} if they could not be retrieved.
-   * 
+   *
    * Note that this list may be incomplete (only the primary gid may be returned), but it is
    * guaranteed that the first one in the list is the primary gid as returned by {@link #getGid()}.
-   * 
+   *
    * @return The gids, or null.
    */
   public long[] getGids() {
@@ -103,7 +103,7 @@ public final class AFUNIXSocketCredentials implements Serializable {
   /**
    * Returns the process' unique identifier, or {@code null} if no such identifier could be
    * retrieved. Note that all processes run by the same Java runtime may share the same UUID.
-   * 
+   *
    * @return The UUID, or null.
    */
   public UUID getUUID() {
@@ -120,7 +120,7 @@ public final class AFUNIXSocketCredentials implements Serializable {
 
   /**
    * Checks if neither of the possible peer credentials are set.
-   * 
+   *
    * @return {@code true} if no credentials set.
    */
   public boolean isEmpty() {
@@ -201,10 +201,10 @@ public final class AFUNIXSocketCredentials implements Serializable {
   /**
    * Returns the {@link AFUNIXSocketCredentials} for the currently active remote session, or
    * {@code null} if it was not possible to retrieve these credentials.
-   * 
+   *
    * NOTE: For now, only RMI remote sessions are supported (RemoteServer sessions during a remote
    * method invocation).
-   * 
+   *
    * If you want to retrieve the peer credentials for an RMI server, see junixsocket-rmi's
    * RemotePeerInfo.
    *
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketExtensions.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketExtensions.java
index a59ea78..3479ec8 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketExtensions.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketExtensions.java
@@ -24,23 +24,23 @@ import java.io.InputStream;
 /**
  * Defines certain methods that all junixsocket AF_UNIX socket implementations share and extend
  * beyond the standard socket API.
- * 
+ *
  * The set of features include methods to support working with ancillary messages (such as file
  * descriptors) as well as socket credentials.
- * 
+ *
  * Keep in mind that the platform this code runs on may not support these features, and exceptions
  * may be thrown when not checking for the corresponding {@link AFUNIXSocketCapability} first.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public interface AFUNIXSocketExtensions extends AFSocketExtensions {
   /**
    * Retrieves an array of incoming {@link FileDescriptor}s that were sent as ancillary messages,
    * along with a call to {@link InputStream#read()}, etc.
-   * 
+   *
    * NOTE: Another call to this method will not return the same file descriptors again (most likely,
    * an empty array will be returned).
-   * 
+   *
    * @return The file descriptors, or an empty array if none were available.
    * @throws IOException if the operation fails.
    */
@@ -54,15 +54,15 @@ public interface AFUNIXSocketExtensions extends AFSocketExtensions {
   /**
    * Sets a list of {@link FileDescriptor}s that should be sent as an ancillary message along with
    * the next write.
-   * 
+   *
    * Important: There can only be one set of file descriptors active until the write completes. The
    * socket also needs to be connected for this operation to succeed.
-   * 
+   *
    * It is also important to know that there may be an upper limit imposed by the operation system
    * as to how many file descriptors can be sent at once. Linux, for example, may support up to 253.
    * If the number of file descriptors exceeds the limit, an exception may be thrown when sending
    * data along with the ancillary message containing the file descriptors.
-   * 
+   *
    * @param fdescs The file descriptors, or {@code null} if none.
    * @throws IOException if the operation fails.
    */
@@ -71,7 +71,7 @@ public interface AFUNIXSocketExtensions extends AFSocketExtensions {
   /**
    * Returns {@code true} if there are pending file descriptors to be sent as part of an ancillary
    * message.
-   * 
+   *
    * @return {@code true} if there are file descriptors pending.
    */
   boolean hasOutboundFileDescriptors();
@@ -80,7 +80,7 @@ public interface AFUNIXSocketExtensions extends AFSocketExtensions {
    * Retrieves the "peer credentials" for this connection.
    *
    * These credentials may be useful to authenticate the other end of the socket (client or server).
-   * 
+   *
    * Depending on the socket/connection/environment, you may not receive any or all credentials. For
    * example, on Linux, {@link AFUNIXDatagramSocket} and {@link AFUNIXDatagramChannel} may not be
    * able to retrieve credentials at all.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketFactory.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketFactory.java
index 3ac2791..3993829 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketFactory.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketFactory.java
@@ -28,10 +28,10 @@ import javax.net.SocketFactory;
 
 /**
  * The base for a SocketFactory that connects to UNIX sockets.
- * 
+ *
  * Typically, the "hostname" is used as a reference to a socketFile on the file system. The actual
  * mapping is left to the implementor.
- * 
+ *
  * @see AFUNIXSocketFactory.FactoryArg
  * @see AFUNIXSocketFactory.SystemProperty
  * @see AFUNIXSocketFactory.URIScheme
@@ -83,9 +83,9 @@ public abstract class AFUNIXSocketFactory extends AFSocketFactory<AFUNIXSocketAd
    * A socket factory that handles a custom hostname ("localhost", by default, and configured by the
    * system property &quot;org.newsclub.net.unix.socket.hostname&quot;), forwarding all other
    * requests to the fallback {@link SocketFactory}.
-   * 
+   *
    * The socket path is configured through an argument passed by to the constructor.
-   * 
+   *
    * This is particularly useful for JDBC drivers that take a "socketFactory" and a
    * "socketFactoryArg". The latter will be passed as a constructor argument.
    */
@@ -94,7 +94,7 @@ public abstract class AFUNIXSocketFactory extends AFSocketFactory<AFUNIXSocketAd
 
     /**
      * Constructs a new {@link FactoryArg} factory using the given socket path.
-     * 
+     *
      * @param socketPath The path to the socket.
      */
     public FactoryArg(String socketPath) {
@@ -106,7 +106,7 @@ public abstract class AFUNIXSocketFactory extends AFSocketFactory<AFUNIXSocketAd
 
     /**
      * Constructs a new {@link FactoryArg} factory using the given socket path.
-     * 
+     *
      * @param file The path to the socket.
      */
     public FactoryArg(File file) {
@@ -126,10 +126,10 @@ public abstract class AFUNIXSocketFactory extends AFSocketFactory<AFUNIXSocketAd
    * A socket factory that handles a custom hostname ("junixsocket.localhost", by default, and
    * configured by the system property &quot;org.newsclub.net.unix.socket.hostname&quot;),
    * forwarding all other requests to the fallback {@link SocketFactory}.
-   * 
+   *
    * The socket path is configured through a system property,
    * &quot;org.newsclub.net.unix.socket.default&quot;.
-   * 
+   *
    * NOTE: While it is technically possible, it is highly discouraged to programmatically change the
    * value of the property as it can lead to concurrency issues and undefined behavior.
    */
@@ -157,12 +157,12 @@ public abstract class AFUNIXSocketFactory extends AFSocketFactory<AFUNIXSocketAd
 
   /**
    * A socket factory that handles special host names formatted as file:// URIs.
-   * 
+   *
    * The file:// URI may also be specified in URL-encoded format, i.e., file:%3A%2F%2F etc.
-   * 
+   *
    * You may also surround the URL with square brackets ("[" and "]"), whereas the closing bracket
    * may be omitted.
-   * 
+   *
    * NOTE: In some circumstances it is recommended to use "<code>[file:%3A%2F%2F</code>(...)", i.e.
    * encoded and without the closing bracket. Since this is an invalid hostname, it will not trigger
    * a DNS lookup, but can still be used within a JDBC Connection URL.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketImpl.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketImpl.java
index 3593487..12ae2ac 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketImpl.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketImpl.java
@@ -29,7 +29,7 @@ class AFUNIXSocketImpl extends AFSocketImpl<AFUNIXSocketAddress> {
 
   /**
    * Changes the behavior to be somewhat lenient with respect to the specification.
-   * 
+   *
    * In particular, we ignore calls to {@link Socket#getTcpNoDelay()} and
    * {@link Socket#setTcpNoDelay(boolean)}.
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketPair.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketPair.java
index 08e22cb..6841301 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketPair.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFUNIXSocketPair.java
@@ -21,7 +21,7 @@ import java.io.IOException;
 
 /**
  * A pair of sockets.
- * 
+ *
  * @param <T> The socket type.
  * @author Christian Kohlschütter
  */
@@ -32,7 +32,7 @@ public final class AFUNIXSocketPair<T extends AFSomeSocket> extends AFSocketPair
 
   /**
    * Opens a socket pair of interconnected channels.
-   * 
+   *
    * @return The new channel pair.
    * @throws IOException on error.
    */
@@ -42,7 +42,7 @@ public final class AFUNIXSocketPair<T extends AFSomeSocket> extends AFSocketPair
 
   /**
    * Opens a socket pair of interconnected datagram channels.
-   * 
+   *
    * @return The new channel pair.
    * @throws IOException on error.
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFVSOCKSocketAddress.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFVSOCKSocketAddress.java
index a9c8012..9929ba4 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFVSOCKSocketAddress.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFVSOCKSocketAddress.java
@@ -35,7 +35,7 @@ import java.util.regex.Pattern;
 
 /**
  * An {@link AFSocketAddress} for VSOCK sockets.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFVSOCKSocketAddress extends AFSocketAddress {
@@ -104,7 +104,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFVSOCKSocketAddress}, especially useful for binding, that refers to "any"
    * port on the hypervisor; the "java port" is set to -1.
-   * 
+   *
    * @return A corresponding {@link AFVSOCKSocketAddress} instance.
    * @throws SocketException if the operation fails.
    */
@@ -115,7 +115,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFVSOCKSocketAddress} that refers to the given port with the local/loopback
    * CID; the "java port" is set to -1.
-   * 
+   *
    * @param port The VSOCK port.
    * @return A corresponding {@link AFVSOCKSocketAddress} instance.
    * @throws SocketException if the operation fails.
@@ -127,7 +127,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFVSOCKSocketAddress}, especially useful for binding, that refers to "any"
    * port with the local/loopback CID; the "java port" is set to -1.
-   * 
+   *
    * @return A corresponding {@link AFVSOCKSocketAddress} instance.
    * @throws SocketException if the operation fails.
    */
@@ -150,7 +150,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFVSOCKSocketAddress}, especially useful for binding, that refers to "any"
    * port on the host; the "java port" is set to -1.
-   * 
+   *
    * @return A corresponding {@link AFVSOCKSocketAddress} instance.
    * @throws SocketException if the operation fails.
    */
@@ -161,7 +161,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFVSOCKSocketAddress}, especially useful for binding, that refers to "any"
    * port and CID; the "java port" is set to -1.
-   * 
+   *
    * @return A corresponding {@link AFVSOCKSocketAddress} instance.
    * @throws SocketException if the operation fails.
    */
@@ -172,7 +172,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFVSOCKSocketAddress}, especially useful for binding, that refers to the
    * given port with "any CID"; the "java port" is set to -1.
-   * 
+   *
    * @param port The VSOCK port.
    * @return A corresponding {@link AFVSOCKSocketAddress} instance.
    * @throws SocketException if the operation fails.
@@ -198,7 +198,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
   /**
    * Returns an {@link AFVSOCKSocketAddress} given a special {@link InetAddress} that encodes the
    * byte sequence of an AF_VSOCK socket address, like those returned by {@link #wrapAddress()}.
-   * 
+   *
    * @param address The "special" {@link InetAddress}.
    * @param port The port (use 0 for "none").
    * @return The {@link AFVSOCKSocketAddress} instance.
@@ -213,7 +213,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
    * Returns an {@link AFVSOCKSocketAddress} given a special {@link InetAddress} hostname that
    * encodes the byte sequence of an AF_VSOCK socket address, like those returned by
    * {@link #wrapAddress()}.
-   * 
+   *
    * @param hostname The "special" hostname, as provided by {@link InetAddress#getHostName()}.
    * @param port The port (use 0 for "none").
    * @return The {@link AFVSOCKSocketAddress} instance.
@@ -226,7 +226,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
 
   /**
    * Returns an {@link AFVSOCKSocketAddress} given a generic {@link SocketAddress}.
-   * 
+   *
    * @param address The address to unwrap.
    * @return The {@link AFVSOCKSocketAddress} instance.
    * @throws SocketException if the operation fails, for example when an unsupported address is
@@ -242,7 +242,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the "VSOCK port" part of this address.
-   * 
+   *
    * @return The VSOCK port identifier
    * @see #getPort()
    */
@@ -254,7 +254,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the "VSOCK CID" part of this address.
-   * 
+   *
    * @return The VSOCK CID identifier.
    */
   public int getVSOCKCID() {
@@ -265,7 +265,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the "VSOCK reserved1" part of this address.
-   * 
+   *
    * @return The "reserved1" identifier, which should be 0.
    */
   public int getVSOCKReserved1() {
@@ -313,7 +313,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
 
   /**
    * Checks if an {@link InetAddress} can be unwrapped to an {@link AFVSOCKSocketAddress}.
-   * 
+   *
    * @param addr The instance to check.
    * @return {@code true} if so.
    * @see #wrapAddress()
@@ -325,7 +325,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
 
   /**
    * Checks if a {@link SocketAddress} can be unwrapped to an {@link AFVSOCKSocketAddress}.
-   * 
+   *
    * @param addr The instance to check.
    * @return {@code true} if so.
    * @see #unwrap(InetAddress, int)
@@ -345,7 +345,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
 
   /**
    * Returns the corresponding {@link AFAddressFamily}.
-   * 
+   *
    * @return The address family instance.
    */
   @SuppressWarnings("null")
@@ -385,7 +385,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
 
   /**
    * Returns an {@link AFVSOCKSocketAddress} for the given URI, if possible.
-   * 
+   *
    * @param uri The URI.
    * @return The address.
    * @throws SocketException if the operation fails.
@@ -397,7 +397,7 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
 
   /**
    * Returns an {@link AFVSOCKSocketAddress} for the given URI, if possible.
-   * 
+   *
    * @param uri The URI.
    * @param overridePort The port to forcibly use, or {@code -1} for "don't override".
    * @return The address.
@@ -551,13 +551,13 @@ public final class AFVSOCKSocketAddress extends AFSocketAddress {
 
   /**
    * Checks if the given address could cover another address.
-   * 
+   *
    * By default, this is only true if both addresses are regarded equal using
    * {@link #equals(Object)}.
-   * 
+   *
    * However, implementations may support "wildcard" addresses, and this method would compare a
    * wildcard address against some non-wildcard address, for example.
-   * 
+   *
    * @param covered The other address that could be covered by this address.
    * @return {@code true} if the other address could be covered.
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFVSOCKSocketImplExtensions.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFVSOCKSocketImplExtensions.java
index fc7b65e..57a597f 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AFVSOCKSocketImplExtensions.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AFVSOCKSocketImplExtensions.java
@@ -22,7 +22,7 @@ import java.io.IOException;
 /**
  * VSOCK-specific code that resides in the native library. To be used by {@code AFVSOCKSocket} and
  * {@code AFVSOCKDatagramSocket} only.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFVSOCKSocketImplExtensions implements
@@ -36,12 +36,12 @@ public final class AFVSOCKSocketImplExtensions implements
 
   /**
    * Returns the local CID.
-   * 
+   *
    * If the system does not support vsock, or status about support cannot be retrieved, -1
    * ({@link AFVSOCKSocketAddress#VMADDR_CID_ANY}) is returned.
-   * 
+   *
    * The value may be cached upon initialization of the library.
-   * 
+   *
    * @return The CID, or -1.
    * @throws IOException on error.
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/AddressUnavailableSocketException.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/AddressUnavailableSocketException.java
index c892bcd..9d3faa2 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/AddressUnavailableSocketException.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/AddressUnavailableSocketException.java
@@ -22,7 +22,7 @@ import java.net.SocketException;
 /**
  * A {@link SocketException} that may be thrown upon some "address unavailable" condition from
  * native code (e.g., EADDRNOTAVAIL is returned).
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class AddressUnavailableSocketException extends InvalidSocketException {
@@ -37,7 +37,7 @@ public class AddressUnavailableSocketException extends InvalidSocketException {
 
   /**
    * Constructs a new {@link AddressUnavailableSocketException}.
-   * 
+   *
    * @param msg The error message.
    */
   public AddressUnavailableSocketException(String msg) {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/BrokenPipeSocketException.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/BrokenPipeSocketException.java
index 55973cb..91969d1 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/BrokenPipeSocketException.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/BrokenPipeSocketException.java
@@ -21,7 +21,7 @@ import java.net.SocketException;
 
 /**
  * A {@link SocketException} indicating that a socket connection was broken ("broken pipe").
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class BrokenPipeSocketException extends SocketException {
@@ -36,7 +36,7 @@ public final class BrokenPipeSocketException extends SocketException {
 
   /**
    * Constructs a new {@link BrokenPipeSocketException}.
-   * 
+   *
    * @param msg The error message.
    */
   public BrokenPipeSocketException(String msg) {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/CleanableState.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/CleanableState.java
index e77bfe9..de7e8d6 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/CleanableState.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/CleanableState.java
@@ -24,7 +24,7 @@ import java.lang.ref.Cleaner;
 /**
  * This wrapper (along with the Java 8-specific counterpart in src/main/java8) allows us to
  * implement cleanup logic for objects that are garbage-collectable/no longer reachable.
- * 
+ *
  * <p>
  * Usage:
  * <ol>
@@ -46,7 +46,7 @@ import java.lang.ref.Cleaner;
  * <li>In Java 8 or earlier, {@link #finalize()} calls {@link #doClean()} directly.</li>
  * </ul>
  * </p>
- * 
+ *
  * @author Christian Kohlschütter
  */
 abstract class CleanableState implements Closeable {
@@ -56,7 +56,7 @@ abstract class CleanableState implements Closeable {
   /**
    * Creates a state object to be used as an implementation detail of the specified observed
    * instance.
-   * 
+   *
    * @param observed The observed instance (the outer class referencing this
    *          {@link CleanableState}).
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/CloseablePair.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/CloseablePair.java
index 557c1eb..cbaedc1 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/CloseablePair.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/CloseablePair.java
@@ -25,7 +25,7 @@ import org.eclipse.jdt.annotation.NonNull;
 
 /**
  * A pair of two closeable items.
- * 
+ *
  * @param <T> The type of the items.
  * @author Christian Kohlschütter
  */
@@ -36,7 +36,7 @@ public class CloseablePair<T extends Closeable> implements Closeable {
 
   /**
    * Creates a pair of two items.
-   * 
+   *
    * @param a The first item.
    * @param b The second item.
    */
@@ -46,7 +46,7 @@ public class CloseablePair<T extends Closeable> implements Closeable {
 
   /**
    * Creates a pair of two items.
-   * 
+   *
    * @param a The first item.
    * @param b The second item.
    * @param alsoClose Some closeable that is also closed upon {@link #close()}, or {@code null}.
@@ -70,7 +70,7 @@ public class CloseablePair<T extends Closeable> implements Closeable {
 
   /**
    * Returns the pair's first item.
-   * 
+   *
    * @return The first item.
    */
   public final @NonNull T getFirst() {
@@ -79,7 +79,7 @@ public class CloseablePair<T extends Closeable> implements Closeable {
 
   /**
    * Returns the pair's second item.
-   * 
+   *
    * @return The second item.
    */
   public final @NonNull T getSecond() {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/Closeables.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/Closeables.java
index c2c3be5..5f70cc0 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/Closeables.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/Closeables.java
@@ -26,7 +26,7 @@ import java.util.List;
 
 /**
  * A set of {@link Closeables} that can be closed at once.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class Closeables implements Closeable {
@@ -41,7 +41,7 @@ public final class Closeables implements Closeable {
   /**
    * Creates a new {@link Closeables} instance, populating it with the given {@link Closeable}
    * objects.
-   * 
+   *
    * @param closeable The {@link Closeable}s to add.
    */
   public Closeables(Closeable... closeable) {
@@ -57,7 +57,7 @@ public final class Closeables implements Closeable {
 
   /**
    * Closes all registered closeables.
-   * 
+   *
    * @param superException If set, any exceptions thrown in here will be chained to the given
    *          exception via addSuppressed, and then thrown.
    * @throws IOException if an exception occurs.
@@ -106,7 +106,7 @@ public final class Closeables implements Closeable {
 
   /**
    * Adds the given closeable, but only using a weak reference.
-   * 
+   *
    * @param closeable The closeable.
    * @return {@code true} iff the closeable was added, {@code false} if it was {@code null} or
    *         already added before.
@@ -133,7 +133,7 @@ public final class Closeables implements Closeable {
 
   /**
    * Adds the given closeable.
-   * 
+   *
    * @param closeable The closeable.
    * @return {@code true} iff the closeable was added, {@code false} if it was {@code null} or
    *         already added before.
@@ -144,7 +144,7 @@ public final class Closeables implements Closeable {
 
   /**
    * Removes the given closeable.
-   * 
+   *
    * @param closeable The closeable.
    * @return {@code true} iff the closeable was removed, {@code fale} if it was {@code null} or not
    *         previously added.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/DatagramSocketImplShim.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/DatagramSocketImplShim.java
index 6ee2954..7cbda33 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/DatagramSocketImplShim.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/DatagramSocketImplShim.java
@@ -24,7 +24,7 @@ import java.util.Set;
 
 /**
  * A shim that is filled with Java version-specific overrides. This variant is for Java 9 and above.
- * 
+ *
  * @author Christian Kohlschütter
  */
 abstract class DatagramSocketImplShim extends DatagramSocketImpl {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/DatagramSocketShim.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/DatagramSocketShim.java
new file mode 100644
index 0000000..5c86081
--- /dev/null
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/DatagramSocketShim.java
@@ -0,0 +1,70 @@
+/*
+ * junixsocket
+ *
+ * Copyright 2009-2022 Christian Kohlschütter
+ *
+ * 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 org.newsclub.net.unix;
+
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.DatagramSocketImpl;
+import java.net.SocketOption;
+
+abstract class DatagramSocketShim extends DatagramSocket {
+
+  protected DatagramSocketShim(DatagramSocketImpl impl) {
+    super(impl);
+  }
+
+  @Override
+  public <T> T getOption(SocketOption<T> name) throws IOException {
+    if (name instanceof AFSocketOption<?>) {
+      return getOption((AFSocketOption<T>) name);
+    } else {
+      return super.getOption(name);
+    }
+  }
+
+  @Override
+  public <T> DatagramSocket setOption(SocketOption<T> name, T value) throws IOException {
+    if (name instanceof AFSocketOption<?>) {
+      return setOption((AFSocketOption<T>) name, value);
+    } else {
+      return super.setOption(name, value);
+    }
+  }
+
+  /**
+   * Returns the value of a junixsocket socket option.
+   *
+   * @param <T> The type of the socket option value.
+   * @param name The socket option.
+   * @return The value of the socket option.
+   * @throws IOException on error.
+   */
+  public abstract <T> T getOption(AFSocketOption<T> name) throws IOException;
+
+  /**
+   * Sets the value of a socket option.
+   *
+   * @param <T> The type of the socket option value.
+   * @param name The socket option.
+   * @param value The value of the socket option.
+   * @return this DatagramSocket.
+   * @throws IOException on error.
+   */
+  @SuppressWarnings("PMD.LinguisticNaming")
+  public abstract <T> DatagramSocket setOption(AFSocketOption<T> name, T value) throws IOException;
+}
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorAccess.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorAccess.java
index 15f5da8..0298c35 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorAccess.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorAccess.java
@@ -22,13 +22,13 @@ import java.io.IOException;
 
 /**
  * Something that has a {@link FileDescriptor}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public interface FileDescriptorAccess {
   /**
    * Returns the corresponding {@link FileDescriptor}.
-   * 
+   *
    * @return The corresponding {@link FileDescriptor}.
    * @throws IOException on error.
    */
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorCast.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorCast.java
index e77caa5..e9d7b35 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorCast.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/FileDescriptorCast.java
@@ -46,16 +46,16 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
  * </p>
  * <pre><code>
  * FileDescriptor fd;
- * 
+ *
  * // succeeds if fd refers to an AF_UNIX stream socket
- * AFUNIXSocket socket = FileDescriptorCast.using(fd).as(AFUNIXSocket.class); 
- * 
+ * AFUNIXSocket socket = FileDescriptorCast.using(fd).as(AFUNIXSocket.class);
+ *
  * // succeeds if fd refers to an AF_UNIX datagram socket
- * AFUNIXDatagramChannel channel = FileDescriptorCast.using(fd).as(AFUNIXDatagramChannel.class); 
- * 
+ * AFUNIXDatagramChannel channel = FileDescriptorCast.using(fd).as(AFUNIXDatagramChannel.class);
+ *
  * // always succeeds
- * InputStream in = FileDescriptorCast.using(fd).as(InputStream.class); 
- * OutputStream in = FileDescriptorCast.using(fd).as(OutputStream.class); 
+ * InputStream in = FileDescriptorCast.using(fd).as(InputStream.class);
+ * OutputStream in = FileDescriptorCast.using(fd).as(OutputStream.class);
  * </code></pre>
  * <p>
  * IMPORTANT: On some platforms (e.g., Solaris, Illumos) you may need to re-apply a read timeout
@@ -66,7 +66,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
  * that do not encode this information directly (such as {@link AFUNIXSocketAddress} and
  * {@link AFTIPCSocketAddress}).
  * </p>
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class FileDescriptorCast implements FileDescriptorAccess {
@@ -108,7 +108,6 @@ public final class FileDescriptorCast implements FileDescriptorAccess {
         }
       });
       addProvider(ReadableByteChannel.class, new CastingProvider<ReadableByteChannel>() {
-        @SuppressWarnings("resource")
         @Override
         public ReadableByteChannel provideAs(FileDescriptorCast fdc,
             Class<? super ReadableByteChannel> desiredType) throws IOException {
@@ -270,7 +269,7 @@ public final class FileDescriptorCast implements FileDescriptorAccess {
 
   /**
    * Creates a {@link FileDescriptorCast} using the given file descriptor.
-   * 
+   *
    * @param fdObj The file descriptor.
    * @return The {@link FileDescriptorCast} instance.
    * @throws IOException on error, especially if the given file descriptor is invalid or
@@ -298,10 +297,10 @@ public final class FileDescriptorCast implements FileDescriptorAccess {
 
   /**
    * Registers the given port number as the "local port" for this file descriptor.
-   * 
+   *
    * Important: This only changes the state of this instance. The actual file descriptor is not
    * affected.
-   * 
+   *
    * @param port The port to assign to (must be &gt;= 0).
    * @return This instance.
    */
@@ -315,10 +314,10 @@ public final class FileDescriptorCast implements FileDescriptorAccess {
 
   /**
    * Registers the given port number as the "remote port" for this file descriptor.
-   * 
+   *
    * Important: This only changes the state of this instance. The actual file descriptor is not
    * affected.
-   * 
+   *
    * @param port The port to assign to (must be &gt;= 0).
    * @return This instance.
    */
@@ -332,7 +331,7 @@ public final class FileDescriptorCast implements FileDescriptorAccess {
 
   /**
    * Casts this instance to the desired type.
-   * 
+   *
    * @param <K> The desired type.
    * @param desiredType The class of the desired type.
    * @return s An instance of the desired type.
@@ -357,7 +356,7 @@ public final class FileDescriptorCast implements FileDescriptorAccess {
 
   /**
    * Checks if the instance can be cast as the given desired type (using {@link #as(Class)}).
-   * 
+   *
    * @param desiredType The class of the desired type.
    * @return {@code true} if the cast can be made.
    * @throws IOException on error.
@@ -370,7 +369,7 @@ public final class FileDescriptorCast implements FileDescriptorAccess {
   /**
    * Returns a collection of available types this instance can be cast to (using
    * {@link #as(Class)}).
-   * 
+   *
    * @return The collection of available types.
    */
   public Set<Class<?>> availableTypes() {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/HostAndPort.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/HostAndPort.java
index ba17827..5f8fb49 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/HostAndPort.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/HostAndPort.java
@@ -28,7 +28,7 @@ import java.util.regex.Pattern;
 
 /**
  * Hostname and port.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class HostAndPort {
@@ -39,7 +39,7 @@ public final class HostAndPort {
 
   /**
    * Creates a new hostname and port combination.
-   * 
+   *
    * @param hostname The hostname.
    * @param port The port, or {@code -1} for "no port".
    */
@@ -88,7 +88,7 @@ public final class HostAndPort {
 
   /**
    * Tries to extract hostname and port information from the given URI.
-   * 
+   *
    * @param u The URI to extract from.
    * @return The parsed {@link HostAndPort} instance.
    * @throws SocketException on error.
@@ -130,7 +130,7 @@ public final class HostAndPort {
 
   /**
    * Returns the hostname.
-   * 
+   *
    * @return The hostname.
    */
   public String getHostname() {
@@ -139,7 +139,7 @@ public final class HostAndPort {
 
   /**
    * Returns the port, or {@code -1} for "no port specified".
-   * 
+   *
    * @return The port.
    */
   public int getPort() {
@@ -148,7 +148,7 @@ public final class HostAndPort {
 
   /**
    * Returns a URI with this hostname and port.
-   * 
+   *
    * @param scheme The scheme to use.
    * @return The URI.
    */
@@ -159,7 +159,7 @@ public final class HostAndPort {
   /**
    * Returns a URI with this hostname and port, potentially reusing other URI parameters from the
    * given template URI (authority, path, query, fragment).
-   * 
+   *
    * @param scheme The scheme to use.
    * @param template The template. or {@code null}.
    * @return The URI.
@@ -192,7 +192,7 @@ public final class HostAndPort {
   /**
    * Returns a URI with this hostname and port, potentially using other URI parameters from the
    * given set of parameters.
-   * 
+   *
    * @param scheme The scheme to use.
    * @param rawAuthority The raw authority field, or {@code null}.
    * @param rawPath The raw path field, or {@code null}.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/InvalidArgumentSocketException.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/InvalidArgumentSocketException.java
index b644cfc..6860dbf 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/InvalidArgumentSocketException.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/InvalidArgumentSocketException.java
@@ -22,7 +22,7 @@ import java.net.SocketException;
 /**
  * A {@link SocketException} that may be thrown upon some "invalid argument" being passed into
  * native code (i.e., EINVAL is returned).
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class InvalidArgumentSocketException extends InvalidSocketException {
@@ -37,7 +37,7 @@ public class InvalidArgumentSocketException extends InvalidSocketException {
 
   /**
    * Constructs a new {@link InvalidArgumentSocketException}.
-   * 
+   *
    * @param msg The error message.
    */
   public InvalidArgumentSocketException(String msg) {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/InvalidSocketException.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/InvalidSocketException.java
index c1aaa8a..b4381ca 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/InvalidSocketException.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/InvalidSocketException.java
@@ -22,7 +22,7 @@ import java.net.SocketException;
 /**
  * A {@link SocketException} that may be thrown upon some "invalid" state, mostly detected in native
  * code.
- * 
+ *
  * @author Christian Kohlschütter
  * @see InvalidArgumentSocketException
  * @see AddressUnavailableSocketException
@@ -40,7 +40,7 @@ public class InvalidSocketException extends SocketException {
 
   /**
    * Constructs a new {@link InvalidSocketException}.
-   * 
+   *
    * @param msg The error message.
    */
   public InvalidSocketException(String msg) {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/NamedInteger.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/NamedInteger.java
index 647a329..aca83ba 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/NamedInteger.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/NamedInteger.java
@@ -27,9 +27,9 @@ import org.eclipse.jdt.annotation.Nullable;
 
 /**
  * A "named integer", usually used for constants.
- * 
+ *
  * See the concrete implementations for usage.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @NonNullByDefault
@@ -57,7 +57,7 @@ public class NamedInteger implements Serializable {
   /**
    * Creates a new {@link NamedInteger} instance, without actually naming it. A name of "UNDEFINED"
    * is used.
-   * 
+   *
    * @param id The value.
    */
   protected NamedInteger(int id) {
@@ -66,7 +66,7 @@ public class NamedInteger implements Serializable {
 
   /**
    * Creates a new {@link NamedInteger} instance.
-   * 
+   *
    * @param name The name.
    * @param id The value.
    */
@@ -77,7 +77,7 @@ public class NamedInteger implements Serializable {
 
   /**
    * Returns the name.
-   * 
+   *
    * @return The name.
    */
   public final String name() {
@@ -86,7 +86,7 @@ public class NamedInteger implements Serializable {
 
   /**
    * Returns the value.
-   * 
+   *
    * @return The value.
    */
   public final int value() {
@@ -118,7 +118,7 @@ public class NamedInteger implements Serializable {
 
   /**
    * Ensures that the {@code VALUES} array is configured correctly.
-   * 
+   *
    * @param <T> The instance type.
    * @param values The {@code VALUES} array.
    * @return The verified {@code VALUES} array.
@@ -135,14 +135,14 @@ public class NamedInteger implements Serializable {
 
   /**
    * Constructor for "undefined" values.
-   * 
+   *
    * @param <T> The instance type.
    */
   @FunctionalInterface
   protected interface UndefinedValueConstructor<T extends NamedInteger> {
     /**
      * Creates a new "undefined" value instance.
-     * 
+     *
      * @param id The value.
      * @return The instance.
      */
@@ -151,7 +151,7 @@ public class NamedInteger implements Serializable {
 
   /**
    * Returns an instance given an integer value.
-   * 
+   *
    * @param <T> The instance type.
    * @param values The {@code VALUES} array.
    * @param constr The constructor for undefined values.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/NamedIntegerBitmask.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/NamedIntegerBitmask.java
index af525de..995ee41 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/NamedIntegerBitmask.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/NamedIntegerBitmask.java
@@ -28,7 +28,7 @@ import org.eclipse.jdt.annotation.Nullable;
 
 /**
  * Describes a 32-bit bitmask that supports named flags.
- * 
+ *
  * @param <T> The subclass's type itself.
  * @author Christian Kohlschütter
  */
@@ -49,7 +49,7 @@ public abstract class NamedIntegerBitmask<T extends NamedIntegerBitmask<T>> impl
 
   /**
    * Creates a new named flag.
-   * 
+   *
    * @param name The name of the flag / flag set.
    * @param flags The flag value.
    */
@@ -60,7 +60,7 @@ public abstract class NamedIntegerBitmask<T extends NamedIntegerBitmask<T>> impl
 
   /**
    * Returns the name of the flag / flag set.
-   * 
+   *
    * @return The name.
    */
   public final String name() {
@@ -69,7 +69,7 @@ public abstract class NamedIntegerBitmask<T extends NamedIntegerBitmask<T>> impl
 
   /**
    * Returns the value of the flag / flag set.
-   * 
+   *
    * @return The value.
    */
   public final int value() {
@@ -78,7 +78,7 @@ public abstract class NamedIntegerBitmask<T extends NamedIntegerBitmask<T>> impl
 
   /**
    * Checks if the given flag is set.
-   * 
+   *
    * @param flag The flag to check.
    * @return {@code true} iff set.
    */
@@ -95,7 +95,7 @@ public abstract class NamedIntegerBitmask<T extends NamedIntegerBitmask<T>> impl
   /**
    * Combines two flags / flag sets (use this to implement
    * {@link #combineWith(NamedIntegerBitmask)}).
-   * 
+   *
    * @param allFlags The array of all defined flags, expected "none".
    * @param flagsNone The "none" flag set.
    * @param constr The constructor.
@@ -109,7 +109,7 @@ public abstract class NamedIntegerBitmask<T extends NamedIntegerBitmask<T>> impl
 
   /**
    * Combines two flags / flag sets.
-   * 
+   *
    * @param other The other flag / flag set.
    * @return An instance combining both.
    */
@@ -118,14 +118,14 @@ public abstract class NamedIntegerBitmask<T extends NamedIntegerBitmask<T>> impl
 
   /**
    * Creates a new instance.
-   * 
+   *
    * @param <T> This type.
    */
   @FunctionalInterface
   protected interface Constructor<T extends NamedIntegerBitmask<T>> {
     /**
      * Creates a new instance.
-     * 
+     *
      * @param name The name.
      * @param flags The flag value.
      * @return The instance.
@@ -135,7 +135,7 @@ public abstract class NamedIntegerBitmask<T extends NamedIntegerBitmask<T>> impl
 
   /**
    * Returns a {@link NamedIntegerBitmask} instance given a flag value.
-   * 
+   *
    * @param <T> The subclass's type itself.
    * @param allFlags The array of all defined flags, expected "none".
    * @param flagsNone The "none" flag set.
@@ -167,7 +167,7 @@ public abstract class NamedIntegerBitmask<T extends NamedIntegerBitmask<T>> impl
 
   /**
    * Returns a {@link NamedIntegerBitmask} instance given a series of flags.
-   * 
+   *
    * @param <T> The subclass's type itself.
    * @param allFlags The array of all defined flags, expected "none".
    * @param flagsNone The "none" flag set.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
index eb225b1..d34af59 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeLibraryLoader.java
@@ -56,7 +56,7 @@ final class NativeLibraryLoader implements Closeable {
 
   /**
    * Returns the temporary directory where the native library is extracted to; debugging only.
-   * 
+   *
    * @return The temporary directory.
    */
   static File tempDir() {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeUnixSocket.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeUnixSocket.java
index 18ef5de..facf61f 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeUnixSocket.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/NativeUnixSocket.java
@@ -36,7 +36,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * JNI connector to native JNI C code.
- * 
+ *
  * @author Christian Kohlschütter
  */
 final class NativeUnixSocket {
@@ -106,7 +106,7 @@ final class NativeUnixSocket {
   static UnsupportedOperationException unsupportedException() {
     if (!isLoaded()) {
       return (UnsupportedOperationException) new UnsupportedOperationException(
-          "junixsocket is not supported on this platform").initCause(initError);
+          "junixsocket may not be fully supported on this platform").initCause(initError);
     } else {
       return null;
     }
@@ -161,7 +161,7 @@ final class NativeUnixSocket {
 
   /**
    * Reads data from an {@link AFSocketImpl}.
-   * 
+   *
    * @param fd The corresponding file descriptor.
    * @param buf The buffer to read into, or {@code null} if a single byte should be read.
    * @param off The buffer offset.
@@ -177,7 +177,7 @@ final class NativeUnixSocket {
 
   /**
    * Writes data to an {@link AFSocketImpl}.
-   * 
+   *
    * @param fd The corresponding file descriptor.
    * @param buf The buffer to write from, or {@code null} if a single byte should be written.
    * @param off The buffer offset, or the byte to write if {@code buf} is {@code null}.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/OperationNotSupportedSocketException.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/OperationNotSupportedSocketException.java
index f97dce1..4aa38a2 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/OperationNotSupportedSocketException.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/OperationNotSupportedSocketException.java
@@ -22,7 +22,7 @@ import java.net.SocketException;
 /**
  * A {@link SocketException} that may be thrown upon some "unsupported operation" condition from
  * native code (e.g., EOPNOTSUPP is returned).
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class OperationNotSupportedSocketException extends InvalidSocketException {
@@ -37,7 +37,7 @@ public class OperationNotSupportedSocketException extends InvalidSocketException
 
   /**
    * Constructs a new {@link OperationNotSupportedSocketException}.
-   * 
+   *
    * @param msg The error message.
    */
   public OperationNotSupportedSocketException(String msg) {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/RAFChannelProvider.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/RAFChannelProvider.java
index 21b9b26..34c51cf 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/RAFChannelProvider.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/RAFChannelProvider.java
@@ -27,7 +27,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * Hack to get a readable AND writable {@link FileChannel} for a {@link FileDescriptor}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 final class RAFChannelProvider extends RandomAccessFile implements FileDescriptorAccess {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketAddressFilter.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketAddressFilter.java
index 5c82039..6d46903 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketAddressFilter.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketAddressFilter.java
@@ -23,7 +23,7 @@ import java.net.SocketAddress;
 /**
  * A filter that takes a {@link SocketAddress}, and potentially changes it, or throws an exception
  * if certain criteria are met.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @FunctionalInterface
@@ -31,7 +31,7 @@ public interface SocketAddressFilter {
 
   /**
    * Applies the filter on the given address.
-   * 
+   *
    * @param address The address.
    * @return The address itself or a changed address.
    * @throws IOException on error or if a certain error condition is desired.
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketClosedException.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketClosedException.java
index afce7ad..f701c2c 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketClosedException.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketClosedException.java
@@ -21,7 +21,7 @@ import java.net.SocketException;
 
 /**
  * A {@link SocketException} indicating that a socket was closed or is not open for other reasons.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class SocketClosedException extends SocketException {
@@ -36,7 +36,7 @@ public final class SocketClosedException extends SocketException {
 
   /**
    * Constructs a new {@link SocketClosedException}.
-   * 
+   *
    * @param msg The error message.
    */
   public SocketClosedException(String msg) {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketImplShim.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketImplShim.java
index c5829ad..ec176ff 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketImplShim.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketImplShim.java
@@ -21,7 +21,7 @@ import java.net.SocketImpl;
 
 /**
  * A shim that is filled with Java version-specific overrides. This variant is for Java 9 and above.
- * 
+ *
  * @author Christian Kohlschütter
  */
 abstract class SocketImplShim extends SocketImpl {
diff --git a/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketOptionsMapper.java b/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketOptionsMapper.java
index ebc58ac..07e701e 100644
--- a/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketOptionsMapper.java
+++ b/junixsocket-common/src/main/java/org/newsclub/net/unix/SocketOptionsMapper.java
@@ -28,7 +28,7 @@ import java.util.Set;
 
 /**
  * Maps new SocketOption classes to the old integer-based scheme.
- * 
+ *
  * @author Christian Kohlschütter
  */
 final class SocketOptionsMapper {
diff --git a/junixsocket-common/src/main/java8/org/newsclub/net/unix/AFInputStream.java b/junixsocket-common/src/main/java8/org/newsclub/net/unix/AFInputStream.java
index bd11450..0cc123f 100644
--- a/junixsocket-common/src/main/java8/org/newsclub/net/unix/AFInputStream.java
+++ b/junixsocket-common/src/main/java8/org/newsclub/net/unix/AFInputStream.java
@@ -1,3 +1,20 @@
+/*
+ * junixsocket
+ *
+ * Copyright 2009-2022 Christian Kohlschütter
+ *
+ * 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 org.newsclub.net.unix;
 
 import java.io.IOException;
diff --git a/junixsocket-common/src/main/java8/org/newsclub/net/unix/AFOutputStream.java b/junixsocket-common/src/main/java8/org/newsclub/net/unix/AFOutputStream.java
index 4523aa8..cd7e4e7 100644
--- a/junixsocket-common/src/main/java8/org/newsclub/net/unix/AFOutputStream.java
+++ b/junixsocket-common/src/main/java8/org/newsclub/net/unix/AFOutputStream.java
@@ -1,3 +1,20 @@
+/*
+ * junixsocket
+ *
+ * Copyright 2009-2022 Christian Kohlschütter
+ *
+ * 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 org.newsclub.net.unix;
 
 import java.io.IOException;
@@ -16,11 +33,11 @@ public abstract class AFOutputStream extends OutputStream implements FileDescrip
    * Reads all bytes from the given input stream and writes the bytes to this output stream in the
    * order that they are read. On return, this input stream will be at end of stream. This method
    * does not close either stream.
-   * 
+   *
    * This method effectively is the reverse notation of
    * {@link InputStream#transferTo(OutputStream)}, which may or may not be optimized for
    * {@link AFSocket}s.
-   * 
+   *
    * @param in The {@link InputStream} to transfer from.
    * @return The number of bytes transferred.
    * @throws IOException on error.
diff --git a/junixsocket-common/src/main/java8/org/newsclub/net/unix/CleanableState.java b/junixsocket-common/src/main/java8/org/newsclub/net/unix/CleanableState.java
index d787047..c98a3ec 100644
--- a/junixsocket-common/src/main/java8/org/newsclub/net/unix/CleanableState.java
+++ b/junixsocket-common/src/main/java8/org/newsclub/net/unix/CleanableState.java
@@ -1,3 +1,20 @@
+/*
+ * junixsocket
+ *
+ * Copyright 2009-2022 Christian Kohlschütter
+ *
+ * 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 org.newsclub.net.unix;
 
 import java.io.Closeable;
diff --git a/junixsocket-common/src/main/java8/org/newsclub/net/unix/DatagramSocketImplShim.java b/junixsocket-common/src/main/java8/org/newsclub/net/unix/DatagramSocketImplShim.java
index 3bdb3ac..b035322 100644
--- a/junixsocket-common/src/main/java8/org/newsclub/net/unix/DatagramSocketImplShim.java
+++ b/junixsocket-common/src/main/java8/org/newsclub/net/unix/DatagramSocketImplShim.java
@@ -1,10 +1,27 @@
+/*
+ * junixsocket
+ *
+ * Copyright 2009-2022 Christian Kohlschütter
+ *
+ * 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 org.newsclub.net.unix;
 
 import java.net.DatagramSocketImpl;
 
 /**
  * A shim that is filled with Java version-specific overrides. This variant is for Java 7 and 8.
- * 
+ *
  * @author Christian Kohlschütter
  */
 abstract class DatagramSocketImplShim extends DatagramSocketImpl {
diff --git a/junixsocket-common/src/main/java8/org/newsclub/net/unix/DatagramSocketShim.java b/junixsocket-common/src/main/java8/org/newsclub/net/unix/DatagramSocketShim.java
new file mode 100644
index 0000000..e25c52f
--- /dev/null
+++ b/junixsocket-common/src/main/java8/org/newsclub/net/unix/DatagramSocketShim.java
@@ -0,0 +1,51 @@
+/*
+ * junixsocket
+ *
+ * Copyright 2009-2022 Christian Kohlschütter
+ *
+ * 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 org.newsclub.net.unix;
+
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.DatagramSocketImpl;
+
+abstract class DatagramSocketShim extends DatagramSocket {
+
+  protected DatagramSocketShim(DatagramSocketImpl impl) {
+    super(impl);
+  }
+
+  /**
+   * Returns the value of a junixsocket socket option.
+   *
+   * @param <T> The type of the socket option value.
+   * @param name The socket option.
+   * @return The value of the socket option.
+   * @throws IOException on error.
+   */
+  public abstract <T> T getOption(AFSocketOption<T> name) throws IOException;
+
+  /**
+   * Sets the value of a socket option.
+   *
+   * @param <T> The type of the socket option value.
+   * @param name The socket option.
+   * @param value The value of the socket option.
+   * @return this DatagramSocket.
+   * @throws IOException on error.
+   */
+  @SuppressWarnings("PMD.LinguisticNaming")
+  public abstract <T> DatagramSocket setOption(AFSocketOption<T> name, T value) throws IOException;
+}
diff --git a/junixsocket-common/src/main/java8/org/newsclub/net/unix/SocketImplShim.java b/junixsocket-common/src/main/java8/org/newsclub/net/unix/SocketImplShim.java
index d5e3d89..ff6f22f 100644
--- a/junixsocket-common/src/main/java8/org/newsclub/net/unix/SocketImplShim.java
+++ b/junixsocket-common/src/main/java8/org/newsclub/net/unix/SocketImplShim.java
@@ -1,3 +1,20 @@
+/*
+ * junixsocket
+ *
+ * Copyright 2009-2022 Christian Kohlschütter
+ *
+ * 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 org.newsclub.net.unix;
 
 import java.io.IOException;
@@ -8,7 +25,7 @@ import java.util.Set;
 
 /**
  * A shim that is filled with Java version-specific overrides. This variant is for Java 7 and 8.
- * 
+ *
  * @author Christian Kohlschütter
  */
 abstract class SocketImplShim extends SocketImpl {
diff --git a/junixsocket-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-common/jni-config.json b/junixsocket-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-common/jni-config.json
index ca3ffe2..11091a6 100644
--- a/junixsocket-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-common/jni-config.json
+++ b/junixsocket-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-common/jni-config.json
@@ -141,9 +141,11 @@
   "methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
 },
 {
+  "condition" : { "typeReachable" : "org.newsclub.net.unix.tipc.AFTIPCDatagramSocket" },
   "name":"org.newsclub.net.unix.tipc.AFTIPCDatagramSocket"
 },
 {
+  "condition" : { "typeReachable" : "org.newsclub.net.unix.tipc.AFTIPCGroupRequest" },
   "name":"org.newsclub.net.unix.tipc.AFTIPCGroupRequest",
   "methods":[
     {"name":"fromNative","parameterTypes":["int","int","int","int"] }, 
@@ -154,15 +156,40 @@
   ]
 },
 {
+  "condition" : { "typeReachable" : "org.newsclub.net.unix.tipc.AFTIPCSocket" },
   "name":"org.newsclub.net.unix.tipc.AFTIPCSocket"
 },
 {
+  "condition" : { "typeReachable" : "org.newsclub.net.unix.tipc.AFVSOCKDatagramSocket" },
   "name":"org.newsclub.net.unix.vsock.AFVSOCKDatagramSocket"
 },
 {
+  "condition" : { "typeReachable" : "org.newsclub.net.unix.tipc.AFVSOCKSocket" },
   "name":"org.newsclub.net.unix.vsock.AFVSOCKSocket"
 },
 {
+  "condition" : { "typeReachable" : "org.newsclub.net.unix.tipc.AFVSOCKServerSocket" },
   "name":"org.newsclub.net.unix.vsock.AFVSOCKServerSocket"
+},
+{
+  "name":"java.net.SocketImpl"
+},
+{
+  "name":"java.net.DatagramSocketImpl"
+},
+{
+  "name":"org.newsclub.net.unix.AFSocketImpl"
+},
+{
+  "name":"org.newsclub.net.unix.SocketImplShim"
+},
+{
+  "name":"org.newsclub.net.unix.AFUNIXSocketImpl"
+},
+{
+  "name":"org.newsclub.net.unix.AFUNIXDatagramSocketImpl"
+},
+{
+  "name":"org.newsclub.net.unix.AFDatagramSocketImpl"
 }
-]
\ No newline at end of file
+]
diff --git a/junixsocket-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-common/reflect-config.json b/junixsocket-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-common/reflect-config.json
index 7c4e0ed..38c6410 100644
--- a/junixsocket-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-common/reflect-config.json
+++ b/junixsocket-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-common/reflect-config.json
@@ -3,14 +3,13 @@
   "name":"java.nio.channels.spi.AbstractSelectableChannel"
 },
 {
+  "condition" : { "typeReachable" : "org.newsclub.lib.junixsocket.common.NarMetadata" },
   "name":"org.newsclub.lib.junixsocket.common.NarMetadata"
 },
 {
+  "condition" : { "typeReachable" : "org.newsclub.lib.junixsocket.custom.NarMetadata" },
   "name":"org.newsclub.lib.junixsocket.custom.NarMetadata"
 },
-{
-  "name":"org.newsclub.net.unix.AFSocketCapabilityRequirement"
-},
 {
   "name":"org.newsclub.net.unix.AFTIPCSocketAddress",
   "methods":[{"name":"addressFamily","parameterTypes":[] }]
@@ -24,9 +23,17 @@
   "methods":[{"name":"addressFamily","parameterTypes":[] }]
 },
 {
-  "name":"org.newsclub.net.unix.tipc.AFTIPCSelectorProvider"
+  "name":"org.newsclub.net.unix.AFUNIXSelectorProvider",
+  "allPublicMethods":true
+},
+{
+  "condition" : { "typeReachable" : "org.newsclub.net.unix.tipc.AFTIPCSelectorProvider" },
+  "name":"org.newsclub.net.unix.tipc.AFTIPCSelectorProvider",
+  "allPublicMethods":true
 },
 {
-  "name":"org.newsclub.net.unix.vsock.AFVSOCKSelectorProvider"
+  "condition" : { "typeReachable" : "org.newsclub.net.unix.vsock.AFVSOCKSelectorProvider" },
+  "name":"org.newsclub.net.unix.vsock.AFVSOCKSelectorProvider",
+  "allPublicMethods":true
 }
 ]
diff --git a/junixsocket-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-common/resource-config.json b/junixsocket-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-common/resource-config.json
index d75817c..081835e 100644
--- a/junixsocket-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-common/resource-config.json
+++ b/junixsocket-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-common/resource-config.json
@@ -5,9 +5,11 @@
       "pattern":"\\QMETA-INF/maven/com.kohlschutter.junixsocket/junixsocket-common/pom.properties\\E"
     }, 
     {
+      "condition" : { "typeReachable" : "org.newsclub.lib.junixsocket.common.NarMetadata" },
       "pattern":"\\QMETA-INF/maven/com.kohlschutter.junixsocket/junixsocket-native-common/pom.properties\\E"
     }, 
     {
+      "condition" : { "typeReachable" : "org.newsclub.lib.junixsocket.custom.NarMetadata" },
       "pattern":"\\QMETA-INF/maven/com.kohlschutter.junixsocket/junixsocket-native-custom/pom.properties\\E"
     }
   ]},
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/AFDatagramUtil.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/AFDatagramUtil.java
index db1cf67..b610878 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/AFDatagramUtil.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/AFDatagramUtil.java
@@ -23,7 +23,7 @@ import com.kohlschutter.annotations.compiletime.ExcludeFromCodeCoverageGenerated
 
 /**
  * Helper methods for datagrams, but mostly for testing.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFDatagramUtil {
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/AFTIPCSocketAddressTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/AFTIPCSocketAddressTest.java
index ec22687..b497db5 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/AFTIPCSocketAddressTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/AFTIPCSocketAddressTest.java
@@ -18,7 +18,7 @@
 package org.newsclub.net.unix;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -125,12 +125,19 @@ public class AFTIPCSocketAddressTest {
 
   @Test
   public void testSocatString() throws Exception {
-    String socatString = AFTIPCSocketAddress.ofService(123, 456).toSocatAddressString(
-        AFSocketType.SOCK_STREAM, AFSocketProtocol.DEFAULT);
-    if (socatString == null) {
-      assertFalse(AFSocket.supports(AFSocketCapability.CAPABILITY_TIPC));
-    } else {
-      assertTrue(socatString.contains(":"));
+    String socatString;
+    try {
+      socatString = AFTIPCSocketAddress.ofService(123, 456).toSocatAddressString(
+          AFSocketType.SOCK_STREAM, AFSocketProtocol.DEFAULT);
+      assertNotNull(socatString);
+    } catch (SocketException e) {
+      if (AFSocket.supports(AFSocketCapability.CAPABILITY_TIPC)) {
+        throw e;
+      } else {
+        // expected
+        return;
+      }
     }
+    assertTrue(socatString.contains(":"));
   }
 }
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/AFUNIXSocketAddressTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/AFUNIXSocketAddressTest.java
index 828125a..10da058 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/AFUNIXSocketAddressTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/AFUNIXSocketAddressTest.java
@@ -22,7 +22,11 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.net.URI;
 import java.util.Arrays;
 
@@ -133,4 +137,22 @@ public class AFUNIXSocketAddressTest {
     assertNotNull(AFUNIXSocketAddress.inAbstractNamespace("test"));
     assertNotNull(AFUNIXSocketAddress.inAbstractNamespace("test", 1234));
   }
+
+  @Test
+  public void testSerialize() throws Exception {
+    try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(bos)) {
+
+      AFUNIXSocketAddress addr = AFUNIXSocketAddress.of(URI.create("file:/tmp/yo"));
+      oos.writeObject(addr);
+      oos.flush();
+
+      try (ObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(bos
+          .toByteArray()))) {
+        AFUNIXSocketAddress addr2 = (AFUNIXSocketAddress) oin.readObject();
+        assertEquals(addr, addr2);
+        assertEquals(addr.getAddressFamily(), addr2.getAddressFamily());
+      }
+    }
+  }
 }
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/AFVSOCKSocketAddressTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/AFVSOCKSocketAddressTest.java
index 8a13033..f18103e 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/AFVSOCKSocketAddressTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/AFVSOCKSocketAddressTest.java
@@ -18,7 +18,7 @@
 package org.newsclub.net.unix;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -96,12 +96,19 @@ public class AFVSOCKSocketAddressTest {
 
   @Test
   public void testSocatString() throws Exception {
-    String socatString = AFVSOCKSocketAddress.ofPortAndCID(123, 4).toSocatAddressString(
-        AFSocketType.SOCK_STREAM, AFSocketProtocol.DEFAULT);
-    if (socatString == null) {
-      assertFalse(AFSocket.supports(AFSocketCapability.CAPABILITY_VSOCK));
-    } else {
-      assertTrue(socatString.contains(":"));
+    String socatString;
+    try {
+      socatString = AFVSOCKSocketAddress.ofPortAndCID(123, 4).toSocatAddressString(
+          AFSocketType.SOCK_STREAM, AFSocketProtocol.DEFAULT);
+      assertNotNull(socatString);
+    } catch (SocketException e) {
+      if (AFSocket.supports(AFSocketCapability.CAPABILITY_VSOCK)) {
+        throw e;
+      } else {
+        // expected
+        return;
+      }
     }
+    assertTrue(socatString.contains(":"));
   }
 }
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/AcceptTimeoutTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/AcceptTimeoutTest.java
index 58f14c1..4353a48 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/AcceptTimeoutTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/AcceptTimeoutTest.java
@@ -42,7 +42,7 @@ import com.kohlschutter.testutil.TestAbortedWithImportantMessageException.Messag
 
 /**
  * Verifies that accept properly times out when an soTimeout was specified.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @SuppressFBWarnings({
@@ -144,7 +144,7 @@ public abstract class AcceptTimeoutTest<A extends SocketAddress> extends SocketT
                   }
 
                   System.out.println("SocketTimeout, trying connect again (" + i + ")");
-                  e.printStackTrace();
+                  // e.printStackTrace();
                   continue;
                 } catch (TestAbortedWithImportantMessageException e) {
                   runtimeExceptionCF.complete(e);
@@ -194,7 +194,7 @@ public abstract class AcceptTimeoutTest<A extends SocketAddress> extends SocketT
   /**
    * Subclasses may override this to tell that there is a known issue with "Accept timeout after
    * delay".
-   * 
+   *
    * @param serverAddr The server address.
    * @return An explanation iff this should not cause a test failure but trigger "With issues".
    */
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/AddressSpecifics.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/AddressSpecifics.java
index 3e5d3a7..0f5f62d 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/AddressSpecifics.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/AddressSpecifics.java
@@ -31,13 +31,13 @@ import java.nio.channels.spi.SelectorProvider;
 
 /**
  * Test-related methods to work with a particular {@link AFSocket} implementation.
- * 
+ *
  * It is essential to use these methods in tests instead of directly calling the {@link AFSocket}
  * etc. methods: Some socket implementations (and sometimes only in certain kernel/environment
  * configurations) may expose unexpected behavior that is otherwise hard to catch.
- * 
+ *
  * This is especially relevant when connecting/binding sockets.
- * 
+ *
  * @param <A> The socket address.
  * @author Christian Kohlschütter
  * @see SocketTestBase
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/CancelAcceptTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/CancelAcceptTest.java
index d40fdc7..fcbe9e3 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/CancelAcceptTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/CancelAcceptTest.java
@@ -36,7 +36,7 @@ import com.kohlschutter.testutil.TestAbortedWithImportantMessageException.Messag
 
 /**
  * Tests breaking out of accept.
- * 
+ *
  * @see <a href="http://code.google.com/p/junixsocket/issues/detail?id=6">Issue 6</a>
  */
 @SuppressFBWarnings({
@@ -139,7 +139,7 @@ public abstract class CancelAcceptTest<A extends SocketAddress> extends SocketTe
   /**
    * Subclasses may override this to tell that there is a known condition where an otherwise
    * expected SocketException is not thrown.
-   * 
+   *
    * @return An explanation iff this should not cause a test failure but just add a notice.
    */
   protected String checkKnownConditionDidNotThrowSocketException() {
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/EndOfFileTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/EndOfFileTest.java
index 37408db..5c6d5f7 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/EndOfFileTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/EndOfFileTest.java
@@ -43,7 +43,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * See http://code.google.com/p/junixsocket/issues/detail?id=9
- * 
+ *
  * @author Derrick Rice (April, 2010)
  */
 @SuppressFBWarnings({
@@ -234,11 +234,11 @@ public abstract class EndOfFileTest<A extends SocketAddress> extends SocketTestB
       try {
         /*
          * http://www.unixguide.net/network/socketfaq/2.1.shtml http://www.faqs.org/rfcs/rfc793.html
-         * 
+         *
          * The TCP RFC allows the open side to continue sending data. In most (all?)
          * implementations, the closed side will respond with a RST. For this reason, it takes two
          * writes to cause an IOException with TCP sockets. (or more, if there is latency)
-         * 
+         *
          * However, it is expected that the write give an IOException as soon as possible - which
          * means it is OK for our socket implementation to give an IOException on the first write.
          */
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/FinalizeTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/FinalizeTest.java
index 03eab2f..020a1dd 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/FinalizeTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/FinalizeTest.java
@@ -44,10 +44,10 @@ import com.kohlschutter.util.ExceptionUtil;
 /**
  * This tests the issue reported in
  * <a href="https://github.com/kohlschutter/junixsocket/pull/29">issue 29</a>.
- * 
+ *
  * We need to ensure that the native file descriptor is closed whenever our socket implementation is
  * garbage collected, even when {@link AFSocket#close()} is not called.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @CommandAvailabilityRequirement(commands = {"lsof"})
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/FinalizeTestClient.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/FinalizeTestClient.java
index 19673a5..10db902 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/FinalizeTestClient.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/FinalizeTestClient.java
@@ -25,9 +25,9 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * A potentially file descriptor-leaking client.
- * 
+ *
  * See <a href="https://github.com/kohlschutter/junixsocket/pull/29">issue 29</a> for details.
- * 
+ *
  * @see FinalizeTest
  * @author Christian Kohlschütter
  */
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/PipeTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/PipeTest.java
index 8a7b6e5..e88557a 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/PipeTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/PipeTest.java
@@ -38,7 +38,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * Tests the behavior of {@link AFPipe}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @SuppressFBWarnings("THROWS_METHOD_THROWS_CLAUSE_BASIC_EXCEPTION")
@@ -47,7 +47,7 @@ public final class PipeTest {
 
   /**
    * Tests sequential writing/reading.
-   * 
+   *
    * @throws IOException on error.
    */
   @Test
@@ -78,7 +78,7 @@ public final class PipeTest {
 
   /**
    * Tests concurrent writing/reading from the pipe.
-   * 
+   *
    * @throws IOException on error.
    * @throws InterruptedException on error.
    * @throws ExecutionException on error.
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/ReadWriteTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/ReadWriteTest.java
index f18a685..db2b9fd 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/ReadWriteTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/ReadWriteTest.java
@@ -36,7 +36,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 /**
  * Reads and writes data either using byte arrays or byte-for-byte (which may be implemented
  * differently).
- * 
+ *
  * @author Christian Kohlschütter
  */
 @SuppressFBWarnings({
@@ -90,7 +90,7 @@ public abstract class ReadWriteTest<A extends SocketAddress> extends SocketTestB
   }
 
   private final class ByteArrayWritingServerThread extends ServerThread {
-    public ByteArrayWritingServerThread() throws IOException {
+    public ByteArrayWritingServerThread() throws IOException, InterruptedException {
       super();
     }
 
@@ -110,7 +110,7 @@ public abstract class ReadWriteTest<A extends SocketAddress> extends SocketTestB
   }
 
   private final class ByteForByteWritingServerThread extends ServerThread {
-    public ByteForByteWritingServerThread() throws IOException {
+    public ByteForByteWritingServerThread() throws IOException, InterruptedException {
       super();
     }
 
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/SelectorTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/SelectorTest.java
index 9e67e4a..9ab760e 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/SelectorTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/SelectorTest.java
@@ -175,11 +175,11 @@ public abstract class SelectorTest<A extends SocketAddress> extends SocketTestBa
   /**
    * Tests a non-blocking server setup where a client connects, sends "Hello" to the server and then
    * disconnects after the server has received the message.
-   * 
+   *
    * In the selection loop, after the client has disconnected, the server should see that the
    * corresponding {@link SelectionKey} is "readable" (even if that means the connection was
    * closed).
-   * 
+   *
    * @throws Exception on error.
    */
   @Test
@@ -193,7 +193,7 @@ public abstract class SelectorTest<A extends SocketAddress> extends SocketTestBa
    *
    * Unlike {@link #testConnectionCloseEventualClientDisconnect()}, this may uncover additional
    * faults, such as an unexpected exception when trying to read the socket name.
-   * 
+   *
    * @throws Exception on error.
    */
   @Test
@@ -204,11 +204,11 @@ public abstract class SelectorTest<A extends SocketAddress> extends SocketTestBa
   /**
    * Tests a non-blocking server setup where a client connects, sends "Hello" to the server and then
    * disconnects after the server has received the message.
-   * 
+   *
    * In the selection loop, after the client has disconnected, the server should see that the
    * corresponding {@link SelectionKey} is "readable" (even if that means the connection was
    * closed).
-   * 
+   *
    * @throws Exception on error.
    */
   @Test
@@ -222,7 +222,7 @@ public abstract class SelectorTest<A extends SocketAddress> extends SocketTestBa
    *
    * Unlike {@link #testConnectionCloseEventualClientDisconnect()}, this may uncover additional
    * faults, such as an unexpected exception when trying to read the socket name.
-   * 
+   *
    * @throws Exception on error.
    */
   @Test
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/SelftestDiagnosticsHelper.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/SelftestDiagnosticsHelper.java
index bc0544e..836cb2c 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/SelftestDiagnosticsHelper.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/SelftestDiagnosticsHelper.java
@@ -21,7 +21,7 @@ import java.io.File;
 
 /**
  * Some bridging code that allows junixsocket-selftest to do some in-depth diagnostics.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class SelftestDiagnosticsHelper {
@@ -30,7 +30,7 @@ public final class SelftestDiagnosticsHelper {
 
   /**
    * Returns the error that prevented the native library from loading, or {@code null}.
-   * 
+   *
    * @return The error, or {@code null}.
    */
   public static Throwable initError() {
@@ -39,7 +39,7 @@ public final class SelftestDiagnosticsHelper {
 
   /**
    * Returns the temporary directory used for storing the native library, or {@code null}.
-   * 
+   *
    * @return The directory, or {@code null}.
    */
   public static File tempDir() {
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/SelftestProvider.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/SelftestProvider.java
index 0c84122..a708736 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/SelftestProvider.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/SelftestProvider.java
@@ -27,7 +27,7 @@ import java.util.Set;
 /**
  * Provides references to all "junixsocket-common" tests that should be included in
  * junixsocket-selftest.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @SuppressWarnings("PMD.CouplingBetweenObjects")
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/ServerSocketTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/ServerSocketTest.java
index 66ec187..049778e 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/ServerSocketTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/ServerSocketTest.java
@@ -34,7 +34,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * Tests some otherwise uncovered methods of {@link AFSocket}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @SuppressFBWarnings({
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/SoTimeoutTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/SoTimeoutTest.java
index 9f8b0b1..b4bd59c 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/SoTimeoutTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/SoTimeoutTest.java
@@ -39,7 +39,7 @@ import com.kohlschutter.testutil.AssertUtil;
 
 /**
  * Tests {@link Socket#setSoTimeout(int)} behavior.
- * 
+ *
  * @see <a href="http://code.google.com/p/junixsocket/issues/detail?id=14">Issue 14</a>
  */
 @SuppressFBWarnings({
@@ -52,7 +52,7 @@ public abstract class SoTimeoutTest<A extends SocketAddress> extends SocketTestB
   /**
    * Triggers a case where {@link Socket#setSoTimeout(int)} fails on some platforms: when the socket
    * is closed.
-   * 
+   *
    * @throws IOException on error.
    */
   @Test
@@ -82,7 +82,7 @@ public abstract class SoTimeoutTest<A extends SocketAddress> extends SocketTestB
 
   /**
    * Triggers a regular case where {@link Socket#setSoTimeout(int)} should work.
-   * 
+   *
    * @throws IOException on error.
    */
   @Test
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/SocketChannelTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/SocketChannelTest.java
index fb4dea1..822c10a 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/SocketChannelTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/SocketChannelTest.java
@@ -230,7 +230,7 @@ public abstract class SocketChannelTest<A extends SocketAddress> extends SocketT
   /**
    * Subclasses may override this to tell that there is a known issue with "First accept call did
    * not terminate".
-   * 
+   *
    * @return An explanation iff this should not cause a test failure but trigger "With issues".
    */
   protected String checkKnownBugFirstAcceptCallNotTerminated() {
@@ -239,9 +239,9 @@ public abstract class SocketChannelTest<A extends SocketAddress> extends SocketT
 
   /**
    * Returns the temporary address usable to binding on for a second bind.
-   * 
+   *
    * Depending on the socket domain, a wildcard address may be permittable or not for a second bind.
-   * 
+   *
    * @param originalAddress The original temporary address (e.g., a wildcard address).
    * @param ssc The socket that was bound to that address.
    * @return The local bound address, or the {@code originalAddress}.
@@ -256,7 +256,7 @@ public abstract class SocketChannelTest<A extends SocketAddress> extends SocketT
   /**
    * Override to declare that a certain socket domain permits double-binding an address,
    * particularly when the address is comparable to a wildcard address.
-   * 
+   *
    * @return {@code true} iff double-binding the same address is allowed.
    * @see #testDoubleBindAddressReusable()
    */
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/SocketTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/SocketTest.java
index 2044a0d..12fb61f 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/SocketTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/SocketTest.java
@@ -35,7 +35,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * Tests some otherwise uncovered methods of {@link AFSocket}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @SuppressFBWarnings({
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/SocketTestBase.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/SocketTestBase.java
index 3fbf715..7e4b1af 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/SocketTestBase.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/SocketTestBase.java
@@ -48,17 +48,17 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * Some base functionality for socket tests.
- * 
+ *
  * This class provides access to the {@link AddressSpecifics} methods for the socket implementation
  * under test. It is essential to use these wrapper methods in tests instead of directly calling the
  * {@link AFSocket} etc. methods: Some socket implementations (and sometimes only in certain
  * kernel/environment configurations) may expose unexpected behavior that is otherwise hard to
  * catch.
- * 
+ *
  * This is especially relevant when connecting/binding sockets (see
  * {@link #connectSocket(Socket, SocketAddress)}, #bindServerSocket(ServerSocket, SocketAddress)},
  * etc.)
- * 
+ *
  * @author Christian Kohlschuetter
  */
 @SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod")
@@ -145,9 +145,9 @@ public abstract class SocketTestBase<A extends SocketAddress> { // NOTE: needs t
   /**
    * Checks if an optional connection check via {@link AFSocket#checkConnectionClosed()}, is to be
    * run upon {@link AFServerSocket#accept()}.
-   * 
+   *
    * Override to enable.
-   * 
+   *
    * @return {@code true} if enabled; default is {@code false} = disabled.
    */
   protected boolean shouldDoConnectionCheckUponAccept() {
@@ -164,14 +164,16 @@ public abstract class SocketTestBase<A extends SocketAddress> { // NOTE: needs t
     private volatile Error error = null;
     private final AtomicBoolean loop = new AtomicBoolean(true);
     private final Semaphore sema = new Semaphore(1);
+    private final Semaphore readySema = new Semaphore(0);
 
     @SuppressFBWarnings("SC_START_IN_CTOR")
-    protected ServerThread() throws IOException {
+    protected ServerThread() throws IOException, InterruptedException {
       super();
       serverSocket = startServer(); // NOPMD
       setDaemon(true);
 
       start();
+      readySema.acquire();
     }
 
     protected ServerSocket startServer() throws IOException {
@@ -186,7 +188,7 @@ public abstract class SocketTestBase<A extends SocketAddress> { // NOTE: needs t
 
     /**
      * Stops the server.
-     * 
+     *
      * @throws IOException on error.
      */
     public void shutdown() throws IOException {
@@ -199,11 +201,11 @@ public abstract class SocketTestBase<A extends SocketAddress> { // NOTE: needs t
 
     /**
      * Callback used to handle a connection call.
-     * 
+     *
      * After returning from this call, the socket is closed.
-     * 
+     *
      * Use {@link #stopAcceptingConnections()} to stop accepting new calls.
-     * 
+     *
      * @param sock The socket to handle.
      * @throws IOException upon error.
      */
@@ -212,9 +214,9 @@ public abstract class SocketTestBase<A extends SocketAddress> { // NOTE: needs t
     /**
      * Called from within {@link #handleConnection(Socket)} to tell the server to no longer accept
      * new calls and to terminate the server thread.
-     * 
+     *
      * Note that this will lead to existing client connections to be closed.
-     * 
+     *
      * If you want to deny new connections but finish your work on the client side (in another
      * thread), then please use semaphores etc. to ensure reaching a safe state before calling this
      * method.
@@ -229,7 +231,7 @@ public abstract class SocketTestBase<A extends SocketAddress> { // NOTE: needs t
 
     /**
      * Returns the server socket.
-     * 
+     *
      * @return the server socket.
      */
     @SuppressFBWarnings("EI_EXPOSE_REP")
@@ -239,7 +241,7 @@ public abstract class SocketTestBase<A extends SocketAddress> { // NOTE: needs t
 
     /**
      * Returns the server's address to connect to.
-     * 
+     *
      * @return the address.
      */
     public SocketAddress getServerAddress() {
@@ -248,7 +250,7 @@ public abstract class SocketTestBase<A extends SocketAddress> { // NOTE: needs t
 
     /**
      * Called upon receiving an exception that may be handled specifically.
-     * 
+     *
      * @param e The exception
      * @return {@link ExceptionHandlingDecision#RAISE} if we should handle the exception somehow,
      *         {@link ExceptionHandlingDecision#IGNORE} if we should pretend the exception never
@@ -299,6 +301,7 @@ public abstract class SocketTestBase<A extends SocketAddress> { // NOTE: needs t
     public final void run() {
       try {
         loop.set(true);
+        readySema.release();
         onServerReady();
         while (loop.get()) {
           acceptAndHandleConnection();
@@ -323,9 +326,9 @@ public abstract class SocketTestBase<A extends SocketAddress> { // NOTE: needs t
 
     /**
      * Checks if there were any exceptions thrown during the lifetime of this ServerThread.
-     * 
+     *
      * NOTE: This call blocks until the Thread actually terminates.
-     * 
+     *
      * @throws Exception upon error.
      */
     public void checkException() throws Exception {
@@ -343,7 +346,7 @@ public abstract class SocketTestBase<A extends SocketAddress> { // NOTE: needs t
   }
 
   protected abstract class AFUNIXServerThread extends ServerThread {
-    protected AFUNIXServerThread() throws IOException {
+    protected AFUNIXServerThread() throws IOException, InterruptedException {
       super();
     }
 
@@ -357,7 +360,7 @@ public abstract class SocketTestBase<A extends SocketAddress> { // NOTE: needs t
 
   /**
    * Sleeps for the given amount of milliseconds.
-   * 
+   *
    * @param ms The duration in milliseconds.
    * @throws InterruptedIOException when interrupted.
    */
@@ -463,7 +466,7 @@ public abstract class SocketTestBase<A extends SocketAddress> { // NOTE: needs t
    * Returns the Linux kernel's major and minor version as an integer array (i.e., {@code 5.10.2 ->
    * int[]{5,10}}), or {@code null} if the running system isn't Linux or the version could not be
    * determined.
-   * 
+   *
    * @return The running Linux kernels' major and minor version as an integer array, or
    *         {@code null}.
    */
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/StandardSocketOptionsTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/StandardSocketOptionsTest.java
index 4ed2fc7..bd97bae 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/StandardSocketOptionsTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/StandardSocketOptionsTest.java
@@ -47,7 +47,7 @@ import com.kohlschutter.testutil.SoftAssertions;
 
 /**
  * Tests the {@code Socket#getOption(SocketOption)} API available since Java 9.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @SuppressFBWarnings({
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/StdinSocketApp.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/StdinSocketApp.java
index 060e258..85cb7f9 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/StdinSocketApp.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/StdinSocketApp.java
@@ -26,7 +26,7 @@ import java.nio.charset.StandardCharsets;
 /**
  * This test app responds with "Hello world" over a {@link Socket} that was passed from another
  * process via standard input.
- * 
+ *
  * @author Christian Kohlschütter
  * @see org.newsclub.net.unix.domain.FileDescriptorCastTest#testForkedVMRedirectStdin()
  */
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/ThroughputTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/ThroughputTest.java
index 386068f..8a0ff67 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/ThroughputTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/ThroughputTest.java
@@ -55,6 +55,7 @@ import java.util.concurrent.atomic.AtomicLong;
 import org.junit.jupiter.api.MethodOrderer;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestMethodOrder;
+import org.junit.platform.commons.JUnitException;
 
 import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 import com.kohlschutter.util.SystemPropertyUtil;
@@ -301,123 +302,147 @@ public abstract class ThroughputTest<A extends SocketAddress> extends SocketTest
   @Test
   @SuppressWarnings("PMD.CognitiveComplexity")
   public void testDatagramPacket() throws Exception {
-    assertTimeoutPreemptively(Duration.ofSeconds(NUM_SECONDS + 5), () -> {
-      SocketAddress dsAddr = newTempAddressForDatagram();
-      SocketAddress dcAddr = newTempAddressForDatagram();
+    try {
+      assertTimeoutPreemptively(Duration.ofSeconds(NUM_SECONDS + 5), () -> {
+        SocketAddress dsAddr = newTempAddressForDatagram();
+        SocketAddress dcAddr = newTempAddressForDatagram();
 
-      try (DatagramSocket ds = newDatagramSocket(); DatagramSocket dc = newDatagramSocket()) {
-        if (!ds.isBound()) {
-          ds.bind(dsAddr);
-        }
-        if (!dc.isBound()) {
-          dc.bind(dcAddr);
-        }
+        try (DatagramSocket ds = newDatagramSocket(); DatagramSocket dc = newDatagramSocket()) {
+          if (!ds.isBound()) {
+            ds.bind(dsAddr);
+          }
+          if (!dc.isBound()) {
+            dc.bind(dcAddr);
+          }
 
-        dsAddr = ds.getLocalSocketAddress();
-        dcAddr = dc.getLocalSocketAddress();
+          dsAddr = ds.getLocalSocketAddress();
+          dcAddr = dc.getLocalSocketAddress();
 
-        assertNotEquals(dsAddr, dcAddr);
+          assertNotEquals(dsAddr, dcAddr);
 
-        dc.connect(dsAddr);
+          dc.connect(dsAddr);
 
-        AtomicBoolean keepRunning = new AtomicBoolean(true);
-        Executors.newSingleThreadScheduledExecutor().schedule(() -> {
-          keepRunning.set(false);
-        }, NUM_MILLISECONDS, TimeUnit.MILLISECONDS);
+          AtomicBoolean keepRunning = new AtomicBoolean(true);
+          Executors.newSingleThreadScheduledExecutor().schedule(() -> {
+            keepRunning.set(false);
+          }, NUM_MILLISECONDS, TimeUnit.MILLISECONDS);
 
-        AtomicLong readTotal = new AtomicLong();
-        long sentTotal = 0;
+          AtomicLong readTotal = new AtomicLong();
+          long sentTotal = 0;
 
-        new Thread() {
-          final DatagramPacket dp = new DatagramPacket(new byte[PAYLOAD_SIZE], PAYLOAD_SIZE);
+          new Thread() {
+            final DatagramPacket dp = new DatagramPacket(new byte[PAYLOAD_SIZE], PAYLOAD_SIZE);
 
-          @Override
-          public void run() {
-            try {
-              while (!Thread.interrupted() && !ds.isClosed()) {
-                try {
-                  ds.receive(dp);
-                } catch (SocketTimeoutException e) {
-                  continue;
+            @Override
+            public void run() {
+              try {
+                while (!Thread.interrupted() && !ds.isClosed()) {
+                  try {
+                    ds.receive(dp);
+                  } catch (SocketTimeoutException e) {
+                    continue;
+                  }
+                  int read = dp.getLength();
+                  if (read != PAYLOAD_SIZE && read != 0) {
+                    throw new IOException("Unexpected response length: " + read);
+                  }
+                  readTotal.addAndGet(dp.getLength());
                 }
-                int read = dp.getLength();
-                if (read != PAYLOAD_SIZE && read != 0) {
-                  throw new IOException("Unexpected response length: " + read);
+              } catch (SocketException e) {
+                if (keepRunning.get()) {
+                  e.printStackTrace();
                 }
-                readTotal.addAndGet(dp.getLength());
-              }
-            } catch (SocketException e) {
-              if (keepRunning.get()) {
+              } catch (IOException e) {
                 e.printStackTrace();
               }
-            } catch (IOException e) {
-              e.printStackTrace();
             }
-          }
-        }.start();
+          }.start();
 
-        long time = System.currentTimeMillis();
-
-        DatagramPacket dp = new DatagramPacket(new byte[PAYLOAD_SIZE], PAYLOAD_SIZE);
-        byte[] data = dp.getData();
-        for (int i = 0; i < data.length; i++) {
-          data[i] = (byte) i;
-        }
+          long time = System.currentTimeMillis();
 
-        while (keepRunning.get()) {
-          try {
-            dc.send(dp);
-          } catch (PortUnreachableException e) {
-            e.addSuppressed(new Exception(dp.getSocketAddress().toString()));
-            throw e;
+          DatagramPacket dp = new DatagramPacket(new byte[PAYLOAD_SIZE], PAYLOAD_SIZE);
+          byte[] data = dp.getData();
+          for (int i = 0; i < data.length; i++) {
+            data[i] = (byte) i;
           }
-          sentTotal += PAYLOAD_SIZE;
-        }
-        time = System.currentTimeMillis() - time;
-        keepRunning.set(false);
-        ds.close(); // terminate server
 
-        long readTotal0 = readTotal.get();
+          while (keepRunning.get()) {
+            try {
+              dc.send(dp);
+            } catch (PortUnreachableException e) {
+              e.addSuppressed(new Exception(dp.getSocketAddress().toString()));
+              throw e;
+            }
+            sentTotal += PAYLOAD_SIZE;
+          }
+          time = System.currentTimeMillis() - time;
+          keepRunning.set(false);
+          ds.close(); // terminate server
 
-        reportResults(stbTestType() + " DatagramPacket", ((1000f * readTotal0 / time) / 1000f
-            / 1000f) + " MB/s for payload size " + PAYLOAD_SIZE + "; " + String.format(
-                Locale.ENGLISH, "%.1f%% packet loss", 100 * (1 - (readTotal0
-                    / (float) sentTotal))));
-      }
-    });
+          long readTotal0 = readTotal.get();
 
+          reportResults(stbTestType() + " DatagramPacket", ((1000f * readTotal0 / time) / 1000f
+              / 1000f) + " MB/s for payload size " + PAYLOAD_SIZE + "; " + String.format(
+                  Locale.ENGLISH, "%.1f%% packet loss", 100 * (1 - (readTotal0
+                      / (float) sentTotal))));
+        }
+      });
+    } catch (JUnitException e) {
+      // Ignore timeout failure (this is a throughput test only)
+      e.printStackTrace();
+    }
   }
 
   @Test
   @AFSocketCapabilityRequirement(AFSocketCapability.CAPABILITY_UNIX_DATAGRAMS)
   public void testDatagramChannel() throws Exception {
-    assertTimeoutPreemptively(Duration.ofSeconds(NUM_SECONDS + 5), () -> {
-      testDatagramChannel(false, true);
-    });
+    try {
+      assertTimeoutPreemptively(Duration.ofSeconds(NUM_SECONDS + 5), () -> {
+        testDatagramChannel(false, true);
+      });
+    } catch (JUnitException e) {
+      // Ignore timeout failure (this is a throughput test only)
+      e.printStackTrace();
+    }
   }
 
   @Test
   @AFSocketCapabilityRequirement(AFSocketCapability.CAPABILITY_UNIX_DATAGRAMS)
   public void testDatagramChannelDirect() throws Exception {
-    assertTimeoutPreemptively(Duration.ofSeconds(NUM_SECONDS + 5), () -> {
-      testDatagramChannel(true, true);
-    });
+    try {
+      assertTimeoutPreemptively(Duration.ofSeconds(NUM_SECONDS + 5), () -> {
+        testDatagramChannel(true, true);
+      });
+    } catch (JUnitException e) {
+      // Ignore timeout failure (this is a throughput test only)
+      e.printStackTrace();
+    }
   }
 
   @Test
   @AFSocketCapabilityRequirement(AFSocketCapability.CAPABILITY_UNIX_DATAGRAMS)
   public void testDatagramChannelNonBlocking() throws Exception {
-    assertTimeoutPreemptively(Duration.ofSeconds(NUM_SECONDS + 5), () -> {
-      testDatagramChannel(false, false);
-    });
+    try {
+      assertTimeoutPreemptively(Duration.ofSeconds(NUM_SECONDS + 5), () -> {
+        testDatagramChannel(false, false);
+      });
+    } catch (JUnitException e) {
+      // Ignore timeout failure (this is a throughput test only)
+      e.printStackTrace();
+    }
   }
 
   @Test
   @AFSocketCapabilityRequirement(AFSocketCapability.CAPABILITY_UNIX_DATAGRAMS)
   public void testDatagramChannelNonBlockingDirect() throws Exception {
-    assertTimeoutPreemptively(Duration.ofSeconds(NUM_SECONDS + 5), () -> {
-      testDatagramChannel(true, false);
-    });
+    try {
+      assertTimeoutPreemptively(Duration.ofSeconds(NUM_SECONDS + 5), () -> {
+        testDatagramChannel(true, false);
+      });
+    } catch (JUnitException e) {
+      // Ignore timeout failure (this is a throughput test only)
+      e.printStackTrace();
+    }
   }
 
   private void testDatagramChannel(boolean direct, boolean blocking) throws Exception {
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/FileDescriptorCastTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/FileDescriptorCastTest.java
index 0647d95..f684b0c 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/FileDescriptorCastTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/FileDescriptorCastTest.java
@@ -346,7 +346,7 @@ public class FileDescriptorCastTest {
   /**
    * Passes a socket to a newly created Java process as "standard input". The new process sends back
    * "Hello world" over that socket.
-   * 
+   *
    * @throws Exception on failure.
    * @see StdinSocketApp
    */
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/FileDescriptorsTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/FileDescriptorsTest.java
index bc548aa..3bd4150 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/FileDescriptorsTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/FileDescriptorsTest.java
@@ -54,7 +54,7 @@ import com.kohlschutter.util.IOUtil;
 
 /**
  * Tests sending and receiving file descriptors.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @AFSocketCapabilityRequirement({
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/PeerCredentialsTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/PeerCredentialsTest.java
index 8f7dc4d..3bd8eff 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/PeerCredentialsTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/PeerCredentialsTest.java
@@ -45,7 +45,7 @@ import com.kohlschutter.util.ProcessUtil;
 
 /**
  * Verifies that peer credentials are properly set.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @AFSocketCapabilityRequirement({
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/SocketTest.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/SocketTest.java
index 4405a8f..ef68247 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/SocketTest.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/domain/SocketTest.java
@@ -34,7 +34,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * Tests some otherwise uncovered methods of {@link AFUNIXSocket}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @AFSocketCapabilityRequirement(AFSocketCapability.CAPABILITY_UNIX_DOMAIN)
diff --git a/junixsocket-common/src/test/java/org/newsclub/net/unix/java/JavaInetStackRequirement.java b/junixsocket-common/src/test/java/org/newsclub/net/unix/java/JavaInetStackRequirement.java
index d024858..813d7a8 100644
--- a/junixsocket-common/src/test/java/org/newsclub/net/unix/java/JavaInetStackRequirement.java
+++ b/junixsocket-common/src/test/java/org/newsclub/net/unix/java/JavaInetStackRequirement.java
@@ -26,10 +26,10 @@ import org.junit.jupiter.api.extension.ExtendWith;
 
 /**
  * Flags a test that requires the Java Internet stack to function as expected.
- * 
+ *
  * This currently checks if we can bind to an unspecified (0) port on the loopback device, which
  * unfortunately may not always succeed. In the failure case, the annotated tests will be skipped.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @Target({ElementType.TYPE, ElementType.METHOD})
diff --git a/junixsocket-common/src/test/java8/org/newsclub/net/unix/FinalizeTest.java b/junixsocket-common/src/test/java8/org/newsclub/net/unix/FinalizeTest.java
index 7fdfabd..3d67dc0 100644
--- a/junixsocket-common/src/test/java8/org/newsclub/net/unix/FinalizeTest.java
+++ b/junixsocket-common/src/test/java8/org/newsclub/net/unix/FinalizeTest.java
@@ -1,7 +1,7 @@
 /*
  * junixsocket
  *
- * Copyright 2009-2021 Christian Kohlschütter
+ * Copyright 2009-2022 Christian Kohlschütter
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@ import com.kohlschutter.testutil.AvailabilityRequirement;
 /**
  * Not supported on Java 8 yet, but you can manually verify that it works by running the following
  * commands from three different shells:
- * 
+ *
  * <ol>
  * <li>(shell 1) {@code nc -l -U /tmp/testsocket}</li>
  * <li>(shell 2) {@code java -Dtest.junixsocket.socket=/tmp/testsocket
@@ -37,10 +37,10 @@ import com.kohlschutter.testutil.AvailabilityRequirement;
  * <li>(shell 1) type some text, followed by enter</li>
  * <li>(shell 3) {@code lsof -U -a -p $(jps | grep FinalizeTestClient | cut -f 1 -d' ') | wc -l}
  * </ol>
- * 
+ *
  * The number printed in shell 3 after the second {@code lsof} commands should be one less than the
  * one of the first {@code lsof} command.
- * 
+ *
  * See <a href="https://github.com/kohlschutter/junixsocket/pull/29">issue 29</a> for details.
  */
 public abstract class FinalizeTest<A extends SocketAddress> extends SocketTestBase<A> {
diff --git a/junixsocket-common/src/test/java8/org/newsclub/net/unix/StandardSocketOptionsTest.java b/junixsocket-common/src/test/java8/org/newsclub/net/unix/StandardSocketOptionsTest.java
index d0e9448..5eba739 100644
--- a/junixsocket-common/src/test/java8/org/newsclub/net/unix/StandardSocketOptionsTest.java
+++ b/junixsocket-common/src/test/java8/org/newsclub/net/unix/StandardSocketOptionsTest.java
@@ -1,3 +1,20 @@
+/*
+ * junixsocket
+ *
+ * Copyright 2009-2022 Christian Kohlschütter
+ *
+ * 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 org.newsclub.net.unix;
 
 import java.net.SocketAddress;
@@ -9,10 +26,10 @@ import com.kohlschutter.testutil.AvailabilityRequirement;
 
 /**
  * Tests the {@code Socket#getOption(SocketOption)} API available since Java 9.
- * 
+ *
  * This class (in src/test/java8) is a stub that overrides this type so we can compile for Java 8
  * and, at the same time, acknowledge the absence of the test programmatically in jUnit.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public abstract class StandardSocketOptionsTest<A extends SocketAddress> extends SocketTestBase<A> {
diff --git a/junixsocket-core/pom.xml b/junixsocket-core/pom.xml
index e588428..831d583 100644
--- a/junixsocket-core/pom.xml
+++ b/junixsocket-core/pom.xml
@@ -7,7 +7,7 @@
     <parent>
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-core</name>
diff --git a/junixsocket-demo/pom.xml b/junixsocket-demo/pom.xml
index 5f2b506..640e859 100644
--- a/junixsocket-demo/pom.xml
+++ b/junixsocket-demo/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-demo</name>
@@ -14,9 +14,7 @@
         <kohlschutter.project.base.directory>${project.parent.basedir}</kohlschutter.project.base.directory>
         <kohlschutter.multirelease.java8.release>8</kohlschutter.multirelease.java8.release>
     </properties>
-
     <description>Some example code to demo junixsocket's features</description>
-
     <dependencies>
         <!-- <dependency> <groupId>com.kohlschutter.junixsocket</groupId> <artifactId>junixsocket-native-common</artifactId>
       <version>${project.version}</version> </dependency> -->
@@ -47,22 +45,9 @@
             <version>${project.version}</version>
         </dependency>
         <dependency>
-            <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-            <version>8.0.30</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>com.google.protobuf</groupId>
-                    <artifactId>protobuf-java</artifactId>
-                    <!-- CVE-2022-3171: 3.19.4 -->
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <!-- CVE-2022-3171: replace 3.19.4 (dependency of mysql-connector-java) -->
-            <groupId>com.google.protobuf</groupId>
-            <artifactId>protobuf-java</artifactId>
-            <version>3.19.6</version>
+            <groupId>com.mysql</groupId>
+            <artifactId>mysql-connector-j</artifactId>
+            <version>8.0.32</version>
         </dependency>
         <dependency>
             <!-- NOTE: Due to this dependency, maven-project-info-reports-plugin
@@ -71,7 +56,7 @@
             <!-- https://issues.apache.org/jira/browse/MPIR-374 -->
             <groupId>org.postgresql</groupId>
             <artifactId>postgresql</artifactId>
-            <version>42.5.0</version>
+            <version>42.5.3</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -93,7 +78,6 @@
             <version>4.10.0</version>
         </dependency>
     </dependencies>
-
     <build>
         <plugins>
             <plugin>
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/mysql/demo/AFUNIXDatabaseSocketFactoryDemo.java b/junixsocket-demo/src/main/java/org/newsclub/net/mysql/demo/AFUNIXDatabaseSocketFactoryDemo.java
index a91d974..68a5b7e 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/mysql/demo/AFUNIXDatabaseSocketFactoryDemo.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/mysql/demo/AFUNIXDatabaseSocketFactoryDemo.java
@@ -31,7 +31,7 @@ import org.newsclub.net.unix.demo.DemoHelper;
 
 /**
  * Demonstrates how to connect to a local MySQL server.
- * 
+ *
  * @author Christian Kohlschuetter
  */
 public class AFUNIXDatabaseSocketFactoryDemo {
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/DemoHelper.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/DemoHelper.java
index 50ca192..00c7d30 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/DemoHelper.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/DemoHelper.java
@@ -45,7 +45,7 @@ public final class DemoHelper {
   /**
    * Adds a key-value pair to a Properties instance. Takes values from a given system property and
    * overrides the default value with it.
-   * 
+   *
    * @param props The Properties instance to write to.
    * @param key The name of the property.
    * @param defaultValue The default value (for demo purposes)
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/SimpleTestClient.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/SimpleTestClient.java
index 6945775..2502e87 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/SimpleTestClient.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/SimpleTestClient.java
@@ -30,12 +30,12 @@ import org.newsclub.net.unix.AFUNIXSocketAddress;
 
 /**
  * A simple demo client.
- * 
+ *
  * Reads a server greeting string, then sends a "Hello Server" string as a response.
- * 
+ *
  * Finally, reads integers (via {@link DataInputStream}), then sends twice the sent value each,
  * unless a "-123" magic number is read to indicate the end of the conversation.
- * 
+ *
  * @author Christian Kohlschütter
  * @see SimpleTestServer
  */
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/SimpleTestServer.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/SimpleTestServer.java
index 9d80664..dc32ad8 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/SimpleTestServer.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/SimpleTestServer.java
@@ -31,13 +31,13 @@ import org.newsclub.net.unix.SocketClosedException;
 
 /**
  * A simple demo server.
- * 
+ *
  * Sends a hello message (as a string), then reads back a response string.
- * 
+ *
  * Finally, sends integers (via {@link DataOutputStream}) from 1 to 5, expects an integer response
  * of twice the sent value each, then sends a "-123" magic number to indicate the end of the
  * conversation.
- * 
+ *
  * @author Christian Kohlschütter
  * @see SimpleTestClient
  */
@@ -56,18 +56,18 @@ public final class SimpleTestServer {
     try (AFUNIXServerSocket server = AFUNIXServerSocket.newInstance()) {
       /*
        * Uncomment the code below to change the bind behavior:
-       * 
+       *
        * By default ("reuseAddress" is true), attempting to bind while another server is running on
        * the same address will cause the first server to terminate, and the new server will take
        * over the address. Depending on the operating system, this may involve connecting to the
        * first server in order to "wake up" the accept call.
-       * 
+       *
        * In this demo code, we use AFSocket.getConnectionStatus to see if the accepted connection is
        * alive by sending
-       * 
+       *
        * When "reuseAddress" is false, attempting to bind while another server is running won't
        * disrupt the first connection. The second bind will throw a SocketException instead.
-       * 
+       *
        * NOTE: "reuseAddress=true" may not yet be supported on certain operating systems, such as
        * IBM i and z/OS. On these platforms, the behavior is as if "reuseAddress=false". Please
        * reach out by filing an issue on https://github.com/kohlschutter/junixsocket/issues if this
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/client/DemoClient.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/client/DemoClient.java
index 7faf9b5..e9d8e29 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/client/DemoClient.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/client/DemoClient.java
@@ -25,7 +25,7 @@ import org.newsclub.net.unix.demo.DemoHelper;
 
 /**
  * A demo program to configure and run several {@link AFSocket} client demos from the command line.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class DemoClient {
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/client/DemoClientBase.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/client/DemoClientBase.java
index 8864068..661e345 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/client/DemoClientBase.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/client/DemoClientBase.java
@@ -26,7 +26,7 @@ import org.newsclub.net.unix.AFUNIXSocket;
 
 /**
  * An {@link AFUNIXSocket} client that's just good for demo purposes.
- * 
+ *
  * @author Christian Kohlschütter
  */
 abstract class DemoClientBase {
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/jdbc/PostgresDemo.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/jdbc/PostgresDemo.java
index da854ab..f889e90 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/jdbc/PostgresDemo.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/jdbc/PostgresDemo.java
@@ -32,7 +32,7 @@ import org.newsclub.net.unix.demo.DemoHelper;
 
 /**
  * Demonstrates how to connect to a local PostgreSQL server via unix sockets.
- * 
+ *
  * @author Christian Kohlschuetter
  * @see AFUNIXSocketFactory
  */
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/nanohttpd/NanoHttpdServerDemo.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/nanohttpd/NanoHttpdServerDemo.java
index 133953c..c4bb840 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/nanohttpd/NanoHttpdServerDemo.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/nanohttpd/NanoHttpdServerDemo.java
@@ -32,9 +32,9 @@ import fi.iki.elonen.NanoHTTPD;
 
 /**
  * Creates a {@link NanoHTTPD} server, bound to {@code /tmp/junixsocket-http-server.sock}.
- * 
+ *
  * Http requests on that socket should return "Hello world from &lt;hostname&gt;".
- * 
+ *
  * @author Christian Kohlschütter
  * @see OkHttpClientDemo
  */
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/okhttp/OkHttpClientDemo.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/okhttp/OkHttpClientDemo.java
index 4d4086b..8f20d0b 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/okhttp/OkHttpClientDemo.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/okhttp/OkHttpClientDemo.java
@@ -38,9 +38,9 @@ import okhttp3.ResponseBody;
 /**
  * Connects to {@code /tmp/junixsocket-http-server.sock} and performs an http request over that
  * socket, using the <a href="https://square.github.io/okhttp/">OkHttp</a> HTTP client library.
- * 
+ *
  * If that socket is bound by {@link NanoHttpdServerDemo}, the expected output is "Hello world".
- * 
+ *
  * @author Christian Kohlschütter
  * @see NanoHttpdServerDemo
  */
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/okhttp/OkHttpClientTIPCDemo.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/okhttp/OkHttpClientTIPCDemo.java
index 1e1f9d8..2d7dd1b 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/okhttp/OkHttpClientTIPCDemo.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/okhttp/OkHttpClientTIPCDemo.java
@@ -39,10 +39,10 @@ import okhttp3.ResponseBody;
 /**
  * Connects to TIPC service 8080.1 and performs an HTTP request over that socket, using the
  * <a href="https://square.github.io/okhttp/">OkHttp</a> HTTP client library.
- * 
+ *
  * If that socket is bound by {@link NanoHttpdServerDemo}, the expected output is "Hello world from
  * &lt;hostname&gt;" (start {@link NanoHttpdServerDemo} with {@code --url tipc://8080.1}.
- * 
+ *
  * @author Christian Kohlschütter
  * @see NanoHttpdServerDemo
  */
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/HelloWorldImpl.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/HelloWorldImpl.java
index 6e3d12d..b12a15b 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/HelloWorldImpl.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/HelloWorldImpl.java
@@ -29,7 +29,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * The implementation of the very simple {@link HelloWorld} service.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class HelloWorldImpl implements HelloWorld {
@@ -37,7 +37,7 @@ public class HelloWorldImpl implements HelloWorld {
 
   /**
    * Creates a new {@link HelloWorld} implementation.
-   * 
+   *
    * @param naming The naming instance to use.
    */
   @SuppressFBWarnings("EI_EXPOSE_REP")
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/SimpleRMIClient.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/SimpleRMIClient.java
index aef5a3a..7ed0296 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/SimpleRMIClient.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/SimpleRMIClient.java
@@ -28,7 +28,7 @@ import org.newsclub.net.unix.rmi.RemotePeerInfo;
 /**
  * A simple RMI client. Locates the RMI registry via AF_UNIX sockets and calls
  * {@link HelloWorld#hello()}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class SimpleRMIClient {
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/SimpleRMIClientActingAsServer.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/SimpleRMIClientActingAsServer.java
index 0828564..190ee65 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/SimpleRMIClientActingAsServer.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/SimpleRMIClientActingAsServer.java
@@ -30,7 +30,7 @@ import org.newsclub.net.unix.rmi.RemotePeerInfo;
 /**
  * A simple RMI client. Locates the RMI registry via AF_UNIX sockets and calls
  * {@link HelloWorld#hello()}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class SimpleRMIClientActingAsServer {
@@ -59,14 +59,14 @@ public final class SimpleRMIClientActingAsServer {
 
     /**
      * Uncommenting the line below keeps this instance running.
-     * 
+     *
      * Try it and run SimpleRMIClient to see the difference.
      */
     naming.unexportAndUnbind("world", world);
 
     /**
      * Also try to remotely shut down the registry.
-     * 
+     *
      * This will not succeed if the server set {@code naming.setRemoteShutdownAllowed(false)}. See
      * {@link SimpleRMIServer}
      */
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/SimpleRMIServer.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/SimpleRMIServer.java
index c7e73c4..95e25c4 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/SimpleRMIServer.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/SimpleRMIServer.java
@@ -26,7 +26,7 @@ import org.newsclub.net.unix.rmi.AFUNIXNaming;
 /**
  * A very simple RMI server. Provides a registry and the implementation of the {@link HelloWorld}
  * service.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class SimpleRMIServer {
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/WorldImpl.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/WorldImpl.java
index 1c100b1..664a4ee 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/WorldImpl.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/WorldImpl.java
@@ -23,7 +23,7 @@ import org.newsclub.net.unix.demo.rmi.services.World;
 
 /**
  * The implementation of the very simple {@link World} service.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class WorldImpl implements World {
@@ -31,7 +31,7 @@ public class WorldImpl implements World {
 
   /**
    * Creates a new {@link World} instance.
-   * 
+   *
    * @param text The text to return upon calling {@link #world()}.
    */
   public WorldImpl(String text) {
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/fd/StreamClient.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/fd/StreamClient.java
index 991def1..eab1c77 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/fd/StreamClient.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/fd/StreamClient.java
@@ -31,7 +31,7 @@ import org.newsclub.net.unix.rmi.RemoteFileInput;
 
 /**
  * Demonstrates how to read files via FileDescriptors that are exchanged via RMI.
- * 
+ *
  * @author Christian Kohlschütter
  * @see StreamServer
  */
@@ -42,7 +42,7 @@ public final class StreamClient {
 
   /**
    * {@link StreamClient} command-line tool.
-   * 
+   *
    * @param args Command-line arguments.
    * @throws IOException on error.
    * @throws NotBoundException if the server cannot be reached.
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/fd/StreamServer.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/fd/StreamServer.java
index b432a7c..6df8d18 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/fd/StreamServer.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/fd/StreamServer.java
@@ -24,14 +24,14 @@ import org.newsclub.net.unix.rmi.AFUNIXNaming;
 
 /**
  * Demonstrates how to read/write files via FileDescriptors that are exchanged via RMI.
- * 
+ *
  * This allows reading/writing from and to files that are otherwise not even accessible by the user.
  * For example, starting the {@link StreamServer} as root and the {@link StreamClient} as a
  * non-privileged user will allow the non-privileged user to read files only accessible to root.
- * 
+ *
  * NOTE: For obvious security reasons, running this server without modification is not advised for
  * anything other than demo purposes.
- * 
+ *
  * @author Christian Kohlschütter
  * @see StreamClient
  */
@@ -42,7 +42,7 @@ public final class StreamServer {
 
   /**
    * {@link StreamServer} command-line tool.
-   * 
+   *
    * @param args Command-line arguments.
    * @throws IOException on error.
    * @throws AlreadyBoundException if there was already a server running.
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/fd/StreamServiceImpl.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/fd/StreamServiceImpl.java
index 6ac3eeb..77e5bf6 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/fd/StreamServiceImpl.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/fd/StreamServiceImpl.java
@@ -35,7 +35,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * An implementation of {@link StreamService}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class StreamServiceImpl implements StreamService, Closeable {
@@ -43,7 +43,7 @@ public class StreamServiceImpl implements StreamService, Closeable {
 
   /**
    * Creates a new instance.
-   * 
+   *
    * @param socketFactory The socket factory to use.
    * @throws RemoteException on error.
    */
@@ -82,7 +82,7 @@ public class StreamServiceImpl implements StreamService, Closeable {
 
   /**
    * Checks if the given path may be accessed for reading.
-   * 
+   *
    * @param path The path to check.
    * @return {@code true} if permitted.
    */
@@ -92,7 +92,7 @@ public class StreamServiceImpl implements StreamService, Closeable {
 
   /**
    * Checks if the given path may be accessed for writing.
-   * 
+   *
    * @param path The path to check.
    * @return {@code true} if permitted.
    */
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/services/HelloWorld.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/services/HelloWorld.java
index bd004d2..b5989bd 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/services/HelloWorld.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/services/HelloWorld.java
@@ -22,13 +22,13 @@ import java.rmi.Remote;
 
 /**
  * A very simple "hello world" service.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public interface HelloWorld extends Remote {
   /**
    * Returns "Hello".
-   * 
+   *
    * @return "Hello"
    * @throws IOException if the operation fails.
    */
@@ -36,7 +36,7 @@ public interface HelloWorld extends Remote {
 
   /**
    * Returns "World" (or something else?).
-   * 
+   *
    * @return "World" (usually)
    * @throws IOException if the operation fails.
    */
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/services/StreamService.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/services/StreamService.java
index 5c56cf1..1b3d379 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/services/StreamService.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/services/StreamService.java
@@ -28,14 +28,14 @@ import org.newsclub.net.unix.rmi.RemoteFileOutput;
 
 /**
  * The {@link StreamServer}'s RMI service.
- * 
+ *
  * @author Christian Kohlschütter
  * @see StreamServer
  */
 public interface StreamService extends Remote {
   /**
    * Opens the given file for reading.
-   * 
+   *
    * @param path The file to open.
    * @return A remote instance for the file.
    * @throws IOException on error.
@@ -44,7 +44,7 @@ public interface StreamService extends Remote {
 
   /**
    * Opens the given file for writing.
-   * 
+   *
    * @param path The file to open.
    * @return A remote instance for the file.
    * @throws IOException on error.
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/services/World.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/services/World.java
index d8f341a..285bd56 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/services/World.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/rmi/services/World.java
@@ -22,14 +22,14 @@ import java.rmi.RemoteException;
 
 /**
  * A very simple "world" service.
- * 
+ *
  * @author Christian Kohlschütter
  * @see HelloWorld
  */
 public interface World extends Remote {
   /**
    * Returns "World" (or something else?).
-   * 
+   *
    * @return "World" (usually)
    * @throws RemoteException if the operation fails.
    */
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/ChargenServer.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/ChargenServer.java
index 40338db..e49e05b 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/ChargenServer.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/ChargenServer.java
@@ -28,7 +28,7 @@ import java.net.SocketException;
 /**
  * A multi-threaded unix socket server that implements a TCP-style character generator compliant
  * with RFC864.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class ChargenServer extends DemoServerBase {
@@ -38,7 +38,7 @@ public final class ChargenServer extends DemoServerBase {
 
   /**
    * Defines a TCP-style character generator compliant with RFC864.
-   * 
+   *
    * @see <a href="https://tools.ietf.org/html/rfc864">RFC864</a>
    */
   private interface Chargen {
@@ -83,9 +83,9 @@ public final class ChargenServer extends DemoServerBase {
 
   /**
    * A simple chargen implementation.
-   * 
+   *
    * Even though this looks straightforward, it's not the fastest implementation.
-   * 
+   *
    * @see FastChargen
    */
   private static final class SimpleChargen implements Chargen {
@@ -113,7 +113,7 @@ public final class ChargenServer extends DemoServerBase {
   /**
    * A fast chargen implementation, using a pre-built data buffer that is just large enough to
    * always send a full array of bytes matching the socket's send buffer capacity.
-   * 
+   *
    * @see SimpleChargen
    */
   private static final class FastChargen implements Chargen {
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/DemoServerBase.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/DemoServerBase.java
index c52f3d1..ba857f1 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/DemoServerBase.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/DemoServerBase.java
@@ -30,7 +30,7 @@ import org.newsclub.net.unix.server.SocketServer;
 
 /**
  * An {@link SocketServer} that's just good for demo purposes.
- * 
+ *
  * @author Christian Kohlschütter
  */
 abstract class DemoServerBase extends SocketServer<SocketAddress, Socket, ServerSocket> {
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/EchoServer.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/EchoServer.java
index aac916a..6429501 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/EchoServer.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/EchoServer.java
@@ -25,7 +25,7 @@ import java.net.SocketAddress;
 
 /**
  * A multi-threaded unix socket server that simply echoes all input, byte per byte.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class EchoServer extends DemoServerBase {
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/NullServer.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/NullServer.java
index ac600b8..5ec4bc3 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/NullServer.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/NullServer.java
@@ -25,7 +25,7 @@ import java.net.SocketAddress;
 /**
  * A multi-threaded unix socket server that simply reads all input, byte per byte, not doing
  * anything else with it.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class NullServer extends DemoServerBase {
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/SendFileHandleServer.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/SendFileHandleServer.java
index 281b525..e7b3fdf 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/SendFileHandleServer.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/SendFileHandleServer.java
@@ -30,7 +30,7 @@ import org.newsclub.net.unix.AFUNIXSocket;
 /**
  * A multi-threaded unix socket server that simply reads all input, byte per byte, not doing
  * anything else with it.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class SendFileHandleServer extends DemoServerBase {
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/SocketServerDemo.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/SocketServerDemo.java
index a23c742..0fba2b4 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/SocketServerDemo.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/SocketServerDemo.java
@@ -26,7 +26,7 @@ import org.newsclub.net.unix.server.SocketServer;
 
 /**
  * A demo program to configure and run several {@link SocketServer} demos from the command line.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class SocketServerDemo {
diff --git a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/ZeroServer.java b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/ZeroServer.java
index 752f4c5..7a8a268 100644
--- a/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/ZeroServer.java
+++ b/junixsocket-demo/src/main/java/org/newsclub/net/unix/demo/server/ZeroServer.java
@@ -25,7 +25,7 @@ import java.net.SocketAddress;
 /**
  * A multi-threaded unix socket server that simply writes null-bytes, and does not attempt to read
  * anything.
- * 
+ *
  * @author Christian Kohlschütter
  */
 // CPD-OFF
diff --git a/junixsocket-dist/pom.xml b/junixsocket-dist/pom.xml
index 941f993..6fa9ad0 100644
--- a/junixsocket-dist/pom.xml
+++ b/junixsocket-dist/pom.xml
@@ -8,7 +8,7 @@
     <parent>
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-dist</name>
@@ -66,7 +66,7 @@
                     <plugin>
                         <groupId>org.apache.maven.plugins</groupId>
                         <artifactId>maven-assembly-plugin</artifactId>
-                        <version>3.1.1</version>
+                        <version>3.4.2</version>
                         <executions>
                             <execution>
                                 <id>build-dist</id>
diff --git a/junixsocket-jetty/pom.xml b/junixsocket-jetty/pom.xml
index be05bc1..4236359 100644
--- a/junixsocket-jetty/pom.xml
+++ b/junixsocket-jetty/pom.xml
@@ -6,13 +6,13 @@
     <parent>
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-jetty</name>
     <properties>
         <kohlschutter.project.base.directory>${project.parent.basedir}</kohlschutter.project.base.directory>
-        <jetty.version>11.0.12</jetty.version>
+        <jetty.version>11.0.13</jetty.version>
     </properties>
 
     <description>junixsocket for Jetty</description>
@@ -34,7 +34,7 @@
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-simple</artifactId>
-            <version>2.0.3</version>
+            <version>2.0.6</version>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/junixsocket-jetty/src/main/java/org/newsclub/net/unix/jetty/AFSocketClientConnector.java b/junixsocket-jetty/src/main/java/org/newsclub/net/unix/jetty/AFSocketClientConnector.java
index 5dee068..34d3a81 100644
--- a/junixsocket-jetty/src/main/java/org/newsclub/net/unix/jetty/AFSocketClientConnector.java
+++ b/junixsocket-jetty/src/main/java/org/newsclub/net/unix/jetty/AFSocketClientConnector.java
@@ -32,11 +32,11 @@ import org.newsclub.net.unix.AFSocketAddress;
 
 /**
  * A {@link Connector} implementation for junixsocket server socket channels (Unix domains etc.)
- * 
+ *
  * Based upon jetty's ClientConnector.
- * 
+ *
  * This implementation should work with jetty version 10.0.8 or newer.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFSocketClientConnector extends ClientConnector {
@@ -50,7 +50,7 @@ public final class AFSocketClientConnector extends ClientConnector {
   /**
    * Returns a new {@link ClientConnector} configured to use given {@link AFSocketAddress} for
    * communication with junixsocket sockets.
-   * 
+   *
    * @param addr The socket address.
    * @return The client connector.
    */
diff --git a/junixsocket-jetty/src/main/java/org/newsclub/net/unix/jetty/AFSocketServerConnector.java b/junixsocket-jetty/src/main/java/org/newsclub/net/unix/jetty/AFSocketServerConnector.java
index 7991b81..402ac66 100644
--- a/junixsocket-jetty/src/main/java/org/newsclub/net/unix/jetty/AFSocketServerConnector.java
+++ b/junixsocket-jetty/src/main/java/org/newsclub/net/unix/jetty/AFSocketServerConnector.java
@@ -49,12 +49,10 @@ import java.nio.channels.spi.SelectorProvider;
 import java.nio.file.Path;
 import java.util.EventListener;
 import java.util.Locale;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.eclipse.jetty.io.ArrayByteBufferPool;
 import org.eclipse.jetty.io.ByteBufferPool;
 import org.eclipse.jetty.io.Connection;
 import org.eclipse.jetty.io.EndPoint;
@@ -81,9 +79,9 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * A {@link Connector} implementation for junixsocket server socket channels (Unix domains etc.)
- * 
+ *
  * Based upon jetty's UnixDomainServerConnector.
- * 
+ *
  * This implementation should work with jetty version 9.4.12 or newer.
  */
 @ManagedObject
@@ -100,12 +98,13 @@ public class AFSocketServerConnector extends AbstractConnector {
   private int acceptedSendBufferSize;
 
   private boolean mayStopServer = false;
+  private boolean mayStopServerForce = false;
   private final Class<? extends EventListener> selectorManagerListenerClass;
   private final Server server;
 
   /**
    * Creates a new {@link AFSocketServerConnector}.
-   * 
+   *
    * @param server The server this connector will be added to. Must not be null.
    * @param factories The Connection Factories to use.
    */
@@ -115,7 +114,7 @@ public class AFSocketServerConnector extends AbstractConnector {
 
   /**
    * Creates a new {@link AFSocketServerConnector}.
-   * 
+   *
    * @param server The server this connector will be added to. Must not be null.
    * @param acceptors the number of acceptor threads to use, or -1 for a default value. If 0, then
    *          no acceptor threads will be launched and some other mechanism will need to be used to
@@ -130,13 +129,13 @@ public class AFSocketServerConnector extends AbstractConnector {
 
   /**
    * Creates a new {@link AFSocketServerConnector}.
-   * 
+   *
    * @param server The server this connector will be added to. Must not be null.
    * @param executor An executor for this connector or null to use the servers executor
    * @param scheduler A scheduler for this connector or null to either a {@link Scheduler} set as a
    *          server bean or if none set, then a new {@link ScheduledExecutorScheduler} instance.
    * @param pool A buffer pool for this connector or null to either a {@link ByteBufferPool} set as
-   *          a server bean or none set, the new {@link ArrayByteBufferPool} instance.
+   *          a server bean or none set, the new {code ArrayByteBufferPool} instance.
    * @param acceptors the number of acceptor threads to use, or -1 for a default value. If 0, then
    *          no acceptor threads will be launched and some other mechanism will need to be used to
    *          accept new connections.
@@ -172,9 +171,9 @@ public class AFSocketServerConnector extends AbstractConnector {
 
   /**
    * Returns the Unix-Domain path this connector listens to.
-   * 
+   *
    * Added for compatibility with jetty's {@code UnixDomainServerConnector}.
-   * 
+   *
    * @return The Unix-Domain path this connector listens to.
    * @deprecated Use {@link #getListenSocketAddress()} instead.
    * @see #getListenSocketAddress()
@@ -196,9 +195,9 @@ public class AFSocketServerConnector extends AbstractConnector {
 
   /**
    * Sets the Unix-Domain path this connector listens to.
-   * 
+   *
    * Added for compatibility with jetty's {@code UnixDomainServerConnector}.
-   * 
+   *
    * @param unixDomainPath The path.
    * @deprecated Use {@link #setListenSocketAddress(AFSocketAddress)} instead.
    * @see #setListenSocketAddress(AFSocketAddress)
@@ -213,7 +212,7 @@ public class AFSocketServerConnector extends AbstractConnector {
 
   /**
    * Returns the socket address this connector listens to.
-   * 
+   *
    * @return The socket address, or {@code null} if none set.
    */
   @ManagedAttribute("The socket address this connector listens to")
@@ -224,7 +223,7 @@ public class AFSocketServerConnector extends AbstractConnector {
 
   /**
    * Sets the socket address this connector listens to.
-   * 
+   *
    * @param addr The socket address, or {@code null}.
    */
   @SuppressFBWarnings("EI_EXPOSE_REP2")
@@ -234,7 +233,7 @@ public class AFSocketServerConnector extends AbstractConnector {
 
   /**
    * Checks whether this connector uses a server channel inherited from the JVM.
-   * 
+   *
    * @return {@code true} if so.
    */
   @ManagedAttribute("Whether this connector uses a server channel inherited from the JVM")
@@ -244,7 +243,7 @@ public class AFSocketServerConnector extends AbstractConnector {
 
   /**
    * Sets whether this connector uses a server channel inherited from the JVM.
-   * 
+   *
    * @param inheritChannel {@code true} if so.
    */
   public void setInheritChannel(boolean inheritChannel) {
@@ -253,7 +252,7 @@ public class AFSocketServerConnector extends AbstractConnector {
 
   /**
    * Returns the accept queue size (backlog) for the server socket.
-   * 
+   *
    * @return The backlog.
    */
   @ManagedAttribute("The accept queue size (backlog) for the server socket")
@@ -263,7 +262,7 @@ public class AFSocketServerConnector extends AbstractConnector {
 
   /**
    * Sets the accept queue size (backlog) for the server socket.
-   * 
+   *
    * @param acceptQueueSize The backlog.
    */
   public void setAcceptQueueSize(int acceptQueueSize) {
@@ -272,7 +271,7 @@ public class AFSocketServerConnector extends AbstractConnector {
 
   /**
    * Returns the SO_RCVBUF size for accepted sockets.
-   * 
+   *
    * @return The buffer size.
    */
   @ManagedAttribute("The SO_RCVBUF option for accepted sockets")
@@ -282,7 +281,7 @@ public class AFSocketServerConnector extends AbstractConnector {
 
   /**
    * Sets the SO_RCVBUF size for accepted sockets.
-   * 
+   *
    * @param acceptedReceiveBufferSize The buffer size.
    */
   public void setAcceptedReceiveBufferSize(int acceptedReceiveBufferSize) {
@@ -291,7 +290,7 @@ public class AFSocketServerConnector extends AbstractConnector {
 
   /**
    * Returns the SO_SNDBUF size for accepted sockets.
-   * 
+   *
    * @return The buffer size.
    */
   @ManagedAttribute("The SO_SNDBUF option for accepted sockets")
@@ -301,7 +300,7 @@ public class AFSocketServerConnector extends AbstractConnector {
 
   /**
    * Sets the SO_SNDBUF size for accepted sockets.
-   * 
+   *
    * @param acceptedSendBufferSize The buffer size.
    */
   public void setAcceptedSendBufferSize(int acceptedSendBufferSize) {
@@ -342,45 +341,35 @@ public class AFSocketServerConnector extends AbstractConnector {
           takenOver = !((AFServerSocketChannel<?>) sc).isLocalSocketAddressValid();
         }
 
-        if (takenOver) {
-          ExecutorService es = Executors.newSingleThreadExecutor();
-          try {
-            LOG.warn("Another server has taken over our address");
-            es.execute(() -> {
-              Connector[] connectors = server.getConnectors();
-
-              boolean shutdownServer;
-              if (connectors == null) {
-                shutdownServer = true;
-              } else {
-                shutdownServer = true;
-                for (Connector conn : connectors) {
-                  if (conn != AFSocketServerConnector.this && conn.isRunning()) { // NOPMD.CompareObjectsWithEquals
-                    shutdownServer = false;
-                    break;
-                  }
-                }
-              }
-
-              if (shutdownServer && mayStopServer) {
-                LOG.warn("Server has no other connectors; shutting down: " + server); // NOPMD
-
-                try {
-                  server.stop();
-                } catch (Exception e1) {
-                  LOG.warn("Exception upon stopping " + server, e1); // NOPMD
-                }
-              }
-            });
-          } finally {
-            es.shutdown();
-          }
+        if (takenOver && isMayStopServer()) {
+          LOG.warn("Another server has taken over our address");
+          CompletableFuture.runAsync(this::checkServerStop);
         }
         throw (ClosedByInterruptException) new ClosedByInterruptException().initCause(e);
       }
     }
   }
 
+  private void checkServerStop() {
+    Connector[] connectors = server.getConnectors();
+
+    if (connectors != null && !isMayStopServerForce()) {
+      for (Connector conn : connectors) {
+        if (conn != AFSocketServerConnector.this && conn.isRunning()) { // NOPMD.CompareObjectsWithEquals
+          return; // don't stop
+        }
+      }
+    }
+
+    LOG.warn("Server has no other connectors; shutting down: " + server); // NOPMD
+
+    try {
+      server.stop();
+    } catch (Exception e1) {
+      LOG.warn("Exception upon stopping " + server, e1); // NOPMD
+    }
+  }
+
   private void accepted(SocketChannel channel) throws IOException {
     channel.configureBlocking(false);
     configure(channel);
@@ -390,7 +379,7 @@ public class AFSocketServerConnector extends AbstractConnector {
   /**
    * Configures an incoming {@link SocketChannel}, setting socket options such as receive and send
    * buffer sizes.
-   * 
+   *
    * @param channel The socket channel to configure.
    * @throws IOException on error.
    */
@@ -533,7 +522,7 @@ public class AFSocketServerConnector extends AbstractConnector {
   /**
    * Checks if this connector may stop the server when it's no longer able to serve and no other
    * connectors are available.
-   * 
+   *
    * @return {@code true} if so.
    */
   @ManagedAttribute("Whether this connector may stop the server when it's no longer able to"
@@ -545,10 +534,35 @@ public class AFSocketServerConnector extends AbstractConnector {
   /**
    * Sets if this connector may stop the server when it's no longer able to serve and no other
    * connectors are available.
-   * 
+   *
    * @param mayStopServer {@code true} if so.
    */
   public void setMayStopServer(boolean mayStopServer) {
     this.mayStopServer = mayStopServer;
   }
+
+  /**
+   * Checks if this connector may stop the server when it's no longer able to serve, even if other
+   * connectors are available.
+   *
+   * @return {@code true} if so.
+   */
+  @ManagedAttribute("Whether this connector may stop the server when it's no longer able to"
+      + " serve, even if other connectors are available")
+  public boolean isMayStopServerForce() {
+    return mayStopServerForce;
+  }
+
+  /**
+   * Sets if this connector may stop the server when it's no longer able to serve and no other
+   * connectors are available.
+   *
+   * @param b {@code true} if so (which then also implies {@code setMayStopServer(true)}
+   */
+  public void setMayStopServerForce(boolean b) {
+    if (b) {
+      setMayStopServer(true);
+    }
+    this.mayStopServerForce = b;
+  }
 }
diff --git a/junixsocket-mysql/pom.xml b/junixsocket-mysql/pom.xml
index bacd7f4..c79df03 100644
--- a/junixsocket-mysql/pom.xml
+++ b/junixsocket-mysql/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-mysql</name>
@@ -23,9 +23,10 @@
             <version>${project.version}</version>
         </dependency>
         <dependency>
-            <groupId>mysql</groupId>
-            <artifactId>mysql-connector-java</artifactId>
-            <version>8.0.30</version>
+            <!-- Starting with 8.0.31, the artifact mysql:mysql-connector-java has been relocated to com.mysql:mysql-connector-j -->
+            <groupId>com.mysql</groupId>
+            <artifactId>mysql-connector-j</artifactId>
+            <version>8.0.32</version>
             <scope>provided</scope>
         </dependency>
     </dependencies>
diff --git a/junixsocket-mysql/src/main/java/module-info.java b/junixsocket-mysql/src/main/java/module-info.java
index 300b929..4949942 100644
--- a/junixsocket-mysql/src/main/java/module-info.java
+++ b/junixsocket-mysql/src/main/java/module-info.java
@@ -8,7 +8,8 @@
   requires java.sql;
   requires java.base;
 
-  requires mysql.connector.java;
+  // requires mysql.connector.java; // until 8.0.30
+  requires mysql.connector.j; // from 8.0.31
 
   requires static com.kohlschutter.annotations.compiletime;
   requires static org.eclipse.jdt.annotation;
diff --git a/junixsocket-mysql/src/main/java/org/newsclub/net/mysql/AFUNIXDatabaseSocketFactory.java b/junixsocket-mysql/src/main/java/org/newsclub/net/mysql/AFUNIXDatabaseSocketFactory.java
index 4693d06..03b4c71 100644
--- a/junixsocket-mysql/src/main/java/org/newsclub/net/mysql/AFUNIXDatabaseSocketFactory.java
+++ b/junixsocket-mysql/src/main/java/org/newsclub/net/mysql/AFUNIXDatabaseSocketFactory.java
@@ -31,13 +31,13 @@ import com.mysql.jdbc.SocketFactory;
 
 /**
  * Connect to mysql databases (and compatibles) using UNIX domain sockets.
- * 
+ *
  * NOTE: This SocketFactory currently implements the "old" Connector/J SocketFactory. This may
  * change in the future.
- * 
+ *
  * For the time being, see AFUNIXDatabaseSocketFactoryCJ to forcibly use the new "CJ"-style
  * SocketFactory.
- * 
+ *
  * @see AFUNIXDatabaseSocketFactoryCJ
  */
 @SuppressWarnings("deprecation")
diff --git a/junixsocket-native-common/pom.xml b/junixsocket-native-common/pom.xml
index 49bf4aa..92265f6 100644
--- a/junixsocket-native-common/pom.xml
+++ b/junixsocket-native-common/pom.xml
@@ -7,7 +7,7 @@
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
         <!-- Update this manually after maven-release -->
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-native-common</name>
diff --git a/junixsocket-native-common/src/main/java/org/newsclub/lib/junixsocket/common/NarMetadata.java b/junixsocket-native-common/src/main/java/org/newsclub/lib/junixsocket/common/NarMetadata.java
index 76f58e8..e1f0ed9 100644
--- a/junixsocket-native-common/src/main/java/org/newsclub/lib/junixsocket/common/NarMetadata.java
+++ b/junixsocket-native-common/src/main/java/org/newsclub/lib/junixsocket/common/NarMetadata.java
@@ -21,7 +21,7 @@ import com.kohlschutter.annotations.compiletime.ExcludeFromCodeCoverageGenerated
 
 /**
  * Marker class to find native libraries in the classpath.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class NarMetadata {
diff --git a/junixsocket-native-common/src/main/java/org/newsclub/lib/junixsocket/common/package-info.java b/junixsocket-native-common/src/main/java/org/newsclub/lib/junixsocket/common/package-info.java
index fab548b..8571110 100644
--- a/junixsocket-native-common/src/main/java/org/newsclub/lib/junixsocket/common/package-info.java
+++ b/junixsocket-native-common/src/main/java/org/newsclub/lib/junixsocket/common/package-info.java
@@ -1,6 +1,6 @@
 /**
  * Helper package to identify the Maven artifact with JNI libraries for common architectures.
- * 
+ *
  * The set of common architectures is configured through Maven profiles and should at least contain
  * versions for Intel 64-bit macOS and Linux.
  */
diff --git a/junixsocket-native-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-native-common/reflect-config.json b/junixsocket-native-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-native-common/reflect-config.json
new file mode 100644
index 0000000..e760d59
--- /dev/null
+++ b/junixsocket-native-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-native-common/reflect-config.json
@@ -0,0 +1,5 @@
+[
+{
+  "name":"org.newsclub.lib.junixsocket.common.NarMetadata"
+}
+]
diff --git a/junixsocket-native-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-native-common/resource-config.json b/junixsocket-native-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-native-common/resource-config.json
new file mode 100644
index 0000000..54ecda6
--- /dev/null
+++ b/junixsocket-native-common/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-native-common/resource-config.json
@@ -0,0 +1,9 @@
+{
+  "resources":{
+  "includes":[
+    {
+      "pattern":"\\QMETA-INF/maven/com.kohlschutter.junixsocket/junixsocket-native-common/pom.properties\\E"
+    } 
+  ]},
+  "bundles":[]
+}
\ No newline at end of file
diff --git a/junixsocket-native-cross/pom.xml b/junixsocket-native-cross/pom.xml
index ed87217..8d1dbe2 100644
--- a/junixsocket-native-cross/pom.xml
+++ b/junixsocket-native-cross/pom.xml
@@ -7,7 +7,7 @@
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
         <!-- Update this manually after maven-release -->
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-native-cross</name>
diff --git a/junixsocket-native-custom/pom.xml b/junixsocket-native-custom/pom.xml
index 10683e3..41226b5 100644
--- a/junixsocket-native-custom/pom.xml
+++ b/junixsocket-native-custom/pom.xml
@@ -7,7 +7,7 @@
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
         <!-- Update this manually after maven-release -->
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-native-custom</name>
diff --git a/junixsocket-native-custom/src/main/java/org/newsclub/lib/junixsocket/custom/NarMetadata.java b/junixsocket-native-custom/src/main/java/org/newsclub/lib/junixsocket/custom/NarMetadata.java
index 4613c7e..bd66e21 100644
--- a/junixsocket-native-custom/src/main/java/org/newsclub/lib/junixsocket/custom/NarMetadata.java
+++ b/junixsocket-native-custom/src/main/java/org/newsclub/lib/junixsocket/custom/NarMetadata.java
@@ -21,7 +21,7 @@ import com.kohlschutter.annotations.compiletime.ExcludeFromCodeCoverageGenerated
 
 /**
  * Marker class to find native libraries in the classpath.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class NarMetadata {
diff --git a/junixsocket-native-custom/src/main/java/org/newsclub/lib/junixsocket/custom/package-info.java b/junixsocket-native-custom/src/main/java/org/newsclub/lib/junixsocket/custom/package-info.java
index 0680697..6d05281 100644
--- a/junixsocket-native-custom/src/main/java/org/newsclub/lib/junixsocket/custom/package-info.java
+++ b/junixsocket-native-custom/src/main/java/org/newsclub/lib/junixsocket/custom/package-info.java
@@ -1,11 +1,11 @@
 /**
  * Helper package to identify the Maven artifact with JNI libraries for specific architectures.
- * 
+ *
  * There are multiple artifacts with the same identifier (junixsocket-native), one per architecture.
- * 
+ *
  * If you want to run junixsocket on your architecture, you need to make sure that the correct one
  * is in the classpath.
- * 
+ *
  * See "junixsocket-native-common" for an artifact containing the commonly used architectures.
  */
 package org.newsclub.lib.junixsocket.custom;
diff --git a/junixsocket-native-custom/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-native-custom/reflect-config.json b/junixsocket-native-custom/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-native-custom/reflect-config.json
new file mode 100644
index 0000000..3ca3687
--- /dev/null
+++ b/junixsocket-native-custom/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-native-custom/reflect-config.json
@@ -0,0 +1,5 @@
+[
+{
+  "name":"org.newsclub.lib.junixsocket.custom.NarMetadata"
+}
+]
diff --git a/junixsocket-native-custom/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-native-custom/resource-config.json b/junixsocket-native-custom/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-native-custom/resource-config.json
new file mode 100644
index 0000000..6ea5af4
--- /dev/null
+++ b/junixsocket-native-custom/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-native-custom/resource-config.json
@@ -0,0 +1,9 @@
+{
+  "resources":{
+  "includes":[
+    {
+      "pattern":"\\QMETA-INF/maven/com.kohlschutter.junixsocket/junixsocket-native-custom/pom.properties\\E"
+    } 
+  ]},
+  "bundles":[]
+}
\ No newline at end of file
diff --git a/junixsocket-native-graalvm/bin/graalvm b/junixsocket-native-graalvm/bin/graalvm
deleted file mode 100755
index d06e042..0000000
--- a/junixsocket-native-graalvm/bin/graalvm
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-java -version 2>&1 | grep -q GraalVM
-if [[ $? -eq 0 ]]; then
-	exec $@
-fi
-
-# FIXME auto-detect
-export JAVA_HOME=/Library/Java/JavaVirtualMachines/graalvm-ce-java17-22.2.0/Contents/Home
-export PATH=$JAVA_HOME/bin:$PATH
-exec $@
diff --git a/junixsocket-native-graalvm/bin/with-graalvm b/junixsocket-native-graalvm/bin/with-graalvm
new file mode 100755
index 0000000..4f5389a
--- /dev/null
+++ b/junixsocket-native-graalvm/bin/with-graalvm
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+#
+# junixsocket
+# Copyright 2009-2022 Christian Kohlschütter
+# SPDX-License-Identifier: Apache-2.0
+#
+# Script to detect and enable GraalVM.
+#
+# When run without arguments, an eval-able string like "GRAALVM_HOME=/path/to/graalvm" is emitted.
+# Otherwise, the arguments are executed with the determined GraalVM in path (GRAALVM_HOME, JAVA_HOME and PATH set accordingly).
+#
+java -version 2>&1 | grep -q GraalVM
+if [[ $? -eq 0 ]]; then
+    exec $@
+fi
+
+if [[ -z "$GRAALVM_HOME" ]]; then
+    for d in $(find /Library/Java/JavaVirtualMachines /usr/lib/jvm -maxdepth 1 -type d -name "*graalvm*" 2>/dev/null | sort -r); do
+        if [[ -e "$d/bin/java" ]]; then
+            export GRAALVM_HOME="$d"
+            break
+        elif [[ -e "$d/Contents/Home/bin/java" ]]; then
+            export GRAALVM_HOME="$d/Contents/Home"
+            break
+        fi
+    done
+fi
+
+if [[ -z "$GRAALVM_HOME" ]]; then
+    echo "Error: Could not determine GRAALVM_HOME -- Please set manually" >&2
+    exit 1
+else
+    if [[ $# -eq 0 ]]; then
+        echo "GRAALVM_HOME=$GRAALVM_HOME"
+    fi
+fi
+
+export JAVA_HOME="$GRAALVM_HOME"
+export PATH=$JAVA_HOME/bin:$PATH
+exec -- $@
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/project.pbxproj b/junixsocket-native/junixsocket-native.xcodeproj/project.pbxproj
index a1bb6f5..9737a7b 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/project.pbxproj
+++ b/junixsocket-native/junixsocket-native.xcodeproj/project.pbxproj
@@ -2551,7 +2551,7 @@
 		43D436B0261A55D0002D0C12 /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastUpgradeCheck = 1320;
+				LastUpgradeCheck = 1410;
 				TargetAttributes = {
 					432EF186261AD52100F4A583 = {
 						CreatedOnToolsVersion = 11.3.1;
@@ -3314,7 +3314,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3343,7 +3343,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3369,6 +3369,7 @@
 			buildSettings = {
 				CLANG_ENABLE_OBJC_WEAK = YES;
 				CODE_SIGN_STYLE = Automatic;
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 			};
 			name = Debug;
@@ -3378,6 +3379,7 @@
 			buildSettings = {
 				CLANG_ENABLE_OBJC_WEAK = YES;
 				CODE_SIGN_STYLE = Automatic;
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
 			};
 			name = Release;
@@ -3390,7 +3392,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3415,7 +3417,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3440,7 +3442,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3470,7 +3472,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3500,7 +3502,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3527,7 +3529,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3554,7 +3556,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3580,7 +3582,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3606,7 +3608,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3631,7 +3633,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3656,7 +3658,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3681,7 +3683,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3706,7 +3708,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3735,7 +3737,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3764,7 +3766,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3789,7 +3791,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3810,12 +3812,13 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				CLANG_ENABLE_OBJC_WEAK = YES;
+				CODE_SIGN_IDENTITY = "-";
 				CROSSCLANG_TARGET = "x86_64-apple-darwin18.2.0";
 				EXECUTABLE_EXTENSION = dylib;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
 				LLVM_LTO = YES;
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3837,12 +3840,13 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				CLANG_ENABLE_OBJC_WEAK = YES;
+				CODE_SIGN_IDENTITY = "-";
 				CROSSCLANG_TARGET = "x86_64-apple-darwin18.2.0";
 				EXECUTABLE_EXTENSION = dylib;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
 				LLVM_LTO = YES;
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3864,11 +3868,12 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				CLANG_ENABLE_OBJC_WEAK = YES;
+				CODE_SIGN_IDENTITY = "-";
 				CROSSCLANG_TARGET = current;
 				EXECUTABLE_EXTENSION = dylib;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3888,11 +3893,12 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				CLANG_ENABLE_OBJC_WEAK = YES;
+				CODE_SIGN_IDENTITY = "-";
 				CROSSCLANG_TARGET = current;
 				EXECUTABLE_EXTENSION = dylib;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3916,7 +3922,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3947,7 +3953,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -3983,7 +3989,7 @@
 				);
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -4019,7 +4025,7 @@
 				);
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -4057,7 +4063,7 @@
 				);
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -4094,7 +4100,7 @@
 				);
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -4126,7 +4132,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -4152,7 +4158,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -4178,7 +4184,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -4203,7 +4209,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -4228,7 +4234,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -4254,7 +4260,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -4281,7 +4287,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-fno-lto",
@@ -4314,7 +4320,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-fno-lto",
@@ -4342,11 +4348,12 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				CLANG_ENABLE_OBJC_WEAK = YES;
+				CODE_SIGN_IDENTITY = "-";
 				CROSSCLANG_TARGET = "arm64-apple-macos11";
 				EXECUTABLE_EXTENSION = dylib;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -4366,11 +4373,12 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				CLANG_ENABLE_OBJC_WEAK = YES;
+				CODE_SIGN_IDENTITY = "-";
 				CROSSCLANG_TARGET = "arm64-apple-macos11";
 				EXECUTABLE_EXTENSION = dylib;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -4414,6 +4422,7 @@
 				CODE_SIGN_STYLE = Manual;
 				COMPILER_INDEX_STORE_ENABLE = NO;
 				COPY_PHASE_STRIP = NO;
+				DEAD_CODE_STRIPPING = YES;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;
 				EXECUTABLE_PREFIX = "libjunixsocket-";
@@ -4430,6 +4439,7 @@
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = src/main/c/jni;
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				ONLY_ACTIVE_ARCH = YES;
 				OTHER_CFLAGS = (
 					"-fno-strict-overflow",
@@ -4495,6 +4505,7 @@
 				CODE_SIGN_STYLE = Manual;
 				COMPILER_INDEX_STORE_ENABLE = NO;
 				COPY_PHASE_STRIP = NO;
+				DEAD_CODE_STRIPPING = YES;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				EXECUTABLE_PREFIX = "libjunixsocket-";
 				GCC_CW_ASM_SYNTAX = NO;
@@ -4509,6 +4520,7 @@
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				HEADER_SEARCH_PATHS = src/main/c/jni;
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				ONLY_ACTIVE_ARCH = YES;
 				OTHER_CFLAGS = (
 					"-fno-strict-overflow",
@@ -4554,7 +4566,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
@@ -4586,7 +4598,7 @@
 				EXECUTABLE_EXTENSION = so;
 				LD_DEPENDENCY_INFO_FILE = "";
 				LD_LTO_OBJECT_FILE = "";
-				MACOSX_DEPLOYMENT_TARGET = "";
+				MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
 				OTHER_CFLAGS = (
 					"$(inherited)",
 					"-target",
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/All Architectures.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/All Architectures.xcscheme
index 9f879e6..9c89240 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/All Architectures.xcscheme	
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/All Architectures.xcscheme	
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/aarch64-linux-gnu.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/aarch64-linux-gnu.xcscheme
index 22e9345..a48896b 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/aarch64-linux-gnu.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/aarch64-linux-gnu.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/aarch64-w64-mingw32.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/aarch64-w64-mingw32.xcscheme
index f600fdc..5517ae1 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/aarch64-w64-mingw32.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/aarch64-w64-mingw32.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1330"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/amd64-unknown-openbsd6.9.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/amd64-unknown-openbsd6.9.xcscheme
index 1c6732b..c17016a 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/amd64-unknown-openbsd6.9.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/amd64-unknown-openbsd6.9.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/arm64-apple-macos11.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/arm64-apple-macos11.xcscheme
index 868ef8c..50af22b 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/arm64-apple-macos11.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/arm64-apple-macos11.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/armv6--linux-gnueabihf.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/armv6--linux-gnueabihf.xcscheme
index de8f175..5b5eae9 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/armv6--linux-gnueabihf.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/armv6--linux-gnueabihf.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/current.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/current.xcscheme
index bd8707a..de162e8 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/current.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/current.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/i386-pc-solaris2.11_m64.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/i386-pc-solaris2.11_m64.xcscheme
index c5dafb6..3e9ac40 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/i386-pc-solaris2.11_m64.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/i386-pc-solaris2.11_m64.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/powerpc-ibm-aix7.2.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/powerpc-ibm-aix7.2.xcscheme
index b3d78f4..7118054 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/powerpc-ibm-aix7.2.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/powerpc-ibm-aix7.2.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1330"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/powerpc-ibm-os400.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/powerpc-ibm-os400.xcscheme
index 8fa3ed8..5ac14ef 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/powerpc-ibm-os400.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/powerpc-ibm-os400.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1330"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/powerpc64le-linux-gnu.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/powerpc64le-linux-gnu.xcscheme
index c5697fc..feead26 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/powerpc64le-linux-gnu.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/powerpc64le-linux-gnu.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/riscv64-redhat-linux.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/riscv64-redhat-linux.xcscheme
index 743e6ff..9949d41 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/riscv64-redhat-linux.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/riscv64-redhat-linux.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/s390x-ibm-linux-gnu.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/s390x-ibm-linux-gnu.xcscheme
index b1c1522..d1c184f 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/s390x-ibm-linux-gnu.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/s390x-ibm-linux-gnu.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/sparc-sun-solaris2.11.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/sparc-sun-solaris2.11.xcscheme
index 601b42e..468630c 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/sparc-sun-solaris2.11.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/sparc-sun-solaris2.11.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-alpine-linux-musl.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-alpine-linux-musl.xcscheme
index b7073a8..d291263 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-alpine-linux-musl.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-alpine-linux-musl.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-apple-darwin18.2.0.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-apple-darwin18.2.0.xcscheme
index af6dcd6..776cb39 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-apple-darwin18.2.0.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-apple-darwin18.2.0.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-portbld-dragonfly6.0.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-portbld-dragonfly6.0.xcscheme
index 3ec1048..956febc 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-portbld-dragonfly6.0.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-portbld-dragonfly6.0.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-unknown-freebsd12.1.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-unknown-freebsd12.1.xcscheme
index ac4ee63..400d766 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-unknown-freebsd12.1.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-unknown-freebsd12.1.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-unknown-linux-gnu.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-unknown-linux-gnu.xcscheme
index 17a28a1..a2c7afa 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-unknown-linux-gnu.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-unknown-linux-gnu.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-unknown-netbsd9.0.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-unknown-netbsd9.0.xcscheme
index a234090..fb57e5e 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-unknown-netbsd9.0.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-unknown-netbsd9.0.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-w64-mingw32.xcscheme b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-w64-mingw32.xcscheme
index e41a00b..ba0ed1a 100644
--- a/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-w64-mingw32.xcscheme
+++ b/junixsocket-native/junixsocket-native.xcodeproj/xcshareddata/xcschemes/x86_64-w64-mingw32.xcscheme
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "1320"
+   LastUpgradeVersion = "1410"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
diff --git a/junixsocket-native/pom.xml b/junixsocket-native/pom.xml
index f0b74ba..7dfb650 100644
--- a/junixsocket-native/pom.xml
+++ b/junixsocket-native/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-native</name>
diff --git a/junixsocket-rmi/pom.xml b/junixsocket-rmi/pom.xml
index 3e2d19a..0b1cf1f 100644
--- a/junixsocket-rmi/pom.xml
+++ b/junixsocket-rmi/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-rmi</name>
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNaming.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNaming.java
index 9bb43c1..5ee6f7e 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNaming.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNaming.java
@@ -48,7 +48,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 /**
  * The {@link AFSocket}-compatible equivalent of {@link Naming}. Use this class for accessing RMI
  * registries that are reachable by {@link AFSocket}s.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public abstract class AFNaming extends AFRegistryAccess {
@@ -67,7 +67,7 @@ public abstract class AFNaming extends AFRegistryAccess {
 
   /**
    * Creates a new naming instance with the given ports.
-   * 
+   *
    * @param registryPort The registry port.
    * @param servicePort The port for AFRMIService.
    * @throws IOException on error.
@@ -80,7 +80,7 @@ public abstract class AFNaming extends AFRegistryAccess {
 
   /**
    * Creates a new {@link AFRegistry} given a {@link Registry} implementation.
-   * 
+   *
    * @param impl The implementation.
    * @return The new {@link AFRegistry} instance.
    * @throws RemoteException on error.
@@ -89,7 +89,7 @@ public abstract class AFNaming extends AFRegistryAccess {
 
   /**
    * Creates or returns the {@link AFRMISocketFactory} to be used with this instance.
-   * 
+   *
    * @return The socket factory.
    * @throws IOException on error.
    */
@@ -121,7 +121,7 @@ public abstract class AFNaming extends AFRegistryAccess {
 
   /**
    * Returns the {@link AFRMISocketFactory} associated with this instance.
-   * 
+   *
    * @return The {@link AFRMISocketFactory}.
    */
   @SuppressFBWarnings("EI_EXPOSE_REP")
@@ -131,7 +131,7 @@ public abstract class AFNaming extends AFRegistryAccess {
 
   /**
    * Returns the registry port.
-   * 
+   *
    * @return The port.
    */
   public final int getRegistryPort() {
@@ -184,10 +184,10 @@ public abstract class AFNaming extends AFRegistryAccess {
 
   /**
    * Returns a reference to the existing RMI registry.
-   * 
+   *
    * If there's no registry running at this port after waiting for up to the given time, an
    * exception is thrown.
-   * 
+   *
    * @param timeout The timeout value.
    * @param unit The timeout unit.
    * @return The registry.
@@ -208,7 +208,7 @@ public abstract class AFNaming extends AFRegistryAccess {
 
   /**
    * Tries to access the registry, waiting some time if necessary.
-   * 
+   *
    * @param timeout The timeout.
    * @param unit The unit for the timeout.
    * @return The registry instance.
@@ -221,7 +221,7 @@ public abstract class AFNaming extends AFRegistryAccess {
    *
    * If there's no registry running at this port, and {@code create} is set to {@code true}, a new
    * one is created; when {@code create} is set to {@code false}, {@code null} is returned.
-   * 
+   *
    * @param create {@code true} if a new register may be created if necessary.
    * @return The registry, or {@code null}
    * @throws RemoteException If there was a problem.
@@ -262,7 +262,7 @@ public abstract class AFNaming extends AFRegistryAccess {
 
   /**
    * Shuts this RMI Registry down.
-   * 
+   *
    * @throws RemoteException if the operation fails.
    */
   public void shutdownRegistry() throws RemoteException {
@@ -359,12 +359,12 @@ public abstract class AFNaming extends AFRegistryAccess {
 
   /**
    * Creates a new RMI {@link Registry}.
-   * 
+   *
    * If there already was a registry created previously, it is shut down and replaced by the current
    * one.
-   * 
+   *
    * Use {@link #getRegistry()} to try to reuse an existing registry.
-   * 
+   *
    * @return The registry
    * @throws RemoteException if the operation fails.
    * @see #getRegistry()
@@ -407,14 +407,14 @@ public abstract class AFNaming extends AFRegistryAccess {
 
   /**
    * Called by {@link #createRegistry()} right before creating/setting the registry.
-   * 
+   *
    * @throws ServerException on error.
    */
   protected abstract void initRegistryPrerequisites() throws ServerException;
 
   /**
    * Checks if this {@link AFNaming} instance can be shut down remotely.
-   * 
+   *
    * @return {@code true} if remote shutdown is allowed.
    */
   public boolean isRemoteShutdownAllowed() {
@@ -423,7 +423,7 @@ public abstract class AFNaming extends AFRegistryAccess {
 
   /**
    * Controls whether this {@link AFNaming} instance can be shut down remotely.
-   * 
+   *
    * @param remoteShutdownAllowed {@code true} if remote shutdown is allowed.
    */
   public void setRemoteShutdownAllowed(boolean remoteShutdownAllowed) {
@@ -433,7 +433,7 @@ public abstract class AFNaming extends AFRegistryAccess {
   /**
    * Exports and binds the given Remote object to the given name, using the given {@link AFNaming}
    * setup.
-   * 
+   *
    * @param name The name to use to bind the object in the registry.
    * @param obj The object to export and bind.
    * @throws RemoteException if the operation fails.
@@ -448,7 +448,7 @@ public abstract class AFNaming extends AFRegistryAccess {
   /**
    * Exports and re-binds the given Remote object to the given name, using the given
    * {@link AFNaming} setup.
-   * 
+   *
    * @param name The name to use to bind the object in the registry.
    * @param obj The object to export and bind.
    * @throws RemoteException if the operation fails.
@@ -478,9 +478,9 @@ public abstract class AFNaming extends AFRegistryAccess {
 
   /**
    * Exports the given Remote object, using the given socket factory and a randomly assigned port.
-   * 
+   *
    * NOTE: This helper function can also be used for regular RMI servers.
-   * 
+   *
    * @param obj The object to export.
    * @param socketFactory The socket factory to use.
    * @return The remote stub.
@@ -494,9 +494,9 @@ public abstract class AFNaming extends AFRegistryAccess {
   /**
    * Forcibly un-exports the given object, if it exists (otherwise returns without an error). This
    * should be called upon closing a {@link Closeable} {@link Remote} object.
-   * 
+   *
    * NOTE: This helper function can also be used for regular RMI servers.
-   * 
+   *
    * @param obj The object to un-export.
    */
   public static void unexportObject(Remote obj) {
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNamingProvider.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNamingProvider.java
index e412a13..4982036 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNamingProvider.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNamingProvider.java
@@ -21,17 +21,17 @@ import java.io.IOException;
 
 /**
  * The key to accessing to {@link AFNaming} instances.
- * 
+ *
  * Implementors must guarantee that {@link #hashCode()} and {@link #equals(Object)} correctly
  * identify duplicate providers.
- * 
+ *
  * @param <T> The actual {@link AFNaming} subclass.
  * @author Christian Kohlschütter
  */
 public interface AFNamingProvider<T extends AFNaming> {
   /**
    * Creates a new {@link AFNaming} instance using the given registry port.
-   * 
+   *
    * @param registryPort The registry port.
    * @return The {@link AFNaming} instance.
    * @throws IOException on error.
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNamingRef.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNamingRef.java
index 92f010b..f9193f1 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNamingRef.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFNamingRef.java
@@ -22,7 +22,7 @@ import java.util.Objects;
 
 /**
  * A reference to a {@link AFNaming} instance.
- * 
+ *
  * @author Christian Kohlschütter
  */
 final class AFNamingRef {
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIService.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIService.java
index 10d7edd..b70b0bd 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIService.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIService.java
@@ -25,16 +25,16 @@ import java.util.stream.IntStream;
 
 /**
  * The {@link AFRMIService} assigns and keeps track of anonymous ports, among other things.
- * 
+ *
  * This feature is to be used by {@link AFRMISocketFactory} only.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public interface AFRMIService extends Remote {
   /**
    * Registers a new anonymous port and returns it. When the port is not required anymore, it must
    * be returned via {@link #returnPort(int)}.
-   * 
+   *
    * @return The new port.
    * @throws IOException if the operation fails.
    */
@@ -43,7 +43,7 @@ public interface AFRMIService extends Remote {
   /**
    * Returns a previously registered port. No error is thrown if the given port has not been
    * assigned before.
-   * 
+   *
    * @param port The port.
    * @throws IOException if the operation fails.
    */
@@ -51,7 +51,7 @@ public interface AFRMIService extends Remote {
 
   /**
    * Returns a stream of open ports.
-   * 
+   *
    * @return A sequence of open ports.
    * @throws RemoteException if the operation fails.
    */
@@ -59,9 +59,9 @@ public interface AFRMIService extends Remote {
 
   /**
    * Indicates whether a remote-shutdown of the RMI registry is allowed.
-   * 
+   *
    * NOTE: A call to {@link #shutdown()} may or may not succeed regardless.
-   * 
+   *
    * @return Indication of whether a remote-shutdown of the RMI registry is allowed.
    * @throws RemoteException if the operation fails.
    */
@@ -69,7 +69,7 @@ public interface AFRMIService extends Remote {
 
   /**
    * Asks that this RMI registry gets shut down.
-   * 
+   *
    * @throws RemoteException if the operation fails.
    */
   void shutdown() throws RemoteException;
@@ -77,7 +77,7 @@ public interface AFRMIService extends Remote {
   /**
    * Adds the given {@link Closeable} to the list of instances to be closed upon shutdown of the RMI
    * registry.
-   * 
+   *
    * @param closeable The instance.
    * @throws RemoteException if the operation fails.
    */
@@ -86,9 +86,9 @@ public interface AFRMIService extends Remote {
   /**
    * Removes the given {@link Closeable} from the list of instances to be closed upon shutdown of
    * the RMI registry.
-   * 
+   *
    * No error is returned if the given element was not registered before.
-   * 
+   *
    * @param closeable The instance.
    * @throws RemoteException if the operation fails.
    */
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIServiceImpl.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIServiceImpl.java
index 01d5083..727aa74 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIServiceImpl.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMIServiceImpl.java
@@ -38,7 +38,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * A very simple implementation of a {@link AFRMIService}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 final class AFRMIServiceImpl implements AFRMIService {
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMISocketFactory.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMISocketFactory.java
index 820fdfa..ba49e7e 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMISocketFactory.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRMISocketFactory.java
@@ -42,7 +42,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * An {@link RMISocketFactory} that supports {@link AFSocket}s.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public abstract class AFRMISocketFactory extends RMISocketFactory implements Externalizable,
@@ -61,7 +61,7 @@ public abstract class AFRMISocketFactory extends RMISocketFactory implements Ext
 
   /**
    * Constructor required per definition.
-   * 
+   *
    * @see RMISocketFactory
    */
   public AFRMISocketFactory() {
@@ -71,7 +71,7 @@ public abstract class AFRMISocketFactory extends RMISocketFactory implements Ext
 
   /**
    * Creates a new socket factory.
-   * 
+   *
    * @param naming The {@link AFNaming} instance to use.
    * @param defaultClientFactory The default {@link RMIClientSocketFactory}.
    * @param defaultServerFactory The default {@link RMIServerSocketFactory}.
@@ -106,7 +106,7 @@ public abstract class AFRMISocketFactory extends RMISocketFactory implements Ext
 
   /**
    * Creates a new socket address for the given RMI port.
-   * 
+   *
    * @param port The port.
    * @return The socket address.
    * @throws IOException on error.
@@ -115,7 +115,7 @@ public abstract class AFRMISocketFactory extends RMISocketFactory implements Ext
 
   /**
    * Creates a new socket that is connected to the given socket address.
-   * 
+   *
    * @param addr The socket address.
    * @return The connected socket.
    * @throws IOException on error.
@@ -167,7 +167,7 @@ public abstract class AFRMISocketFactory extends RMISocketFactory implements Ext
 
   /**
    * Returns a new free port.
-   * 
+   *
    * @return The new port.
    * @throws IOException on error.
    * @see #returnPort(int)
@@ -178,7 +178,7 @@ public abstract class AFRMISocketFactory extends RMISocketFactory implements Ext
 
   /**
    * Returns a port that was previously returned by {@link #newPort()}.
-   * 
+   *
    * @param port The port to return.
    * @throws IOException on error.
    */
@@ -298,7 +298,7 @@ public abstract class AFRMISocketFactory extends RMISocketFactory implements Ext
 
   /**
    * Deserializes information necessary to instantiate the {@link AFNaming} instance.
-   * 
+   *
    * @param in The stream.
    * @return The {@link AFNaming} instance.
    * @throws IOException on error.
@@ -307,7 +307,7 @@ public abstract class AFRMISocketFactory extends RMISocketFactory implements Ext
 
   /**
    * Serializes information necessary to instantiate the given {@link AFNaming} instance.
-   * 
+   *
    * @param out The stream.
    * @param namingInstance The {@link AFNaming} instance.
    * @throws IOException on error.
@@ -317,7 +317,7 @@ public abstract class AFRMISocketFactory extends RMISocketFactory implements Ext
 
   /**
    * Checks if the given port refers to a local server port.
-   * 
+   *
    * @param port The port to check.
    * @return {@code true} if the given port is a local server.
    */
@@ -332,7 +332,7 @@ public abstract class AFRMISocketFactory extends RMISocketFactory implements Ext
 
   /**
    * The naming instance.
-   * 
+   *
    * @return The instance.
    */
   protected AFNaming getNaming() {
@@ -341,7 +341,7 @@ public abstract class AFRMISocketFactory extends RMISocketFactory implements Ext
 
   /**
    * Checks if this socket factory has some knowledge about the given port.
-   * 
+   *
    * @param port The port.
    * @return {@code true} if registered.
    */
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistry.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistry.java
index c2402bb..8ef24ff 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistry.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistry.java
@@ -39,7 +39,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 /**
  * A wrapper for RMI registries, both remote and local, to allow for a clean removal of bound
  * resources upon shutdown.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public abstract class AFRegistry implements Registry {
@@ -78,7 +78,7 @@ public abstract class AFRegistry implements Registry {
   /**
    * Returns {@code true} if the wrapped Registry instance is a locally created
    * {@link RemoteServer}.
-   * 
+   *
    * @return {@code true} if wrapped instance is a locally created {@link RemoteServer}.
    * @see #isLocal()
    */
@@ -89,7 +89,7 @@ public abstract class AFRegistry implements Registry {
 
   /**
    * Returns {@code true} if the wrapped Registry instance is locally created.
-   * 
+   *
    * @return {@code true} if wrapped instance is locally created.
    */
   public final boolean isLocal() {
@@ -98,7 +98,7 @@ public abstract class AFRegistry implements Registry {
 
   /**
    * Returns the {@link AFNaming} instance responsible for this registry.
-   * 
+   *
    * @return The {@link AFNaming} instance.
    */
   @SuppressFBWarnings("EI_EXPOSE_REP")
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistryAccess.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistryAccess.java
index 24d08c9..050113c 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistryAccess.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFRegistryAccess.java
@@ -28,9 +28,9 @@ import java.util.concurrent.TimeUnit;
 abstract class AFRegistryAccess {
   /**
    * Returns a reference to the existing RMI registry.
-   * 
+   *
    * If there's no registry running at this port, an exception is thrown.
-   * 
+   *
    * @return The registry.
    * @throws RemoteException If there was a problem.
    */
@@ -38,7 +38,7 @@ abstract class AFRegistryAccess {
 
   /**
    * Convenience method for {@code getRegistry().lookup}.
-   * 
+   *
    * @param name the name for the remote reference to look up
    * @return The instance
    * @throws NotBoundException upon error
@@ -53,7 +53,7 @@ abstract class AFRegistryAccess {
 
   /**
    * Convenience method for {@code getRegistry().lookup}.
-   * 
+   *
    * @param name the name for the remote reference to look up
    * @param timeout The timeout value.
    * @param unit The timeout unit.
@@ -70,7 +70,7 @@ abstract class AFRegistryAccess {
 
   /**
    * Convenience method for {@code getRegistry().unbind}.
-   * 
+   *
    * @param name the name for the remote reference to unbind
    * @throws RemoteException upon error
    * @throws NotBoundException upon error
@@ -83,7 +83,7 @@ abstract class AFRegistryAccess {
 
   /**
    * Convenience method for {@code getRegistry().bind}.
-   * 
+   *
    * @param name the name for the remote reference to bind
    * @param obj the remote reference to bind
    * @throws RemoteException upon error
@@ -98,7 +98,7 @@ abstract class AFRegistryAccess {
 
   /**
    * Convenience method for {@code getRegistry().rebind}.
-   * 
+   *
    * @param name the name for the remote reference to rebind
    * @param obj the remote reference to rebind
    * @throws RemoteException upon error
@@ -111,10 +111,10 @@ abstract class AFRegistryAccess {
 
   /**
    * Convenience method for {@code getRegistry().list}.
-   * 
+   *
    * Unlike {@link AFRegistry#list()}, in case the registry has been shut down already, an empty
    * array is returned.
-   * 
+   *
    * @return an array of the names bound in this registry
    * @throws RemoteException upon error
    * @throws AccessException upon error
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXNaming.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXNaming.java
index 10566ab..928b8e4 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXNaming.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXNaming.java
@@ -35,7 +35,7 @@ import org.newsclub.net.unix.AFUNIXSocket;
 /**
  * The {@link AFUNIXSocket}-compatible equivalent of {@link Naming}. Use this class for accessing
  * RMI registries that are reachable by {@link AFUNIXSocket}s.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFUNIXNaming extends AFNaming {
@@ -66,10 +66,10 @@ public final class AFUNIXNaming extends AFNaming {
 
   /**
    * Returns the directory where RMI sockets are stored by default.
-   * 
+   *
    * You can configure this location by setting the System property
    * {@code org.newsclub.net.unix.rmi.socketdir} upon start.
-   * 
+   *
    * @return The directory.
    */
   public static File getDefaultSocketDirectory() {
@@ -79,7 +79,7 @@ public final class AFUNIXNaming extends AFNaming {
   /**
    * Returns a new private instance that resides in a custom location, to avoid any collisions with
    * existing instances.
-   * 
+   *
    * @return The private {@link AFNaming} instance.
    * @throws IOException if the operation fails.
    */
@@ -98,7 +98,7 @@ public final class AFUNIXNaming extends AFNaming {
   /**
    * Returns the default instance of {@link AFUNIXNaming}. Sockets are stored in
    * <code>java.io.tmpdir</code>.
-   * 
+   *
    * @return The default instance.
    * @throws IOException if the operation fails.
    */
@@ -109,7 +109,7 @@ public final class AFUNIXNaming extends AFNaming {
   /**
    * Returns a {@link AFUNIXNaming} instance which support several socket files that can be stored
    * under the same, given directory.
-   * 
+   *
    * @param socketDir The directory to store sockets in.
    * @return The instance.
    * @throws RemoteException if the operation fails.
@@ -121,10 +121,10 @@ public final class AFUNIXNaming extends AFNaming {
   /**
    * Returns a {@link AFUNIXNaming} instance which support several socket files that can be stored
    * under the same, given directory.
-   * 
+   *
    * A custom "registry port" can be specified. Typically, AF-UNIX specific ports should be above
    * {@code 100000}.
-   * 
+   *
    * @param socketDir The directory to store sockets in.
    * @param registryPort The registry port. Should be above {@code 100000}.
    * @return The instance.
@@ -138,10 +138,10 @@ public final class AFUNIXNaming extends AFNaming {
   /**
    * Returns a {@link AFUNIXNaming} instance which support several socket files that can be stored
    * under the same, given directory.
-   * 
+   *
    * A custom "registry port" can be specified. Typically, AF-UNIX specific ports should be above
    * {@code 100000}.
-   * 
+   *
    * @param socketDir The directory to store sockets in.
    * @param registryPort The registry port. Should be above {@code 100000}.
    * @param socketPrefix A string to be inserted at the beginning of each socket filename, or
@@ -183,7 +183,7 @@ public final class AFUNIXNaming extends AFNaming {
   /**
    * Returns an {@link AFUNIXNaming} instance which only supports one file. (Probably only useful
    * when you want/can access the exported {@link UnicastRemoteObject} directly)
-   * 
+   *
    * @param socketFile The socket file.
    * @return The instance.
    * @throws IOException if the operation fails.
@@ -221,7 +221,7 @@ public final class AFUNIXNaming extends AFNaming {
    * Returns the socket file which is used to control the RMI registry.
    *
    * The file is usually in the directory returned by {@link #getRegistrySocketDir()}.
-   * 
+   *
    * @return The directory.
    */
   public File getRegistrySocketFile() {
@@ -285,7 +285,7 @@ public final class AFUNIXNaming extends AFNaming {
 
   /**
    * Returns the directory in which sockets used by this registry are located.
-   * 
+   *
    * @return The directory.
    */
   public File getRegistrySocketDir() {
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRMISocketFactory.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRMISocketFactory.java
index 4f101db..c04fb15 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRMISocketFactory.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRMISocketFactory.java
@@ -39,7 +39,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * An {@link RMISocketFactory} that supports {@link AFUNIXSocket}s.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class AFUNIXRMISocketFactory extends AFRMISocketFactory {
@@ -56,7 +56,7 @@ public class AFUNIXRMISocketFactory extends AFRMISocketFactory {
 
   /**
    * Constructor required per definition.
-   * 
+   *
    * @see RMISocketFactory
    */
   public AFUNIXRMISocketFactory() {
@@ -65,7 +65,7 @@ public class AFUNIXRMISocketFactory extends AFRMISocketFactory {
 
   /**
    * Creates a new socket factory.
-   * 
+   *
    * @param naming The {@link AFNaming} instance to use.
    * @param socketDir The directory to store the sockets in.
    * @param defaultClientFactory The default {@link RMIClientSocketFactory}.
@@ -90,7 +90,7 @@ public class AFUNIXRMISocketFactory extends AFRMISocketFactory {
 
   /**
    * Creates a new socket factory.
-   * 
+   *
    * @param naming The {@link AFNaming} instance to use.
    * @param socketDir The directory to store the sockets in.
    * @param defaultClientFactory The default {@link RMIClientSocketFactory}.
@@ -105,7 +105,7 @@ public class AFUNIXRMISocketFactory extends AFRMISocketFactory {
 
   /**
    * Creates a new socket factory.
-   * 
+   *
    * @param naming The {@link AFNaming} instance to use.
    * @param socketDir The directory to store the sockets in.
    * @throws IOException on error.
@@ -164,7 +164,7 @@ public class AFUNIXRMISocketFactory extends AFRMISocketFactory {
 
   /**
    * The directory in which socket files are stored.
-   * 
+   *
    * @return The directory.
    */
   public File getSocketDir() {
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRegistry.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRegistry.java
index 7f94a60..f03defa 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRegistry.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/AFUNIXRegistry.java
@@ -23,9 +23,9 @@ import java.rmi.registry.Registry;
 /**
  * A wrapper for RMI registries, both remote and local, to allow for a clean removal of bound
  * resources upon shutdown.
- * 
+ *
  * This subclass mostly exists for backwards compatibility.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class AFUNIXRegistry extends AFRegistry {
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/DefaultRMIClientSocketFactory.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/DefaultRMIClientSocketFactory.java
index a7b3cb4..30377e7 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/DefaultRMIClientSocketFactory.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/DefaultRMIClientSocketFactory.java
@@ -22,12 +22,10 @@ import java.io.Serializable;
 import java.net.Socket;
 import java.rmi.server.RMIClientSocketFactory;
 
-import org.newsclub.net.unix.AFSocket;
-
 /**
  * An implementation of {@link RMIClientSocketFactory}.
- * 
- * @see AFRMISocketFactory where we deal with {@link AFSocket}s.
+ *
+ * @see AFRMISocketFactory
  */
 public final class DefaultRMIClientSocketFactory implements RMIClientSocketFactory, Serializable {
   private static final long serialVersionUID = 1L;
@@ -38,7 +36,7 @@ public final class DefaultRMIClientSocketFactory implements RMIClientSocketFacto
 
   /**
    * Returns the singleton instance for DefaultRMIClientSocketFactory.
-   * 
+   *
    * @return The singleton.
    */
   public static DefaultRMIClientSocketFactory getInstance() {
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/DefaultRMIServerSocketFactory.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/DefaultRMIServerSocketFactory.java
index 55c6887..db18690 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/DefaultRMIServerSocketFactory.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/DefaultRMIServerSocketFactory.java
@@ -22,12 +22,10 @@ import java.io.Serializable;
 import java.net.ServerSocket;
 import java.rmi.server.RMIServerSocketFactory;
 
-import org.newsclub.net.unix.AFSocket;
-
 /**
  * An implementation of {@link RMIServerSocketFactory}.
- * 
- * @see AFRMISocketFactory where we deal with {@link AFSocket}.
+ *
+ * @see AFRMISocketFactory
  */
 public class DefaultRMIServerSocketFactory implements RMIServerSocketFactory, Serializable {
   private static final long serialVersionUID = 1L;
@@ -42,7 +40,7 @@ public class DefaultRMIServerSocketFactory implements RMIServerSocketFactory, Se
 
   /**
    * Returns the singleton instance for DefaultRMIServerSocketFactory.
-   * 
+   *
    * @return The singleton.
    */
   public static DefaultRMIServerSocketFactory getInstance() {
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RMIPorts.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RMIPorts.java
index 246e302..e1dc0ae 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RMIPorts.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RMIPorts.java
@@ -23,7 +23,7 @@ import com.kohlschutter.annotations.compiletime.ExcludeFromCodeCoverageGenerated
 
 /**
  * Contains some default ports used by junixsocket for RMI-over-AF_UNIX etc.
- * 
+ *
  * @author Christian Kohlschütter
  * @see AFRMISocketFactory
  * @see AFRMIService
@@ -42,14 +42,14 @@ final class RMIPorts {
 
   /**
    * This is the port reserved for the port assigner.
-   * 
+   *
    * @see AFRMIService
    */
   static final int RMI_SERVICE_PORT = 100002;
 
   /**
    * This is the base for anonymous ports. Any anonymous port will be higher than this number.
-   * 
+   *
    * @see AFRMIService
    */
   static final int ANONYMOUS_PORT_BASE = 110000;
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteCloseable.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteCloseable.java
index 54aa9fc..960ab1b 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteCloseable.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteCloseable.java
@@ -24,17 +24,18 @@ import java.rmi.Remote;
 
 /**
  * A resource that can be exposed remotely, and closed locally as well as remotely.
- * 
+ *
  * @author Christian Kohlschütter
+ * @param <T> The resource type.
  */
 public interface RemoteCloseable<T> extends Remote, Closeable {
   /**
    * Returns the resource (or the Remote instance of it).
-   * 
+   *
    * If the returned resource is {@link Closeable}, then closing via {@code get().close()}} will
    * affect the client-side (local), but not necessarily the server-side as well (the exact behavior
    * depends on the resource).
-   * 
+   *
    * @return The wrapped resource.
    * @throws NoSuchObjectException if this instance has been closed already.
    * @throws IOException if there was a problem.
@@ -44,7 +45,7 @@ public interface RemoteCloseable<T> extends Remote, Closeable {
   /**
    * Closes the resource on the server-side (i.e., where it was created), and — as long as the
    * wrapped resource returned by {@link #get()} supports it — locally as well.
-   * 
+   *
    * @throws IOException if there was a problem.
    */
   @Override
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteCloseableImpl.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteCloseableImpl.java
index 2eb5814..5ffac44 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteCloseableImpl.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteCloseableImpl.java
@@ -27,13 +27,14 @@ import java.rmi.server.RMISocketFactory;
  *
  * @author Christian Kohlschütter
  * @see RemoteCloseable
+ * @param <T> The resource type.
  */
 public class RemoteCloseableImpl<T> implements RemoteCloseable<T> {
   private final T remote;
 
   /**
    * Created a new instance.
-   * 
+   *
    * @param socketFactory The socket factory.
    * @param obj The object to wrap.
    * @throws RemoteException on error.
@@ -51,7 +52,7 @@ public class RemoteCloseableImpl<T> implements RemoteCloseable<T> {
 
   /**
    * Closes the given object.
-   * 
+   *
    * @param obj The object to close.
    * @throws IOException on error.
    */
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptor.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptor.java
index 42406fe..7cc2e1e 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptor.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptor.java
@@ -24,7 +24,7 @@ import java.io.ObjectInput;
 
 /**
  * A generic (unspecific) {@link FileDescriptor} reference.
- * 
+ *
  * @author Christian Kohlschütter
  * @see RemoteFileInput
  * @see RemoteFileOutput
@@ -34,7 +34,7 @@ public final class RemoteFileDescriptor extends RemoteFileDescriptorBase<Void> {
 
   /**
    * Creates an uninitialized instance; used for externalization.
-   * 
+   *
    * @see #readExternal(ObjectInput)
    */
   public RemoteFileDescriptor() {
@@ -44,7 +44,7 @@ public final class RemoteFileDescriptor extends RemoteFileDescriptorBase<Void> {
   /**
    * Creates a new {@link RemoteFileOutput} instance, encapsulating a generic {@link FileDescriptor}
    * so that it can be shared with other processes via RMI.
-   * 
+   *
    * @param socketFactory The socket factory.
    * @param fd The {@link FileDescriptor}.
    */
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptorBase.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptorBase.java
index 32a4a12..32827f6 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptorBase.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileDescriptorBase.java
@@ -22,8 +22,6 @@ import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.Externalizable;
 import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.ObjectInput;
@@ -46,10 +44,11 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * A wrapper that allows a {@link FileDescriptor} be sent via RMI over AF_UNIX sockets.
- * 
+ *
  * @author Christian Kohlschütter
- * @see RemoteFileInput subclass for sending {@link FileInputStream}s.
- * @see RemoteFileOutput subclass for sending {@link FileOutputStream}s.
+ * @param <T> The resource type.
+ * @see RemoteFileInput
+ * @see RemoteFileOutput
  */
 public abstract class RemoteFileDescriptorBase<T> implements Externalizable, Closeable,
     FileDescriptorAccess {
@@ -75,7 +74,7 @@ public abstract class RemoteFileDescriptorBase<T> implements Externalizable, Clo
   /**
    * An optional, closeable resource that is related to this instance. If the reference is non-null,
    * this will be closed upon {@link #close()}.
-   * 
+   *
    * For unidirectional implementations, this could be the corresponding input/output stream. For
    * bidirectional implementations (e.g., a Socket, Pipe, etc.), this should close both directions.
    */
@@ -87,7 +86,7 @@ public abstract class RemoteFileDescriptorBase<T> implements Externalizable, Clo
 
   /**
    * Creates an uninitialized instance; used for externalization.
-   * 
+   *
    * @see #readExternal(ObjectInput)
    */
   RemoteFileDescriptorBase() {
@@ -223,10 +222,10 @@ public abstract class RemoteFileDescriptorBase<T> implements Externalizable, Clo
 
   /**
    * Returns the file descriptor.
-   * 
+   *
    * This is either the original one that was specified in the constructor or a copy that was sent
    * via RMI over an AF_UNIX connection as part of an ancillary message.
-   * 
+   *
    * @return The file descriptor.
    */
   @Override
@@ -237,11 +236,11 @@ public abstract class RemoteFileDescriptorBase<T> implements Externalizable, Clo
 
   /**
    * Returns the "magic value" for this type of file descriptor.
-   * 
+   *
    * The magic value consists of an indicator ("this is a file descriptor") as well as its
    * capabilities (read/write). It is used to prevent, for example, converting an output stream to
    * an input stream.
-   * 
+   *
    * @return The magic value.
    */
   protected final int getMagicValue() {
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileInput.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileInput.java
index bad662b..1042687 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileInput.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileInput.java
@@ -25,7 +25,7 @@ import java.io.ObjectInput;
 /**
  * A specialized subclass of {@link RemoteFileDescriptorBase}, specifically for
  * {@link FileInputStream}s.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class RemoteFileInput extends RemoteFileDescriptorBase<FileInputStream> implements
@@ -34,7 +34,7 @@ public final class RemoteFileInput extends RemoteFileDescriptorBase<FileInputStr
 
   /**
    * Creates an uninitialized instance; used for externalization.
-   * 
+   *
    * @see #readExternal(ObjectInput)
    */
   public RemoteFileInput() {
@@ -44,7 +44,7 @@ public final class RemoteFileInput extends RemoteFileDescriptorBase<FileInputStr
   /**
    * Creates a new {@link RemoteFileInput} instance, encapsulating a {@link FileInputStream} so that
    * it can be shared with other processes via RMI.
-   * 
+   *
    * @param socketFactory The socket factory.
    * @param fin The {@link FileInputStream}.
    * @throws IOException if the operation fails.
@@ -58,7 +58,7 @@ public final class RemoteFileInput extends RemoteFileDescriptorBase<FileInputStr
   /**
    * Returns a FileInputStream for the given instance. This either is the actual instance provided
    * by the constructor or a new instance created from the file descriptor.
-   * 
+   *
    * @return The FileInputStream.
    * @throws IOException if the operation fails.
    */
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileOutput.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileOutput.java
index 1198333..dab0def 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileOutput.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemoteFileOutput.java
@@ -25,7 +25,7 @@ import java.io.ObjectInput;
 /**
  * A specialized subclass of {@link RemoteFileDescriptorBase}, specifically for
  * {@link FileOutputStream}s.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class RemoteFileOutput extends RemoteFileDescriptorBase<FileOutputStream> {
@@ -33,7 +33,7 @@ public final class RemoteFileOutput extends RemoteFileDescriptorBase<FileOutputS
 
   /**
    * Creates an uninitialized instance; used for externalization.
-   * 
+   *
    * @see #readExternal(ObjectInput)
    */
   public RemoteFileOutput() {
@@ -43,7 +43,7 @@ public final class RemoteFileOutput extends RemoteFileDescriptorBase<FileOutputS
   /**
    * Creates a new {@link RemoteFileOutput} instance, encapsulating a {@link FileOutputStream} so
    * that it can be shared with other processes via RMI.
-   * 
+   *
    * @param socketFactory The socket factory.
    * @param fout The {@link FileOutputStream}.
    * @throws IOException if the operation fails.
@@ -57,7 +57,7 @@ public final class RemoteFileOutput extends RemoteFileDescriptorBase<FileOutputS
   /**
    * Returns a FileOutputStream for the given instance. This either is the actual instance provided
    * by the constructor or a new instance created from the file descriptor.
-   * 
+   *
    * @return The FileOutputStream.
    * @throws IOException if the operation fails.
    */
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemotePeerInfo.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemotePeerInfo.java
index 4b7a7b7..0ab724e 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemotePeerInfo.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/RemotePeerInfo.java
@@ -31,7 +31,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * Information about the remote connection.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class RemotePeerInfo {
@@ -45,7 +45,7 @@ public final class RemotePeerInfo {
 
   /**
    * The socket factory used to establish connections.
-   * 
+   *
    * @return The socket factory.
    */
   public RMISocketFactory getSocketFactory() {
@@ -54,7 +54,7 @@ public final class RemotePeerInfo {
 
   /**
    * The hostname.
-   * 
+   *
    * @return The hostname
    */
   public String getHost() {
@@ -63,7 +63,7 @@ public final class RemotePeerInfo {
 
   /**
    * The port.
-   * 
+   *
    * @return The port
    */
   public int getPort() {
@@ -72,7 +72,7 @@ public final class RemotePeerInfo {
 
   /**
    * The remote socket credentials, or {@code null} if they could not be retrieved.
-   * 
+   *
    * @return The peer credentials, or {@code null}.
    */
   @SuppressFBWarnings("EI_EXPOSE_REP")
@@ -94,7 +94,7 @@ public final class RemotePeerInfo {
   /**
    * Returns the {@link AFUNIXSocketCredentials} for the peer (server) of the given {@link Remote}
    * instance, or {@code null} if it was not possible to retrieve these credentials.
-   * 
+   *
    * @param obj The remote object.
    * @return The credentials, or {@code null} if unable to retrieve.
    * @throws IOException if an exception occurs.
@@ -107,9 +107,9 @@ public final class RemotePeerInfo {
    * Returns the connection information ({@link RMISocketFactory}, hostname and port) used for the
    * given {@link Remote} object, or {@code null} if no custom {@link RMISocketFactory} was
    * specified.
-   * 
+   *
    * An {@link IOException} may be thrown if we couldn't determine the socket factory.
-   * 
+   *
    * @param obj The remote object.
    * @return The factory, or {@code null}
    * @throws IOException if the operation fails.
@@ -145,10 +145,10 @@ public final class RemotePeerInfo {
   /**
    * Mimics a Serializer for RemoteRef.writeExternal, so we can extract the information we need
    * about the remote reference without having to break-open internal Java classes.
-   * 
+   *
    * NOTE: The format for the data we extract is assumed to be stable across JVM implementations,
    * otherwise RMI would probably not work.
-   * 
+   *
    * @author Christian Kohlschütter
    */
   static final class ExtractingObjectOutput implements ObjectOutput {
diff --git a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/ShutdownHookSupport.java b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/ShutdownHookSupport.java
index be4500b..f4c4bdb 100644
--- a/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/ShutdownHookSupport.java
+++ b/junixsocket-rmi/src/main/java/org/newsclub/net/unix/rmi/ShutdownHookSupport.java
@@ -25,7 +25,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * Simplifies handling shutdown hooks.
- * 
+ *
  * @author Christian Kohlschütter
  */
 final class ShutdownHookSupport {
@@ -34,9 +34,9 @@ final class ShutdownHookSupport {
 
   /**
    * Registers a shutdown hook to be executed upon Runtime shutdown.
-   * 
+   *
    * NOTE: Only a weak reference to the hook is stored.
-   * 
+   *
    * @param hook The hook to register.
    * @return The thread, to be used with #removeShutdownHook
    */
@@ -68,19 +68,19 @@ final class ShutdownHookSupport {
 
   /**
    * Something that wants to be called upon Runtime shutdown.
-   * 
+   *
    * @author Christian Kohlschütter
    */
   interface ShutdownHook {
     /**
      * Called upon Runtime shutdown.
-     * 
+     *
      * When you implement this method, make sure to check that the given Thread matches the current
      * thread, e.g.: <code>
      * if (thread != Thread.currentThread() || !(thread instanceof ShutdownThread)) {
      * throw new IllegalStateException("Illegal caller"); }
      * </code>
-     * 
+     *
      * @param thread The current Thread.
      * @throws Exception Most likely ignored
      */
@@ -90,7 +90,7 @@ final class ShutdownHookSupport {
 
   /**
    * The Thread that will be called upon Runtime shutdown.
-   * 
+   *
    * @author Christian Kohlschütter
    */
   static final class ShutdownThread extends Thread {
diff --git a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/Hello.java b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/Hello.java
index f8dca96..2af28e5 100644
--- a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/Hello.java
+++ b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/Hello.java
@@ -22,13 +22,13 @@ import java.rmi.Remote;
 
 /**
  * A very simple "hello" service.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public interface Hello extends Remote {
   /**
    * Returns "Hello".
-   * 
+   *
    * @return "Hello"
    * @throws IOException if the operation fails.
    */
diff --git a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/HelloImpl.java b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/HelloImpl.java
index 813f616..9d4b4e5 100644
--- a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/HelloImpl.java
+++ b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/HelloImpl.java
@@ -21,7 +21,7 @@ import java.io.IOException;
 
 /**
  * The implementation of the very simple {@link Hello} service.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class HelloImpl implements Hello {
diff --git a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/JunixsocketVersionTest.java b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/JunixsocketVersionTest.java
index b8c4092..1523247 100644
--- a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/JunixsocketVersionTest.java
+++ b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/JunixsocketVersionTest.java
@@ -25,10 +25,10 @@ import org.newsclub.net.unix.AFSocket;
 
 /**
  * Tests whether we can get the junixsocket version (which is encoded in a properties file).
- * 
+ *
  * This can't easily be tested from within the Maven build for junixsocket-common, which is why we
  * have it in junixsocket-rmi.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class JunixsocketVersionTest {
diff --git a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/NaiveFileInputStreamRemote.java b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/NaiveFileInputStreamRemote.java
index 57575f8..67bde46 100644
--- a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/NaiveFileInputStreamRemote.java
+++ b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/NaiveFileInputStreamRemote.java
@@ -25,10 +25,10 @@ import java.rmi.RemoteException;
 
 /**
  * Exposes a {@link FileInputStream}'s basic functionality over RMI.
- * 
+ *
  * As opposed to {@link RemoteFileDescriptorBase}, all data is read, then copied and serialized via
  * RMI.
- * 
+ *
  * @author Christian Kohlschütter
  * @see RemoteFileDescriptorBase for a better way.
  */
diff --git a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RMIPeerCredentialsTest.java b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RMIPeerCredentialsTest.java
index 5446de8..747dbb3 100644
--- a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RMIPeerCredentialsTest.java
+++ b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RMIPeerCredentialsTest.java
@@ -30,7 +30,7 @@ import org.newsclub.net.unix.AFUNIXSocketCredentials;
 
 /**
  * Verifies that peer credentials are properly set when communicating over RMI.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @AFSocketCapabilityRequirement({
diff --git a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RemoteCloseableTest.java b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RemoteCloseableTest.java
index 961aa72..0d520b6 100644
--- a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RemoteCloseableTest.java
+++ b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RemoteCloseableTest.java
@@ -35,7 +35,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * Tests {@link RemoteCloseable}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @SuppressFBWarnings({
diff --git a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RemoteCloseableThing.java b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RemoteCloseableThing.java
index 47b7e78..a5322e0 100644
--- a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RemoteCloseableThing.java
+++ b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RemoteCloseableThing.java
@@ -22,7 +22,7 @@ import java.io.Serializable;
 
 /**
  * To be used by {@link RemoteCloseableTest}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public interface RemoteCloseableThing extends Serializable {
diff --git a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RemoteCloseableThingImpl.java b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RemoteCloseableThingImpl.java
index a904ca4..68b6b10 100644
--- a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RemoteCloseableThingImpl.java
+++ b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/RemoteCloseableThingImpl.java
@@ -23,7 +23,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * To be used by {@link RemoteCloseableTest}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 abstract class RemoteCloseableThingImpl implements RemoteCloseableThing {
diff --git a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/SelftestProvider.java b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/SelftestProvider.java
index 263ce5b..46225cc 100644
--- a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/SelftestProvider.java
+++ b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/SelftestProvider.java
@@ -25,7 +25,7 @@ import java.util.Set;
 /**
  * Provides references to all "junixsocket-rmi" tests that should be included in
  * junixsocket-selftest.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class SelftestProvider {
diff --git a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/TestRegistryServer.java b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/TestRegistryServer.java
index ca636f5..498ebcf 100644
--- a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/TestRegistryServer.java
+++ b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/TestRegistryServer.java
@@ -28,9 +28,9 @@ import com.kohlschutter.util.SystemPropertyUtil;
 /**
  * A simple RMI Registry that is launched as forked Java VM from unit tests such as
  * {@link RemoteRegistryTest}.
- * 
+ *
  * Important: The server will terminate ca. 10 seconds after starting.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class TestRegistryServer {
diff --git a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/TestService.java b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/TestService.java
index 05fd713..7646219 100644
--- a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/TestService.java
+++ b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/TestService.java
@@ -24,7 +24,7 @@ import org.newsclub.net.unix.AFUNIXSocketCredentials;
 
 /**
  * A test service.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public interface TestService extends Remote {
diff --git a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/TestServiceImpl.java b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/TestServiceImpl.java
index c1d9d20..c17c994 100644
--- a/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/TestServiceImpl.java
+++ b/junixsocket-rmi/src/test/java/org/newsclub/net/unix/rmi/TestServiceImpl.java
@@ -37,7 +37,7 @@ import com.kohlschutter.util.IOUtil;
 
 /**
  * The implementation for the test service.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class TestServiceImpl implements TestService, Closeable {
diff --git a/junixsocket-rmi/src/test/java8/org/newsclub/net/unix/rmi/RemoteRegistryTest.java b/junixsocket-rmi/src/test/java8/org/newsclub/net/unix/rmi/RemoteRegistryTest.java
index b99e8d0..f01d1fb 100644
--- a/junixsocket-rmi/src/test/java8/org/newsclub/net/unix/rmi/RemoteRegistryTest.java
+++ b/junixsocket-rmi/src/test/java8/org/newsclub/net/unix/rmi/RemoteRegistryTest.java
@@ -1,7 +1,7 @@
 /*
  * junixsocket
  *
- * Copyright 2009-2021 Christian Kohlschütter
+ * Copyright 2009-2022 Christian Kohlschütter
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/junixsocket-selftest-native-image/pom.xml b/junixsocket-selftest-native-image/pom.xml
index 9effeca..7f38c6d 100644
--- a/junixsocket-selftest-native-image/pom.xml
+++ b/junixsocket-selftest-native-image/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-selftest-native-image</name>
@@ -51,7 +51,7 @@
                         <plugin>
                             <groupId>org.graalvm.buildtools</groupId>
                             <artifactId>native-maven-plugin</artifactId>
-                            <version>0.9.14</version>
+                            <version>0.9.19</version>
                         </plugin>
                     </plugins>
                 </pluginManagement>
diff --git a/junixsocket-selftest-native-image/src/main/java/org/newsclub/net/unix/selftest/nativeimage/Main.java b/junixsocket-selftest-native-image/src/main/java/org/newsclub/net/unix/selftest/nativeimage/Main.java
index c9c846e..c7a83ef 100644
--- a/junixsocket-selftest-native-image/src/main/java/org/newsclub/net/unix/selftest/nativeimage/Main.java
+++ b/junixsocket-selftest-native-image/src/main/java/org/newsclub/net/unix/selftest/nativeimage/Main.java
@@ -21,7 +21,7 @@ import org.newsclub.net.unix.selftest.Selftest;
 
 /**
  * Main entry.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class Main { // NOPMD
@@ -31,7 +31,7 @@ public final class Main { // NOPMD
 
   /**
    * Starts junixsocket-selftest.
-   * 
+   *
    * @param args The args.
    * @throws Exception on error.
    */
diff --git a/junixsocket-selftest/pom.xml b/junixsocket-selftest/pom.xml
index 1ebdc63..da51a84 100644
--- a/junixsocket-selftest/pom.xml
+++ b/junixsocket-selftest/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-selftest</name>
@@ -91,27 +91,6 @@
                         <groupId>org.apache.maven.plugins</groupId>
                         <artifactId>maven-resources-plugin</artifactId>
                         <executions>
-                            <execution>
-                                <id>copy-overlay-sources</id>
-                                <phase>generate-sources</phase>
-                                <goals>
-                                    <goal>copy-resources</goal>
-                                </goals>
-                                <configuration>
-                                    <outputDirectory>${project.build.directory}/sources-java9</outputDirectory>
-                                    <includeEmptyDirs>true</includeEmptyDirs>
-                                    <resources>
-                                        <resource>
-                                            <directory>${project.basedir}/src/main/java-overlay</directory>
-                                            <includes>
-                                                <include>**</include>
-                                            </includes>
-                                        </resource>
-                                    </resources>
-                                    <overwrite>true</overwrite>
-                                </configuration>
-                            </execution>
-
                             <execution>
                                 <id>copy-sources-from-junixsocket-java8</id>
                                 <phase>generate-sources</phase>
@@ -122,71 +101,95 @@
                                     <outputDirectory>${project.build.directory}/sources-java8</outputDirectory>
                                     <includeEmptyDirs>true</includeEmptyDirs>
                                     <resources>
-                                        <resource>
-                                            <directory>${project.basedir}/src/main/java-overlay</directory>
-                                            <includes>
-                                                <include>**</include>
-                                            </includes>
-                                        </resource>
                                         <resource>
                                             <directory>${project.parent.basedir}/junixsocket-common/src/main/java</directory>
                                             <includes>
                                                 <include>**</include>
                                             </includes>
+                                            <excludes>
+                                                <exclude>module-info.java</exclude>
+                                            </excludes>
                                         </resource>
                                         <resource>
                                             <directory>${project.parent.basedir}/junixsocket-common/src/main/java8</directory>
                                             <includes>
                                                 <include>**</include>
                                             </includes>
+                                            <excludes>
+                                                <exclude>module-info.java</exclude>
+                                            </excludes>
                                         </resource>
                                         <resource>
                                             <directory>${project.parent.basedir}/junixsocket-common/src/test/java</directory>
                                             <includes>
                                                 <include>**</include>
                                             </includes>
+                                            <excludes>
+                                                <exclude>module-info.java</exclude>
+                                            </excludes>
                                         </resource>
                                         <resource>
                                             <directory>${project.parent.basedir}/junixsocket-common/src/test/java8</directory>
                                             <includes>
                                                 <include>**</include>
                                             </includes>
+                                            <excludes>
+                                                <exclude>module-info.java</exclude>
+                                            </excludes>
                                         </resource>
                                         <resource>
                                             <directory>${project.parent.basedir}/junixsocket-tipc/src/test/java</directory>
                                             <includes>
                                                 <include>**</include>
                                             </includes>
+                                            <excludes>
+                                                <exclude>module-info.java</exclude>
+                                            </excludes>
                                         </resource>
                                         <resource>
                                             <directory>${project.parent.basedir}/junixsocket-tipc/src/test/java8</directory>
                                             <includes>
                                                 <include>**</include>
                                             </includes>
+                                            <excludes>
+                                                <exclude>module-info.java</exclude>
+                                            </excludes>
                                         </resource>
                                         <resource>
                                             <directory>${project.parent.basedir}/junixsocket-vsock/src/test/java</directory>
                                             <includes>
                                                 <include>**</include>
                                             </includes>
+                                            <excludes>
+                                                <exclude>module-info.java</exclude>
+                                            </excludes>
                                         </resource>
                                         <resource>
                                             <directory>${project.parent.basedir}/junixsocket-vsock/src/test/java8</directory>
                                             <includes>
                                                 <include>**</include>
                                             </includes>
+                                            <excludes>
+                                                <exclude>module-info.java</exclude>
+                                            </excludes>
                                         </resource>
                                         <resource>
                                             <directory>${project.parent.basedir}/junixsocket-rmi/src/test/java</directory>
                                             <includes>
                                                 <include>**</include>
                                             </includes>
+                                            <excludes>
+                                                <exclude>module-info.java</exclude>
+                                            </excludes>
                                         </resource>
                                         <resource>
                                             <directory>${project.parent.basedir}/junixsocket-rmi/src/test/java8</directory>
                                             <includes>
                                                 <include>**</include>
                                             </includes>
+                                            <excludes>
+                                                <exclude>module-info.java</exclude>
+                                            </excludes>
                                         </resource>
                                     </resources>
                                     <overwrite>true</overwrite>
diff --git a/junixsocket-selftest/src/main/java-overlay/org/newsclub/net/unix/selftest/SelftestProvider.java b/junixsocket-selftest/src/main/java-overlay/org/newsclub/net/unix/selftest/SelftestProvider.java
index e7dedf3..5aeedf5 100644
--- a/junixsocket-selftest/src/main/java-overlay/org/newsclub/net/unix/selftest/SelftestProvider.java
+++ b/junixsocket-selftest/src/main/java-overlay/org/newsclub/net/unix/selftest/SelftestProvider.java
@@ -1,6 +1,22 @@
+/*
+ * junixsocket
+ *
+ * Copyright 2009-2022 Christian Kohlschütter
+ *
+ * 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 org.newsclub.net.unix.selftest;
 
-import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
@@ -8,7 +24,7 @@ import java.util.HashSet;
 
 /**
  * Provides references to all tests that should be included in junixsocket-selftest.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class SelftestProvider {
diff --git a/junixsocket-selftest/src/main/java/org/newsclub/net/unix/selftest/Selftest.java b/junixsocket-selftest/src/main/java/org/newsclub/net/unix/selftest/Selftest.java
index 51eb15d..4460db3 100644
--- a/junixsocket-selftest/src/main/java/org/newsclub/net/unix/selftest/Selftest.java
+++ b/junixsocket-selftest/src/main/java/org/newsclub/net/unix/selftest/Selftest.java
@@ -63,12 +63,12 @@ import com.kohlschutter.util.SystemPropertyUtil;
 
 /**
  * Performs a series of self-tests.
- * 
+ *
  * Specifically, we run all unit tests of junixsocket-core and junixsocket-rmi.
- * 
+ *
  * NOTE: The Selftest will fail when run from within Eclipse due to test classes not being present.
  * Invoke via <code>java -jar junixsocket-selftest-...-jar-with-dependencies.jar</code>.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.CognitiveComplexity"})
@@ -124,7 +124,7 @@ public class Selftest {
   /**
    * maven-shade-plugin's minimizeJar isn't perfect, so we give it a little hint by adding static
    * references to classes that are otherwise only found via reflection.
-   * 
+   *
    * @author Christian Kohlschütter
    */
   @SuppressFBWarnings("UUF_UNUSED_FIELD")
@@ -162,9 +162,9 @@ public class Selftest {
 
   /**
    * Run this from the command line to ensure junixsocket works correctly on the target system.
-   * 
+   *
    * A zero error code indicates success.
-   * 
+   *
    * @param args Ignored.
    * @throws IOException on error.
    */
@@ -324,7 +324,7 @@ public class Selftest {
 
   /**
    * Checks if any test has failed so far.
-   * 
+   *
    * @return {@code true} if failed.
    */
   public boolean isFail() {
@@ -368,7 +368,7 @@ public class Selftest {
 
   /**
    * Dumps the results of the selftest.
-   * 
+   *
    */
   public void dumpResults() { // NOPMD
     if (modified) {
@@ -462,7 +462,7 @@ public class Selftest {
 
   /**
    * Runs the given test classes for the specified module.
-   * 
+   *
    * @param module The module name.
    * @param testClasses The test classes.
    */
diff --git a/junixsocket-selftest/src/main/java/org/newsclub/net/unix/selftest/SelftestProvider.java b/junixsocket-selftest/src/main/java/org/newsclub/net/unix/selftest/SelftestProvider.java
index dff5bb7..e4f3850 100644
--- a/junixsocket-selftest/src/main/java/org/newsclub/net/unix/selftest/SelftestProvider.java
+++ b/junixsocket-selftest/src/main/java/org/newsclub/net/unix/selftest/SelftestProvider.java
@@ -24,11 +24,11 @@ import java.util.Set;
 
 /**
  * Provides references to all tests that should be included in junixsocket-selftest.
- * 
+ *
  * Important: This is just a dummy implementation so we can properly develop in Eclipse. The actual
  * provider is in src/main/java-overlay/... and contains references to test classes from
  * junixsocket-common and junixsocket-rmi, which are otherwise not accessible from this artifact.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class SelftestProvider {
diff --git a/junixsocket-server/pom.xml b/junixsocket-server/pom.xml
index 3fa2869..49a6ecf 100644
--- a/junixsocket-server/pom.xml
+++ b/junixsocket-server/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-server</name>
diff --git a/junixsocket-server/src/main/java/org/newsclub/net/unix/server/AFSocketServer.java b/junixsocket-server/src/main/java/org/newsclub/net/unix/server/AFSocketServer.java
index 2fa7b29..4034453 100644
--- a/junixsocket-server/src/main/java/org/newsclub/net/unix/server/AFSocketServer.java
+++ b/junixsocket-server/src/main/java/org/newsclub/net/unix/server/AFSocketServer.java
@@ -27,14 +27,15 @@ import org.newsclub.net.unix.AFSocketAddress;
 
 /**
  * A base implementation for a simple, multi-threaded socket server using {@link AFSocket}s.
- * 
+ *
  * @author Christian Kohlschütter
+ * @param <A> The supported address type.
  */
 public abstract class AFSocketServer<A extends AFSocketAddress> extends
     SocketServer<A, AFSocket<? extends A>, AFServerSocket<? extends A>> {
   /**
    * Creates a server using the given, bound {@link ServerSocket}.
-   * 
+   *
    * @param serverSocket The server socket to use (must be bound).
    */
   public AFSocketServer(AFServerSocket<? extends A> serverSocket) {
@@ -43,7 +44,7 @@ public abstract class AFSocketServer<A extends AFSocketAddress> extends
 
   /**
    * Creates a server using the given {@link SocketAddress}.
-   * 
+   *
    * @param listenAddress The address to bind the socket on.
    */
   public AFSocketServer(A listenAddress) {
diff --git a/junixsocket-server/src/main/java/org/newsclub/net/unix/server/AFUNIXSocketServer.java b/junixsocket-server/src/main/java/org/newsclub/net/unix/server/AFUNIXSocketServer.java
index 5941e9d..edaca98 100644
--- a/junixsocket-server/src/main/java/org/newsclub/net/unix/server/AFUNIXSocketServer.java
+++ b/junixsocket-server/src/main/java/org/newsclub/net/unix/server/AFUNIXSocketServer.java
@@ -27,16 +27,16 @@ import org.newsclub.net.unix.AFSocketAddress;
 
 /**
  * A base implementation for a simple, multi-threaded socket server.
- * 
+ *
  * This class supports both AF_UNIX and "regular" sockets.
- * 
+ *
  * @author Christian Kohlschütter
  * @deprecated Use {@link SocketServer} or {@link AFSocketServer}
  */
 public abstract class AFUNIXSocketServer extends SocketServer<SocketAddress, Socket, ServerSocket> {
   /**
    * Creates a server using the given, bound {@link ServerSocket}.
-   * 
+   *
    * @param serverSocket The server socket to use (must be bound).
    */
   public AFUNIXSocketServer(ServerSocket serverSocket) {
@@ -45,7 +45,7 @@ public abstract class AFUNIXSocketServer extends SocketServer<SocketAddress, Soc
 
   /**
    * Creates a server using the given {@link SocketAddress}.
-   * 
+   *
    * @param listenAddress The address to bind the socket on.
    */
   public AFUNIXSocketServer(SocketAddress listenAddress) {
@@ -54,7 +54,7 @@ public abstract class AFUNIXSocketServer extends SocketServer<SocketAddress, Soc
 
   /**
    * Starts the server and waits until it is ready or had to shop due to an error.
-   * 
+   *
    * @param duration The duration wait.
    * @param unit The duration's time unit.
    * @return {@code true} if the server is ready to serve requests.
diff --git a/junixsocket-server/src/main/java/org/newsclub/net/unix/server/SocketServer.java b/junixsocket-server/src/main/java/org/newsclub/net/unix/server/SocketServer.java
index 7cea541..4479af7 100644
--- a/junixsocket-server/src/main/java/org/newsclub/net/unix/server/SocketServer.java
+++ b/junixsocket-server/src/main/java/org/newsclub/net/unix/server/SocketServer.java
@@ -43,9 +43,12 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * A base implementation for a simple, multi-threaded socket server.
- * 
+ *
  * @author Christian Kohlschütter
  * @see AFSocketServer
+ * @param <A> The supported address type.
+ * @param <S> The supported {@link Socket} type.
+ * @param <V> The supported {@link ServerSocket} type.
  */
 public abstract class SocketServer<A extends SocketAddress, S extends Socket, V extends ServerSocket> {
   private static final ScheduledExecutorService TIMEOUTS = Executors.newScheduledThreadPool(1);
@@ -70,7 +73,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Creates a server using the given, bound {@link ServerSocket}.
-   * 
+   *
    * @param serverSocket The server socket to use (must be bound).
    */
   @SuppressWarnings({"null", "unchecked"})
@@ -80,7 +83,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Creates a server using the given {@link SocketAddress}.
-   * 
+   *
    * @param listenAddress The address to bind the socket on.
    */
   @SuppressWarnings("null")
@@ -98,7 +101,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Returns the maximum number of concurrent connections.
-   * 
+   *
    * @return The maximum number of concurrent connections.
    */
   public int getMaxConcurrentConnections() {
@@ -107,7 +110,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Sets the maximum number of concurrent connections.
-   * 
+   *
    * @param maxConcurrentConnections The new maximum.
    */
   public void setMaxConcurrentConnections(int maxConcurrentConnections) {
@@ -119,7 +122,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Returns the server timeout (in milliseconds).
-   * 
+   *
    * @return The server timeout in milliseconds (0 = no timeout).
    */
   public int getServerTimeout() {
@@ -128,7 +131,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Sets the server timeout (in milliseconds).
-   * 
+   *
    * @param timeout The new timeout in milliseconds (0 = no timeout).
    */
   public void setServerTimeout(int timeout) {
@@ -142,7 +145,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Returns the socket timeout (in milliseconds).
-   * 
+   *
    * @return The socket timeout in milliseconds (0 = no timeout).
    */
   public int getSocketTimeout() {
@@ -151,7 +154,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Sets the socket timeout (in milliseconds).
-   * 
+   *
    * @param timeout The new timeout in milliseconds (0 = no timeout).
    */
   public void setSocketTimeout(int timeout) {
@@ -160,7 +163,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Returns the server-busy timeout (in milliseconds).
-   * 
+   *
    * @return The server-busy timeout in milliseconds (0 = no timeout).
    */
   public int getServerBusyTimeout() {
@@ -169,7 +172,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Sets the server-busy timeout (in milliseconds).
-   * 
+   *
    * @param timeout The new timeout in milliseconds (0 = no timeout).
    */
   public void setServerBusyTimeout(int timeout) {
@@ -178,7 +181,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Checks if the server is running.
-   * 
+   *
    * @return {@code true} if the server is alive.
    */
   public boolean isRunning() {
@@ -189,7 +192,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Checks if the server is running and accepting new connections.
-   * 
+   *
    * @return {@code true} if the server is alive and ready to accept new connections.
    */
   public boolean isReady() {
@@ -198,7 +201,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Starts the server, and returns immediately.
-   * 
+   *
    * @see #startAndWaitToBecomeReady(long, TimeUnit)
    */
   public void start() {
@@ -229,7 +232,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Starts the server and waits until it is ready or had to shop due to an error.
-   * 
+   *
    * @param duration The duration wait.
    * @param unit The duration's time unit.
    * @return {@code true} if the server is ready to serve requests.
@@ -253,7 +256,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Returns a new server socket.
-   * 
+   *
    * @return The new socket (an {@link AFServerSocket} if the listen address is an
    *         {@link AFSocketAddress}).
    * @throws IOException on error.
@@ -365,7 +368,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Stops the server.
-   * 
+   *
    * @throws IOException If there was an error.
    */
   @SuppressWarnings("null")
@@ -424,7 +427,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
   /**
    * Requests that the server will be stopped after the given time delay. If the server is not
    * started yet (and {@link #stop()} was not called yet, it will be started first.
-   * 
+   *
    * @param delay The delay.
    * @param unit The time unit for the delay.
    * @return A scheduled future that can be used to monitor progress / cancel the request. If there
@@ -460,7 +463,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Called when a socket is ready to be served.
-   * 
+   *
    * @param socket The socket to serve.
    * @throws IOException If there was an error.
    */
@@ -474,9 +477,9 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Called when the server has been bound to a socket.
-   * 
+   *
    * This is not called when you instantiated the server with a pre-bound socket.
-   * 
+   *
    * @param address The bound address.
    */
   protected void onServerBound(A address) {
@@ -484,7 +487,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Called when the server is ready to accept a new connection.
-   * 
+   *
    * @param activeCount The current number of active tasks (= serving sockets).
    */
   protected void onServerReady(int activeCount) {
@@ -492,10 +495,10 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Called when the server is busy / not ready to accept a new connection.
-   * 
+   *
    * The frequency on how often this method is called when the server is busy is determined by
    * {@link #getServerBusyTimeout()}.
-   * 
+   *
    * @param busyStartTime The time stamp since the server became busy.
    */
   protected void onServerBusy(long busyStartTime) {
@@ -503,7 +506,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Called when the server has been stopped.
-   * 
+   *
    * @param socket The server's socket that stopped.
    */
   protected void onServerStopped(V socket) {
@@ -511,7 +514,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Called when a socket gets submitted into the process queue.
-   * 
+   *
    * @param socket The socket.
    * @param submission The {@link Future} referencing the submission; it's "done" after the socket
    *          has been served.
@@ -527,7 +530,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Called when a {@link SocketException} was thrown during "accept".
-   * 
+   *
    * @param e The exception.
    */
   protected void onSocketExceptionDuringAccept(SocketException e) {
@@ -535,7 +538,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Called when a {@link SocketException} was thrown during "accept".
-   * 
+   *
    * @param socket The socket.
    * @param e The exception.
    */
@@ -544,7 +547,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Called before serving the socket.
-   * 
+   *
    * @param socket The socket.
    */
   protected void onBeforeServingSocket(S socket) {
@@ -552,7 +555,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Called when an exception was thrown while serving a socket.
-   * 
+   *
    * @param socket The socket.
    * @param e The exception.
    */
@@ -561,7 +564,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Called after the socket has been served.
-   * 
+   *
    * @param socket The socket.
    */
   protected void onAfterServingSocket(S socket) {
@@ -569,7 +572,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Called when an exception was thrown while listening on the server socket.
-   * 
+   *
    * @param e The exception.
    */
   protected void onListenException(Exception e) {
@@ -577,7 +580,7 @@ public abstract class SocketServer<A extends SocketAddress, S extends Socket, V
 
   /**
    * Returns the address the server listens to.
-   * 
+   *
    * @return The listen address.
    */
   protected @NonNull A getListenAddress() {
diff --git a/junixsocket-tipc/pom.xml b/junixsocket-tipc/pom.xml
index 2f7946e..24d90e3 100644
--- a/junixsocket-tipc/pom.xml
+++ b/junixsocket-tipc/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-tipc</name>
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCDatagramChannel.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCDatagramChannel.java
index 30aa460..b940f9a 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCDatagramChannel.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCDatagramChannel.java
@@ -26,7 +26,7 @@ import org.newsclub.net.unix.AFTIPCSocketAddress;
 
 /**
  * A {@link DatagramChannel} implementation that works with {@code AF_TIPC} sockets.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFTIPCDatagramChannel extends AFDatagramChannel<AFTIPCSocketAddress> implements
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCDatagramSocket.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCDatagramSocket.java
index e652792..728faf0 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCDatagramSocket.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCDatagramSocket.java
@@ -28,7 +28,7 @@ import org.newsclub.net.unix.AFTIPCSocketImplExtensions;
 
 /**
  * A {@link DatagramSocket} implementation that works with {@code AF_TIPC} sockets.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFTIPCDatagramSocket extends AFDatagramSocket<AFTIPCSocketAddress> implements
@@ -54,7 +54,7 @@ public final class AFTIPCDatagramSocket extends AFDatagramSocket<AFTIPCSocketAdd
   /**
    * Returns a new {@link AFTIPCDatagramSocket} instance, using the default
    * {@link AFSocketType#SOCK_DGRAM} socket type.
-   * 
+   *
    * @return The new instance.
    * @throws IOException on error.
    */
@@ -64,7 +64,7 @@ public final class AFTIPCDatagramSocket extends AFDatagramSocket<AFTIPCSocketAdd
 
   /**
    * Returns a new {@link AFTIPCDatagramSocket} instance for the given socket type.
-   * 
+   *
    * @param socketType The socket type.
    * @return The new instance.
    * @throws IOException on error.
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCDestName.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCDestName.java
index 1431f42..50e21ce 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCDestName.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCDestName.java
@@ -25,7 +25,7 @@ import org.newsclub.net.unix.AFTIPCSocketAddress.Scope;
 
 /**
  * The TIPC-specific DestName response that may be included as ancillary data.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFTIPCDestName implements Serializable {
@@ -47,7 +47,7 @@ public final class AFTIPCDestName implements Serializable {
 
   /**
    * Creates a new instance.
-   * 
+   *
    * @param type The "type" value.
    * @param lower The "lower" service range value (or the service "instance" if {@code lower} and
    *          {@code upper} are the same).
@@ -62,7 +62,7 @@ public final class AFTIPCDestName implements Serializable {
 
   /**
    * Returns the "type" value.
-   * 
+   *
    * @return The type.
    */
   public int getType() {
@@ -72,7 +72,7 @@ public final class AFTIPCDestName implements Serializable {
   /**
    * Returns the "lower" value of the service range (or the service "instance" if identical to the
    * upper value).
-   * 
+   *
    * @return The lower value.
    */
   public int getLower() {
@@ -82,7 +82,7 @@ public final class AFTIPCDestName implements Serializable {
   /**
    * Returns the "upper" value of the service range (or the service "instance" if identical to the
    * lower value).
-   * 
+   *
    * @return The upper value.
    */
   public int getUpper() {
@@ -91,7 +91,7 @@ public final class AFTIPCDestName implements Serializable {
 
   /**
    * Checks if this DestName describes a service range (as opposed to a service) address.
-   * 
+   *
    * @return {@code true} if the {@link #getLower()} value is different from the {@link #getUpper()}
    *         value.
    */
@@ -102,7 +102,7 @@ public final class AFTIPCDestName implements Serializable {
   /**
    * Converts this DestName to a proper {@link AFTIPCSocketAddress}, by using the given
    * {@link Scope} (which is otherwise not included).
-   * 
+   *
    * @param scope The scope to use.
    * @param alwaysRange If {@code true}, a service range address is even returned when a service
    *          address would suffice.
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCErrInfo.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCErrInfo.java
index 5488526..3a83fe9 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCErrInfo.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCErrInfo.java
@@ -26,7 +26,7 @@ import org.newsclub.net.unix.NamedInteger;
 
 /**
  * The TIPC-specific error info response that may be included as ancillary data.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFTIPCErrInfo implements Serializable {
@@ -44,7 +44,7 @@ public final class AFTIPCErrInfo implements Serializable {
 
   /**
    * Some TIPC error code.
-   * 
+   *
    * @author Christian Kohlschütter
    */
   @NonNullByDefault
@@ -100,7 +100,7 @@ public final class AFTIPCErrInfo implements Serializable {
 
     /**
      * Returns an {@link ErrorCode} instance given an integer.
-     * 
+     *
      * @param v The value.
      * @return The instance.
      */
@@ -111,7 +111,7 @@ public final class AFTIPCErrInfo implements Serializable {
 
   /**
    * Creates a new instance.
-   * 
+   *
    * @param errorCode The error code.
    * @param dataLength The length of the returned data.
    */
@@ -122,7 +122,7 @@ public final class AFTIPCErrInfo implements Serializable {
 
   /**
    * Returns the error code.
-   * 
+   *
    * @return The error code.
    */
   public ErrorCode getErrorCode() {
@@ -131,7 +131,7 @@ public final class AFTIPCErrInfo implements Serializable {
 
   /**
    * The length of the corresponding data.
-   * 
+   *
    * @return The length in bytes.
    */
   public int getDataLength() {
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCGroupRequest.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCGroupRequest.java
index c3048d2..dbc4f1e 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCGroupRequest.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCGroupRequest.java
@@ -25,7 +25,7 @@ import org.newsclub.net.unix.NamedIntegerBitmask;
 
 /**
  * A TIPC group request.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @NonNullByDefault
@@ -43,7 +43,7 @@ public final class AFTIPCGroupRequest {
 
   /**
    * Some flags used in the group request.
-   * 
+   *
    * @author Christian Kohlschütter
    */
   public static final class GroupRequestFlags extends NamedIntegerBitmask<GroupRequestFlags> {
@@ -75,7 +75,7 @@ public final class AFTIPCGroupRequest {
 
     /**
      * Returns a {@link GroupRequestFlags} instance given an integer value.
-     * 
+     *
      * @param v The value.
      * @return The instance.
      */
@@ -86,7 +86,7 @@ public final class AFTIPCGroupRequest {
     /**
      * Returns a {@link GroupRequestFlags} instance representing the combination of the given list
      * of {@link GroupRequestFlags} flags.
-     * 
+     *
      * @param flags The flags (zero or more values).
      * @return The instance.
      */
@@ -96,7 +96,7 @@ public final class AFTIPCGroupRequest {
 
     /**
      * Combines the given {@link GroupRequestFlags} instance with another one.
-     * 
+     *
      * @param other The other instance.
      * @return The combined instance.
      */
@@ -115,7 +115,7 @@ public final class AFTIPCGroupRequest {
 
   /**
    * Returns an {@link AFTIPCGroupRequest} instance using the given parameters.
-   * 
+   *
    * @param type The group type.
    * @param instance The group instance.
    * @param scope The group scope.
@@ -134,7 +134,7 @@ public final class AFTIPCGroupRequest {
   /**
    * Returns an {@link AFTIPCGroupRequest} instance using the given parameters, implying cluster
    * scope.
-   * 
+   *
    * @param type The group type.
    * @param instance The group instance.
    * @param flags The request flags.
@@ -150,7 +150,7 @@ public final class AFTIPCGroupRequest {
 
   /**
    * Returns the group type.
-   * 
+   *
    * @return The group type.
    */
   public int getType() {
@@ -159,7 +159,7 @@ public final class AFTIPCGroupRequest {
 
   /**
    * Returns the group instance.
-   * 
+   *
    * @return The group instance.
    */
   public int getInstance() {
@@ -168,7 +168,7 @@ public final class AFTIPCGroupRequest {
 
   /**
    * Returns the group scope.
-   * 
+   *
    * @return The group scope.
    */
   public Scope getScope() {
@@ -185,7 +185,7 @@ public final class AFTIPCGroupRequest {
 
   /**
    * Returns the group request flags.
-   * 
+   *
    * @return The group request flags.
    */
   public GroupRequestFlags getFlags() {
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCProtocolFamily.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCProtocolFamily.java
index 7221546..6251e32 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCProtocolFamily.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCProtocolFamily.java
@@ -21,7 +21,7 @@ import java.net.ProtocolFamily;
 
 /**
  * Describes the protocol families supported by junixsocket-tipc.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public enum AFTIPCProtocolFamily implements ProtocolFamily {
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSelectorProvider.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSelectorProvider.java
index e040071..e8d92b6 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSelectorProvider.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSelectorProvider.java
@@ -99,7 +99,7 @@ public final class AFTIPCSelectorProvider extends AFSelectorProvider<AFTIPCSocke
 
   /**
    * Returns the singleton instance.
-   * 
+   *
    * @return The instance.
    */
   @SuppressFBWarnings("MS_EXPOSE_REP")
@@ -109,7 +109,7 @@ public final class AFTIPCSelectorProvider extends AFSelectorProvider<AFTIPCSocke
 
   /**
    * Returns the singleton instance.
-   * 
+   *
    * @return The instance.
    */
   public static AFTIPCSelectorProvider provider() {
@@ -118,7 +118,7 @@ public final class AFTIPCSelectorProvider extends AFSelectorProvider<AFTIPCSocke
 
   /**
    * Constructs a new socket pair from two sockets.
-   * 
+   *
    * @param s1 Some socket, the first one.
    * @param s2 Some socket, the second one.
    * @return The pair.
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCServerSocket.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCServerSocket.java
index 98aaf1e..d95ebe1 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCServerSocket.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCServerSocket.java
@@ -30,7 +30,7 @@ import org.newsclub.net.unix.AFTIPCSocketAddress;
 
 /**
  * The server part of an {@code AF_TIPC} socket.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class AFTIPCServerSocket extends AFServerSocket<AFTIPCSocketAddress> {
@@ -50,7 +50,7 @@ public class AFTIPCServerSocket extends AFServerSocket<AFTIPCSocketAddress> {
 
   /**
    * Returns a new, unbound AF_TIPC {@link ServerSocket}.
-   * 
+   *
    * @return The new, unbound {@link AFServerSocket}.
    * @throws IOException if the operation fails.
    */
@@ -67,7 +67,7 @@ public class AFTIPCServerSocket extends AFServerSocket<AFTIPCSocketAddress> {
   /**
    * Returns a new AF_TIPC {@link ServerSocket} that is bound to the given
    * {@link AFTIPCSocketAddress}.
-   * 
+   *
    * @param addr The socket file to bind to.
    * @return The new, bound {@link AFServerSocket}.
    * @throws IOException if the operation fails.
@@ -78,7 +78,7 @@ public class AFTIPCServerSocket extends AFServerSocket<AFTIPCSocketAddress> {
 
   /**
    * Returns a new AF_TIPC {@link ServerSocket} that is bound to the given {@link AFSocketAddress}.
-   * 
+   *
    * @param addr The socket file to bind to.
    * @param deleteOnClose If {@code true}, the socket file (if the address points to a file) will be
    *          deleted upon {@link #close}.
@@ -93,7 +93,7 @@ public class AFTIPCServerSocket extends AFServerSocket<AFTIPCSocketAddress> {
   /**
    * Returns a new, <em>unbound</em> AF_TIPC {@link ServerSocket} that will always bind to the given
    * address, regardless of any socket address used in a call to <code>bind</code>.
-   * 
+   *
    * @param forceAddr The address to use.
    * @return The new, yet unbound {@link AFServerSocket}.
    * @throws IOException if an exception occurs.
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCServerSocketChannel.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCServerSocketChannel.java
index ddceca7..42527b4 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCServerSocketChannel.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCServerSocketChannel.java
@@ -24,7 +24,7 @@ import org.newsclub.net.unix.AFTIPCSocketAddress;
 
 /**
  * A selectable channel for stream-oriented listening sockets.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFTIPCServerSocketChannel extends AFServerSocketChannel<AFTIPCSocketAddress> {
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocket.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocket.java
index caea0b2..8c1bcbd 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocket.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocket.java
@@ -31,7 +31,7 @@ import org.newsclub.net.unix.AFTIPCSocketImplExtensions;
 
 /**
  * Implementation of an {@code AF_TIPC} socket.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFTIPCSocket extends AFSocket<AFTIPCSocketAddress> implements
@@ -56,13 +56,13 @@ public final class AFTIPCSocket extends AFSocket<AFTIPCSocketAddress> implements
   /**
    * Returns <code>true</code> iff {@link AFTIPCSocket}s (sockets of type "AF_TIPC") are supported
    * by the current Java VM and the kernel.
-   * 
+   *
    * To support {@link AFTIPCSocket}s, a custom JNI library must be loaded that is supplied with
    * <em>junixsocket</em>, and the system must support AF_TIPC sockets.
-   * 
+   *
    * This call is equivalent to checking {@link AFSocket#isSupported()} and
    * {@link AFSocket#supports(AFSocketCapability)} with {@link AFSocketCapability#CAPABILITY_TIPC}.
-   * 
+   *
    * @return {@code true} iff supported.
    */
   public static boolean isSupported() {
@@ -76,12 +76,12 @@ public final class AFTIPCSocket extends AFSocket<AFTIPCSocketAddress> implements
 
   /**
    * Creates a new, unbound {@link AFSocket}.
-   * 
+   *
    * This "default" implementation is a bit "lenient" with respect to the specification.
-   * 
+   *
    * In particular, we ignore calls to {@link Socket#getTcpNoDelay()} and
    * {@link Socket#setTcpNoDelay(boolean)}.
-   * 
+   *
    * @return A new, unbound socket.
    * @throws IOException if the operation fails.
    */
@@ -95,10 +95,10 @@ public final class AFTIPCSocket extends AFSocket<AFTIPCSocketAddress> implements
 
   /**
    * Creates a new, unbound, "strict" {@link AFSocket}.
-   * 
+   *
    * This call uses an implementation that tries to be closer to the specification than
    * {@link #newInstance()}, at least for some cases.
-   * 
+   *
    * @return A new, unbound socket.
    * @throws IOException if the operation fails.
    */
@@ -108,7 +108,7 @@ public final class AFTIPCSocket extends AFSocket<AFTIPCSocketAddress> implements
 
   /**
    * Creates a new {@link AFSocket} and connects it to the given {@link AFTIPCSocketAddress}.
-   * 
+   *
    * @param addr The address to connect to.
    * @return A new, connected socket.
    * @throws IOException if the operation fails.
@@ -124,9 +124,9 @@ public final class AFTIPCSocket extends AFSocket<AFTIPCSocketAddress> implements
 
   /**
    * Very basic self-test function.
-   * 
+   *
    * Prints "supported" and "capabilities" status to System.out.
-   * 
+   *
    * @param args ignored.
    */
   public static void main(String[] args) {
@@ -149,7 +149,7 @@ public final class AFTIPCSocket extends AFSocket<AFTIPCSocketAddress> implements
 
   /**
    * Retrieves the 16-byte node ID given a node hash.
-   * 
+   *
    * @param peerId The node hash.
    * @return The node ID, or {@code  null} if unsupported.
    * @throws IOException on error.
@@ -171,7 +171,7 @@ public final class AFTIPCSocket extends AFSocket<AFTIPCSocketAddress> implements
 
   /**
    * Retrieves the node ID given a node hash, as a hexadecimal string.
-   * 
+   *
    * @param peerId The node hash.
    * @return The node ID, or {@code  null} if unsupported.
    * @throws IOException on error.
@@ -183,7 +183,7 @@ public final class AFTIPCSocket extends AFSocket<AFTIPCSocketAddress> implements
 
   /**
    * Retrieves the link name given a node hash and a bearer ID.
-   * 
+   *
    * @param peerId The node hash.
    * @param bearerId The bearer Id.
    * @return The link name, or {@code  null} if unsupported.
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketChannel.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketChannel.java
index a48b807..70c1cea 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketChannel.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketChannel.java
@@ -22,7 +22,7 @@ import org.newsclub.net.unix.AFTIPCSocketAddress;
 
 /**
  * A selectable channel for stream-oriented connecting sockets.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFTIPCSocketChannel extends AFSocketChannel<AFTIPCSocketAddress> implements
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketExtensions.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketExtensions.java
index 8a08267..cfe0fec 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketExtensions.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketExtensions.java
@@ -22,14 +22,14 @@ import org.newsclub.net.unix.AFSocketExtensions;
 /**
  * Defines certain methods that all junixsocket AF_TIPC socket implementations share and extend
  * beyond the standard socket API.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public interface AFTIPCSocketExtensions extends AFSocketExtensions {
   /**
    * Returns the TIPC "ErrInfo" information from the ancillary receive buffer (if any was set), or
    * {@code null} if no error was retrieved.
-   * 
+   *
    * @return The ErrInfo.
    */
   AFTIPCErrInfo getErrInfo();
@@ -37,7 +37,7 @@ public interface AFTIPCSocketExtensions extends AFSocketExtensions {
   /**
    * Returns the TIPC "DestName" information from the ancillary receive buffer (if any was set), or
    * {@code null} if no DestName was retrieved.
-   * 
+   *
    * @return The service address or range (without scope) that was specified by the sender of the
    *         message.
    */
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketFactory.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketFactory.java
index 856a7ac..a275173 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketFactory.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketFactory.java
@@ -27,7 +27,7 @@ import org.newsclub.net.unix.AFTIPCSocketAddress.Scope;
 
 /**
  * The base for a SocketFactory that connects to TIPC sockets.
- * 
+ *
  * Typically, the "hostname" is used as a reference to a socketFile on the file system. The actual
  * mapping is left to the implementor.
  */
@@ -51,7 +51,7 @@ public abstract class AFTIPCSocketFactory extends AFSocketFactory<AFTIPCSocketAd
 
   /**
    * Performs some optional configuration on a newly created socket.
-   * 
+   *
    * @param sock The socket.
    * @return The very socket.
    * @throws SocketException on error.
@@ -62,7 +62,7 @@ public abstract class AFTIPCSocketFactory extends AFSocketFactory<AFTIPCSocketAd
 
   /**
    * Always connects sockets to the given TIPC type and instance.
-   * 
+   *
    * @author Christian Kohlschütter
    */
   public static class ServiceAddress extends AFTIPCSocketFactory {
@@ -72,7 +72,7 @@ public abstract class AFTIPCSocketFactory extends AFSocketFactory<AFTIPCSocketAd
     /**
      * Creates an {@link AFTIPCSocketFactory} that always uses the given TIPC service type and
      * instance, implying cluster scope.
-     * 
+     *
      * @param type The service type.
      * @param instance The service instance.
      */
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketOptions.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketOptions.java
index b6254a9..305b379 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketOptions.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketOptions.java
@@ -27,14 +27,14 @@ import org.newsclub.net.unix.NamedInteger;
 
 /**
  * TIPC-specific socket options.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @NonNullByDefault
 public final class AFTIPCSocketOptions {
   /**
    * Use as value for {@link SocketOption}s of type {@link Void}.
-   * 
+   *
    * @see #TIPC_GROUP_LEAVE
    */
   @SuppressWarnings({"null"})
@@ -44,7 +44,7 @@ public final class AFTIPCSocketOptions {
    * This option governs how likely a message sent by the socket is to be affected by congestion. A
    * message with higher importance is less likely to be delayed due to link congestion and less
    * likely to be rejected due to receiver congestion.
-   * 
+   *
    * @see MessageImportance
    */
   public static final AFSocketOption<MessageImportance> TIPC_IMPORTANCE = new AFSocketOption<>(
@@ -59,7 +59,7 @@ public final class AFTIPCSocketOptions {
   /**
    * This option governs the handling of a sent message if it cannot be delivered to its
    * destination. If set, the message is discarded; otherwise it is returned to the sender.
-   * 
+   *
    * By default, this option is enabled for SOCK_RDM and SOCK_DGRAM sockets, and disabled otherwise.
    */
   public static final AFSocketOption<Boolean> TIPC_DEST_DROPPABLE = new AFSocketOption<>(
@@ -106,7 +106,7 @@ public final class AFTIPCSocketOptions {
 
   /**
    * Leave the previously joined communication group.
-   * 
+   *
    * Only valid for setOption. The value is ignored. Use {@link #VOID}.
    */
   public static final AFSocketOption<Void> TIPC_GROUP_LEAVE = new AFSocketOption<>(
@@ -115,7 +115,7 @@ public final class AFTIPCSocketOptions {
   /**
    * When using TIPC_SOCK_RECVQ_DEPTH for getsockopt(), it returns the number of buffers in the
    * receive socket buffer which is not so helpful for user space applications.
-   * 
+   *
    * TIPC_SOCK_RECVQ_USED returns the current allocated bytes of the receive socket buffer. This
    * helps user space applications dimension its buffer usage to avoid buffer overload issue.
    */
@@ -135,9 +135,9 @@ public final class AFTIPCSocketOptions {
 
   /**
    * The TIPC message importance.
-   * 
+   *
    * Messages with a higher importance have a lower chance of being dropped when congestion occurs.
-   * 
+   *
    * @author Christian Kohlschütter
    */
   public static final class MessageImportance extends NamedInteger implements
@@ -182,7 +182,7 @@ public final class AFTIPCSocketOptions {
 
     /**
      * Returns a {@link MessageImportance} instance for the given value.
-     * 
+     *
      * @param v The value.
      * @return The instance.
      */
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketPair.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketPair.java
index 139170e..970abd2 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketPair.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCSocketPair.java
@@ -24,14 +24,14 @@ import org.newsclub.net.unix.AFSomeSocket;
 
 /**
  * A pair of sockets.
- * 
+ *
  * @param <T> The socket type.
  * @author Christian Kohlschütter
  */
 public final class AFTIPCSocketPair<T extends AFSomeSocket> extends AFSocketPair<T> {
   /**
    * Creates a new socket pair.
-   * 
+   *
    * @param socket1 The first socket.
    * @param socket2 The second socket.
    */
@@ -41,7 +41,7 @@ public final class AFTIPCSocketPair<T extends AFSomeSocket> extends AFSocketPair
 
   /**
    * Opens a socket pair of interconnected channels.
-   * 
+   *
    * @return The new channel pair.
    * @throws IOException on error.
    */
@@ -51,7 +51,7 @@ public final class AFTIPCSocketPair<T extends AFSomeSocket> extends AFSocketPair
 
   /**
    * Opens a socket pair of interconnected datagram channels.
-   * 
+   *
    * @return The new channel pair.
    * @throws IOException on error.
    */
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCTopologyEvent.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCTopologyEvent.java
index 3424515..6031860 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCTopologyEvent.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCTopologyEvent.java
@@ -36,7 +36,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 /**
  * A TIPC topology event received by the {@link AFTIPCTopologyWatcher} as a result of an
  * {@link AFTIPCTopologySubscription}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @NonNullByDefault
@@ -50,7 +50,7 @@ public final class AFTIPCTopologyEvent {
 
   /**
    * Some TIPC error code.
-   * 
+   *
    * @author Christian Kohlschütter
    */
   @SuppressWarnings("PMD.ShortClassName")
@@ -94,7 +94,7 @@ public final class AFTIPCTopologyEvent {
 
     /**
      * Returns an {@link Type} instance given an integer.
-     * 
+     *
      * @param v The value.
      * @return The instance.
      */
@@ -151,7 +151,7 @@ public final class AFTIPCTopologyEvent {
 
   /**
    * Converts this event message to a new {@link ByteBuffer}.
-   * 
+   *
    * @return The new buffer, ready to read from.
    * @throws IOException on error.
    */
@@ -162,7 +162,7 @@ public final class AFTIPCTopologyEvent {
 
   /**
    * The event type.
-   * 
+   *
    * @return The type.
    */
   public Type getType() {
@@ -171,7 +171,7 @@ public final class AFTIPCTopologyEvent {
 
   /**
    * The found range's lower value.
-   * 
+   *
    * @return The lower value.
    */
   public int getFoundLower() {
@@ -180,7 +180,7 @@ public final class AFTIPCTopologyEvent {
 
   /**
    * The found range's upper value.
-   * 
+   *
    * @return The upper value.
    */
   public int getFoundUpper() {
@@ -189,7 +189,7 @@ public final class AFTIPCTopologyEvent {
 
   /**
    * The corresponding socket address.
-   * 
+   *
    * @return The socket address.
    */
   @SuppressFBWarnings("EI_EXPOSE_REP")
@@ -199,7 +199,7 @@ public final class AFTIPCTopologyEvent {
 
   /**
    * The corresponding subscription that found this event.
-   * 
+   *
    * @return The subscription.
    */
   @SuppressFBWarnings("EI_EXPOSE_REP")
@@ -209,7 +209,7 @@ public final class AFTIPCTopologyEvent {
 
   /**
    * Returns {@code true} iff the event type is {@link Type#TIPC_PUBLISHED}.
-   * 
+   *
    * @return {@code true} if this a "published" event.
    */
   public boolean isPublished() {
@@ -218,7 +218,7 @@ public final class AFTIPCTopologyEvent {
 
   /**
    * Returns {@code true} iff the event type is {@link Type#TIPC_WITHDRAWN}.
-   * 
+   *
    * @return {@code true} if this a "withdrawn" event.
    */
   public boolean isWithdrawn() {
@@ -227,7 +227,7 @@ public final class AFTIPCTopologyEvent {
 
   /**
    * Returns {@code true} iff the event type is {@link Type#TIPC_SUBSCR_TIMEOUT}.
-   * 
+   *
    * @return {@code true} if this a "timeout" event.
    */
   public boolean isTimeout() {
@@ -237,7 +237,7 @@ public final class AFTIPCTopologyEvent {
   /**
    * Returns {@code true} iff the corresponding subscription has the
    * {@link AFTIPCTopologySubscription.Flags#TIPC_SUB_PORTS} flag set.
-   * 
+   *
    * @return {@code true} if this a event referring to a "port" subscription.
    */
   public boolean isPort() {
@@ -247,7 +247,7 @@ public final class AFTIPCTopologyEvent {
   /**
    * Returns {@code true} iff the corresponding subscription has the
    * {@link AFTIPCTopologySubscription.Flags#TIPC_SUB_SERVICE} flag set.
-   * 
+   *
    * @return {@code true} if this a event referring to a "service" subscription.
    */
   public boolean isService() {
@@ -257,7 +257,7 @@ public final class AFTIPCTopologyEvent {
   /**
    * Returns {@code true} iff the corresponding subscription has the
    * {@link AFTIPCTopologySubscription.Flags#TIPC_SUB_CANCEL} flag set.
-   * 
+   *
    * @return {@code true} if this a event referring to a "cancellation" subscription request.
    */
   public boolean isCancellationRequest() {
@@ -287,9 +287,9 @@ public final class AFTIPCTopologyEvent {
    * Returns the link name for a link state event requested by
    * {@link AFTIPCTopologySubscription#TIPC_LINK_STATE} or
    * {@link AFTIPCTopologyWatcher#addLinkStateSubscription()}.
-   * 
+   *
    * A link name is something like "f875a40e707d:eth0-8c1645f2ce27:eth0"
-   * 
+   *
    * @return The link name, or {@code  null} if unsupported.
    * @throws IOException on error.
    */
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCTopologySubscription.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCTopologySubscription.java
index 2cfa0db..4f3b401 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCTopologySubscription.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCTopologySubscription.java
@@ -34,7 +34,7 @@ import org.newsclub.net.unix.NamedIntegerBitmask;
 
 /**
  * An "event subscription" to be used with {@link AFTIPCTopologyWatcher}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @NonNullByDefault
@@ -51,7 +51,7 @@ public final class AFTIPCTopologySubscription {
 
   /**
    * The "node state" cluster topology monitor mode.
-   * 
+   *
    * When TIPC establishes contact with another node, it does internally create a binding {type =
    * TIPC_NODE_STATE, instance = peer node hash number} in the binding table. This makes it possible
    * for applications on a node to keep track of reachable peer nodes at any time. *
@@ -60,11 +60,11 @@ public final class AFTIPCTopologySubscription {
 
   /**
    * The "link state" cluster connectivity monitor mode.
-   * 
+   *
    * When TIPC establishes a new link to another node, it does internally create a binding {type =
    * TIPC_LINK_STATE, instance = peer node hash number} in the binding table. This makes it possible
    * for applications on a node to keep track of working links to peer nodes at any time.
-   * 
+   *
    * This type of binding differs from the topology subscription binding ({@link #TIPC_NODE_STATE})
    * in that there may be two links, and hence two bindings, to keep track of for each peer node.
    * Although this binding type only is published with node visibility, it is possible to combine it
@@ -120,7 +120,7 @@ public final class AFTIPCTopologySubscription {
 
     /**
      * Returns a {@link Flags} instance given an integer value.
-     * 
+     *
      * @param v The value.
      * @return The instance.
      */
@@ -131,7 +131,7 @@ public final class AFTIPCTopologySubscription {
     /**
      * Returns a {@link Flags} instance representing the combination of the given list of
      * {@link Flags} flags.
-     * 
+     *
      * @param flags The flags (zero or more values).
      * @return The instance.
      */
@@ -141,7 +141,7 @@ public final class AFTIPCTopologySubscription {
 
     /**
      * Combines the given {@link Flags} instance with another one.
-     * 
+     *
      * @param other The other instance.
      * @return The combined instance.
      */
@@ -153,7 +153,7 @@ public final class AFTIPCTopologySubscription {
 
   /**
    * Creates a new subscription message that does not time out.
-   * 
+   *
    * @param type The service type (any service, particularly {@link #TIPC_NODE_STATE} and
    *          {@link #TIPC_LINK_STATE}.
    * @param lower The lower instance.
@@ -166,7 +166,7 @@ public final class AFTIPCTopologySubscription {
 
   /**
    * Creates a new subscription message.
-   * 
+   *
    * @param type The service type (any service, particularly {@link #TIPC_NODE_STATE} and
    *          {@link #TIPC_LINK_STATE}.
    * @param lower The lower instance.
@@ -182,7 +182,7 @@ public final class AFTIPCTopologySubscription {
 
   /**
    * Creates a new subscription message.
-   * 
+   *
    * @param type The service type (any service, particularly {@link #TIPC_NODE_STATE} and
    *          {@link #TIPC_LINK_STATE}.
    * @param lower The lower instance.
@@ -244,7 +244,7 @@ public final class AFTIPCTopologySubscription {
 
   /**
    * Converts this subscription message to a new {@link ByteBuffer}.
-   * 
+   *
    * @return The new buffer, ready to read from.
    */
   @SuppressWarnings({"null", "cast"})
@@ -261,9 +261,9 @@ public final class AFTIPCTopologySubscription {
 
   /**
    * Creates an {@link AFTIPCTopologySubscription} that cancels this subscription.
-   * 
+   *
    * Note that a cancellation cannot be cancelled again.
-   * 
+   *
    * @return The new {@link AFTIPCTopologySubscription}.
    */
   public AFTIPCTopologySubscription toCancellation() {
@@ -295,7 +295,7 @@ public final class AFTIPCTopologySubscription {
 
   /**
    * Returns the service type.
-   * 
+   *
    * @return The type.
    */
   public int getType() {
@@ -304,7 +304,7 @@ public final class AFTIPCTopologySubscription {
 
   /**
    * Returns the lower instance value.
-   * 
+   *
    * @return The lower instance value.
    */
   public int getLower() {
@@ -313,7 +313,7 @@ public final class AFTIPCTopologySubscription {
 
   /**
    * Returns the upper instance value.
-   * 
+   *
    * @return The upper instance value.
    */
   public int getUpper() {
@@ -322,7 +322,7 @@ public final class AFTIPCTopologySubscription {
 
   /**
    * Returns the flags.
-   * 
+   *
    * @return The flags.
    */
   public Flags getFlags() {
@@ -331,7 +331,7 @@ public final class AFTIPCTopologySubscription {
 
   /**
    * Returns the timeout, in seconds (or {@link #TIPC_WAIT_FOREVER} for "never timeout").
-   * 
+   *
    * @return The timeout.
    */
   public int getTimeout() {
@@ -340,7 +340,7 @@ public final class AFTIPCTopologySubscription {
 
   /**
    * Returns the 8-byte user handle.
-   * 
+   *
    * @return The user handle.
    */
   public byte[] getUsrHandle() {
@@ -350,7 +350,7 @@ public final class AFTIPCTopologySubscription {
   /**
    * Returns {@code true} iff the subscription has the
    * {@link AFTIPCTopologySubscription.Flags#TIPC_SUB_PORTS} flag set.
-   * 
+   *
    * @return {@code true} if this is a "port" subscription.
    */
   public boolean isPort() {
@@ -360,7 +360,7 @@ public final class AFTIPCTopologySubscription {
   /**
    * Returns {@code true} iff the subscription has the
    * {@link AFTIPCTopologySubscription.Flags#TIPC_SUB_SERVICE} flag set.
-   * 
+   *
    * @return {@code true} if this is a "service" subscription.
    */
   public boolean isService() {
@@ -370,7 +370,7 @@ public final class AFTIPCTopologySubscription {
   /**
    * Returns {@code true} iff the subscription has the
    * {@link AFTIPCTopologySubscription.Flags#TIPC_SUB_CANCEL} flag set.
-   * 
+   *
    * @return {@code true} if this is a "cancellation" subscription request.
    */
   public boolean isCancellation() {
diff --git a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCTopologyWatcher.java b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCTopologyWatcher.java
index e5c58b5..9112dc3 100644
--- a/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCTopologyWatcher.java
+++ b/junixsocket-tipc/src/main/java/org/newsclub/net/unix/tipc/AFTIPCTopologyWatcher.java
@@ -29,7 +29,7 @@ import org.newsclub.net.unix.AFTIPCSocketAddress;
 
 /**
  * Provides access to the TIPC topology service.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class AFTIPCTopologyWatcher implements Closeable {
@@ -42,7 +42,7 @@ public class AFTIPCTopologyWatcher implements Closeable {
   /**
    * Creates an {@link AFTIPCTopologyWatcher} whose subscription requests do not time out by
    * default.
-   * 
+   *
    * @throws IOException on error.
    */
   public AFTIPCTopologyWatcher() throws IOException {
@@ -52,7 +52,7 @@ public class AFTIPCTopologyWatcher implements Closeable {
   /**
    * Creates an {@link AFTIPCTopologyWatcher} whose subscription requests use the given default
    * timeout.
-   * 
+   *
    * @param defaultTimeoutSeconds The timeout in seconds (or
    *          {@link AFTIPCTopologySubscription#TIPC_WAIT_FOREVER};
    * @throws IOException on error.
@@ -67,7 +67,7 @@ public class AFTIPCTopologyWatcher implements Closeable {
 
   /**
    * Watches for all port changes.
-   * 
+   *
    * @return The subscription object.
    * @throws IOException on error.
    * @see #cancelSubscription(AFTIPCTopologySubscription)
@@ -78,7 +78,7 @@ public class AFTIPCTopologyWatcher implements Closeable {
 
   /**
    * Watches for port changes of the given port ("port" meaning TIPC port, not TCP).
-   * 
+   *
    * @param port The port.
    * @return The subscription object.
    * @throws IOException on error.
@@ -90,7 +90,7 @@ public class AFTIPCTopologyWatcher implements Closeable {
 
   /**
    * Watches for port changes within the given range ("port" meaning TIPC port, not TCP).
-   * 
+   *
    * @param lower The lower value of the port range.
    * @param upper The upper value of the port range.
    * @return The subscription object.
@@ -106,7 +106,7 @@ public class AFTIPCTopologyWatcher implements Closeable {
 
   /**
    * Watches for all link state changes.
-   * 
+   *
    * @return The subscription object.
    * @throws IOException on error.
    * @see #cancelSubscription(AFTIPCTopologySubscription)
@@ -119,7 +119,7 @@ public class AFTIPCTopologyWatcher implements Closeable {
 
   /**
    * Watches for service changes of the given service type, matching any instance.
-   * 
+   *
    * @param type The service type.
    * @return The subscription object.
    * @throws IOException on error.
@@ -131,7 +131,7 @@ public class AFTIPCTopologyWatcher implements Closeable {
 
   /**
    * Watches for service changes of the given service type, matching only the specified instance.
-   * 
+   *
    * @param type The service type.
    * @param instance The instance to match.
    * @return The subscription object.
@@ -145,7 +145,7 @@ public class AFTIPCTopologyWatcher implements Closeable {
 
   /**
    * Watches for service changes of the given service type and instance range.
-   * 
+   *
    * @param type The service type.
    * @param lower The lower value of the instance range.
    * @param upper The upper value of the instance range.
@@ -162,7 +162,7 @@ public class AFTIPCTopologyWatcher implements Closeable {
 
   /**
    * Cancels a previously added service subscription.
-   * 
+   *
    * @param sub The subscription to cancel.
    * @throws IOException on error.
    */
@@ -175,7 +175,7 @@ public class AFTIPCTopologyWatcher implements Closeable {
    * need to do this directly; use the
    * {@code #addPortSubscription(int, int)}/{@link #cancelSubscription(AFTIPCTopologySubscription)}
    * methods instead.
-   * 
+   *
    * @param sub The subscription message.
    * @return The very message.
    * @throws IOException on error.
@@ -188,9 +188,9 @@ public class AFTIPCTopologyWatcher implements Closeable {
 
   /**
    * Runs a receive loop until {@link #stopLoop()} or {@link #close()} is called.
-   * 
+   *
    * This method returns after the run loop terminates.
-   * 
+   *
    * @throws IOException on error.
    */
   @SuppressWarnings("null")
@@ -225,7 +225,7 @@ public class AFTIPCTopologyWatcher implements Closeable {
 
   /**
    * Called for every event encountered by the run loop.
-   * 
+   *
    * @param event The event.
    * @throws IOException on error. Any exception will terminate the run loop.
    * @see #runLoop()
@@ -235,7 +235,7 @@ public class AFTIPCTopologyWatcher implements Closeable {
 
   /**
    * Called upon {@link #close()}.
-   * 
+   *
    * @throws IOException on error.
    */
   protected void onClose() throws IOException {
@@ -243,7 +243,7 @@ public class AFTIPCTopologyWatcher implements Closeable {
 
   /**
    * Checks if the watcher run loop is running.
-   * 
+   *
    * @return {@code true} if running.
    * @see #runLoop()
    */
diff --git a/junixsocket-tipc/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-tipc/jni-config.json b/junixsocket-tipc/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-tipc/jni-config.json
new file mode 100644
index 0000000..aa964b9
--- /dev/null
+++ b/junixsocket-tipc/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-tipc/jni-config.json
@@ -0,0 +1,27 @@
+[
+{
+  "name":"org.newsclub.net.unix.tipc.AFTIPCDatagramSocket"
+},
+{
+  "name":"org.newsclub.net.unix.tipc.AFTIPCDatagramSocketImpl"
+},
+{
+  "name":"org.newsclub.net.unix.tipc.AFTIPCSocket"
+},
+{
+  "name":"org.newsclub.net.unix.tipc.AFTIPCSocketImpl"
+},
+{
+  "name":"org.newsclub.net.unix.tipc.AFTIPCServerSocket"
+},
+{
+  "name":"org.newsclub.net.unix.tipc.AFTIPCGroupRequest",
+  "methods":[
+    {"name":"fromNative","parameterTypes":["int","int","int","int"] },
+    {"name":"getFlagsValue","parameterTypes":[] },
+    {"name":"getInstance","parameterTypes":[] },
+    {"name":"getScopeId","parameterTypes":[] },
+    {"name":"getType","parameterTypes":[] }
+  ]
+}
+]
diff --git a/junixsocket-tipc/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-tipc/reflect-config.json b/junixsocket-tipc/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-tipc/reflect-config.json
new file mode 100644
index 0000000..3752b00
--- /dev/null
+++ b/junixsocket-tipc/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-tipc/reflect-config.json
@@ -0,0 +1,9 @@
+[
+{
+  "name":"org.newsclub.net.unix.tipc.AFTIPCSelectorProvider"
+},
+{
+  "name":"org.newsclub.net.unix.tipc.AFTIPCSocketOptions$MessageImportance",
+  "methods":[{"name":"ofValue","parameterTypes":["int"] }]
+}
+]
\ No newline at end of file
diff --git a/junixsocket-tipc/src/test/java/org/newsclub/net/unix/tipc/SelftestProvider.java b/junixsocket-tipc/src/test/java/org/newsclub/net/unix/tipc/SelftestProvider.java
index deed749..b7dad98 100644
--- a/junixsocket-tipc/src/test/java/org/newsclub/net/unix/tipc/SelftestProvider.java
+++ b/junixsocket-tipc/src/test/java/org/newsclub/net/unix/tipc/SelftestProvider.java
@@ -29,7 +29,7 @@ import org.newsclub.net.unix.SocketTestBase;
 /**
  * Provides references to all "junixsocket-tipc" tests that should be included in
  * junixsocket-selftest.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @SuppressWarnings("PMD.CouplingBetweenObjects")
diff --git a/junixsocket-tipc/src/test/java/org/newsclub/net/unix/tipc/SocketOptionsTest.java b/junixsocket-tipc/src/test/java/org/newsclub/net/unix/tipc/SocketOptionsTest.java
index 40660f2..0e5a151 100644
--- a/junixsocket-tipc/src/test/java/org/newsclub/net/unix/tipc/SocketOptionsTest.java
+++ b/junixsocket-tipc/src/test/java/org/newsclub/net/unix/tipc/SocketOptionsTest.java
@@ -23,7 +23,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assumptions.assumeTrue;
 
 import java.io.IOException;
-import java.net.DatagramSocket;
 import java.net.NoRouteToHostException;
 import java.net.Socket;
 import java.net.SocketException;
@@ -87,9 +86,9 @@ public final class SocketOptionsTest extends
 
   @Test
   public void testTIPCSourceDroppable() throws Exception {
-    DatagramSocket socket = newDatagramSocket();
+    // NOTE: casting to work around GraalVM issue
+    AFTIPCDatagramSocket socket = (AFTIPCDatagramSocket) newDatagramSocket();
 
-    @SuppressWarnings("null")
     boolean droppable = socket.getOption(AFTIPCSocketOptions.TIPC_SRC_DROPPABLE);
     assertTrue(droppable, "Datagram messages should be droppable by default");
 
@@ -99,9 +98,9 @@ public final class SocketOptionsTest extends
 
   @Test
   public void testTIPCDestDroppable() throws Exception {
-    DatagramSocket socket = newDatagramSocket();
+    // NOTE: casting to work around GraalVM issue
+    AFTIPCDatagramSocket socket = (AFTIPCDatagramSocket) newDatagramSocket();
 
-    @SuppressWarnings("null")
     boolean droppable = socket.getOption(AFTIPCSocketOptions.TIPC_DEST_DROPPABLE);
     assertTrue(droppable, "Datagram messages should be droppable by default");
 
diff --git a/junixsocket-tipc/src/test/java/org/newsclub/net/unix/tipc/SocketTest.java b/junixsocket-tipc/src/test/java/org/newsclub/net/unix/tipc/SocketTest.java
index ad5d9b8..e1af5a6 100644
--- a/junixsocket-tipc/src/test/java/org/newsclub/net/unix/tipc/SocketTest.java
+++ b/junixsocket-tipc/src/test/java/org/newsclub/net/unix/tipc/SocketTest.java
@@ -28,7 +28,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * Tests some otherwise uncovered methods of {@link AFTIPCSocket}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @AFSocketCapabilityRequirement(AFSocketCapability.CAPABILITY_TIPC)
diff --git a/junixsocket-tipc/src/test/java8/org/newsclub/net/unix/tipc/SocketOptionsTest.java b/junixsocket-tipc/src/test/java8/org/newsclub/net/unix/tipc/SocketOptionsTest.java
index 765e9e0..6de9f6a 100644
--- a/junixsocket-tipc/src/test/java8/org/newsclub/net/unix/tipc/SocketOptionsTest.java
+++ b/junixsocket-tipc/src/test/java8/org/newsclub/net/unix/tipc/SocketOptionsTest.java
@@ -1,7 +1,7 @@
 /*
  * junixsocket
  *
- * Copyright 2009-2021 Christian Kohlschütter
+ * Copyright 2009-2022 Christian Kohlschütter
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/junixsocket-vsock/pom.xml b/junixsocket-vsock/pom.xml
index 0099ae2..66bae68 100644
--- a/junixsocket-vsock/pom.xml
+++ b/junixsocket-vsock/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.kohlschutter.junixsocket</groupId>
         <artifactId>junixsocket</artifactId>
-        <version>2.6.1</version>
+        <version>2.6.2</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
     <name>junixsocket-vsock</name>
diff --git a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKDatagramChannel.java b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKDatagramChannel.java
index e099f52..9d5f184 100644
--- a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKDatagramChannel.java
+++ b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKDatagramChannel.java
@@ -26,7 +26,7 @@ import org.newsclub.net.unix.AFVSOCKSocketAddress;
 
 /**
  * A {@link DatagramChannel} implementation that works with {@code AF_VSOCK} sockets.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFVSOCKDatagramChannel extends AFDatagramChannel<AFVSOCKSocketAddress> implements
diff --git a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKDatagramSocket.java b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKDatagramSocket.java
index f996838..2a6ad14 100644
--- a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKDatagramSocket.java
+++ b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKDatagramSocket.java
@@ -27,7 +27,7 @@ import org.newsclub.net.unix.AFVSOCKSocketAddress;
 
 /**
  * A {@link DatagramSocket} implementation that works with {@code AF_VSOCK} sockets.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFVSOCKDatagramSocket extends AFDatagramSocket<AFVSOCKSocketAddress> implements
@@ -53,7 +53,7 @@ public final class AFVSOCKDatagramSocket extends AFDatagramSocket<AFVSOCKSocketA
   /**
    * Returns a new {@link AFVSOCKDatagramSocket} instance, using the default
    * {@link AFSocketType#SOCK_DGRAM} socket type.
-   * 
+   *
    * @return The new instance.
    * @throws IOException on error.
    */
@@ -63,7 +63,7 @@ public final class AFVSOCKDatagramSocket extends AFDatagramSocket<AFVSOCKSocketA
 
   /**
    * Returns a new {@link AFVSOCKDatagramSocket} instance for the given socket type.
-   * 
+   *
    * @param socketType The socket type.
    * @return The new instance.
    * @throws IOException on error.
diff --git a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKProtocolFamily.java b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKProtocolFamily.java
index cc1531d..75aa818 100644
--- a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKProtocolFamily.java
+++ b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKProtocolFamily.java
@@ -21,7 +21,7 @@ import java.net.ProtocolFamily;
 
 /**
  * Describes the protocol families supported by junixsocket-vsock.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public enum AFVSOCKProtocolFamily implements ProtocolFamily {
diff --git a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKProxyServerSocketConnector.java b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKProxyServerSocketConnector.java
new file mode 100644
index 0000000..8e5672b
--- /dev/null
+++ b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKProxyServerSocketConnector.java
@@ -0,0 +1,94 @@
+/*
+ * junixsocket
+ *
+ * Copyright 2009-2022 Christian Kohlschütter
+ *
+ * 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 org.newsclub.net.unix.vsock;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.newsclub.net.unix.AFServerSocket;
+import org.newsclub.net.unix.AFServerSocketConnector;
+import org.newsclub.net.unix.AFSocketAddress;
+import org.newsclub.net.unix.AFUNIXSocketAddress;
+import org.newsclub.net.unix.AFVSOCKSocketAddress;
+import org.newsclub.net.unix.AddressUnavailableSocketException;
+
+/**
+ * Provides access to AF_VSOCK connections that aren't directly accessible but exposed via a
+ * proxying/multiplexing Unix domain socket.
+ *
+ * @author Christian Kohlschütter
+ * @see #openFirecrackerStyleConnector(File, int)
+ * @see #openDirectConnector()
+ */
+public final class AFVSOCKProxyServerSocketConnector implements
+    AFServerSocketConnector<AFVSOCKSocketAddress, AFSocketAddress> {
+  private static final AFServerSocketConnector<AFVSOCKSocketAddress, AFSocketAddress> DIRECT_CONNECTOR =
+      new AFServerSocketConnector<AFVSOCKSocketAddress, AFSocketAddress>() {
+
+        @Override
+        public AFServerSocket<? extends AFSocketAddress> bind(AFVSOCKSocketAddress addr)
+            throws IOException {
+          return addr.newForceBoundServerSocket();
+        }
+      };
+
+  private final String listenAddressPrefix;
+  private final int allowedCID;
+
+  private AFVSOCKProxyServerSocketConnector(String listenAddressPrefix, int allowedCID) {
+    this.listenAddressPrefix = listenAddressPrefix;
+    this.allowedCID = allowedCID;
+  }
+
+  /**
+   * Returns an instance that is configured to support
+   * [Firecracker-style](https://github.com/firecracker-microvm/firecracker/blob/main/docs/vsock.md)
+   * Unix domain sockets.
+   *
+   * @param listenAddressPrefix The prefix of any listening socket. The actual socket will have
+   *          <code>_<em>vsockPort</em></code> appended to it (with {@code vsockPort} being replaced
+   *          by the corresponding port number).
+   * @param allowedCID The permitted CID, or {@link AFVSOCKSocketAddress#VMADDR_CID_ANY} for "any".
+   * @return The instance.
+   */
+  public static AFServerSocketConnector<AFVSOCKSocketAddress, AFSocketAddress> openFirecrackerStyleConnector(
+      File listenAddressPrefix, int allowedCID) {
+    return new AFVSOCKProxyServerSocketConnector(listenAddressPrefix.getAbsolutePath(), allowedCID);
+  }
+
+  /**
+   * Returns an instance that is configured to connect directly to the given address.
+   *
+   * @return The direct instance.
+   */
+  public static AFServerSocketConnector<AFVSOCKSocketAddress, AFSocketAddress> openDirectConnector() {
+    return DIRECT_CONNECTOR;
+  }
+
+  @Override
+  public AFServerSocket<?> bind(AFVSOCKSocketAddress addr) throws IOException {
+    int cid = addr.getVSOCKCID();
+    if (cid != allowedCID && cid != AFVSOCKSocketAddress.VMADDR_CID_ANY
+        && allowedCID != AFVSOCKSocketAddress.VMADDR_CID_ANY) {
+      throw new AddressUnavailableSocketException("Factory does not cover CID " + cid);
+    }
+
+    return AFUNIXSocketAddress.of(new File(listenAddressPrefix + "_" + addr.getVSOCKPort()))
+        .newForceBoundServerSocket();
+  }
+}
diff --git a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKProxySocketConnector.java b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKProxySocketConnector.java
new file mode 100644
index 0000000..6ab6be9
--- /dev/null
+++ b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKProxySocketConnector.java
@@ -0,0 +1,145 @@
+/*
+ * junixsocket
+ *
+ * Copyright 2009-2022 Christian Kohlschütter
+ *
+ * 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 org.newsclub.net.unix.vsock;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.SocketException;
+import java.nio.charset.StandardCharsets;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.newsclub.net.unix.AFSocket;
+import org.newsclub.net.unix.AFSocketAddress;
+import org.newsclub.net.unix.AFSocketConnector;
+import org.newsclub.net.unix.AFUNIXSocket;
+import org.newsclub.net.unix.AFUNIXSocketAddress;
+import org.newsclub.net.unix.AFVSOCKSocketAddress;
+import org.newsclub.net.unix.AddressUnavailableSocketException;
+
+/**
+ * Provides access to AF_VSOCK connections that aren't directly accessible but exposed via a
+ * proxying/multiplexing Unix domain socket.
+ *
+ * @author Christian Kohlschütter
+ * @see #openFirecrackerStyleConnector(AFUNIXSocketAddress, int)
+ * @see #openDirectConnector()
+ */
+public final class AFVSOCKProxySocketConnector implements
+    AFSocketConnector<AFVSOCKSocketAddress, AFSocketAddress> {
+  private static final AFSocketConnector<AFVSOCKSocketAddress, AFSocketAddress> DIRECT_CONNECTOR =
+      new AFSocketConnector<AFVSOCKSocketAddress, AFSocketAddress>() {
+
+        @Override
+        public AFSocket<? extends AFSocketAddress> connect(AFVSOCKSocketAddress addr)
+            throws IOException {
+          return addr.newConnectedSocket();
+        }
+      };
+
+  private static final Pattern PAT_OK = Pattern.compile("OK ([0-9]+)");
+  private static final byte[] OK = {'O', 'K', ' '};
+  private final AFUNIXSocketAddress connectorAddress;
+  private final int allowedCID;
+
+  private AFVSOCKProxySocketConnector(AFUNIXSocketAddress connectorAddress, int allowedCID) {
+    this.connectorAddress = connectorAddress;
+    this.allowedCID = allowedCID;
+  }
+
+  /**
+   * Returns an instance that is configured to support
+   * [Firecracker-style](https://github.com/firecracker-microvm/firecracker/blob/main/docs/vsock.md)
+   * Unix domain sockets.
+   *
+   * @param connectorAddress The unix socket address pointing at the Firecracker-style multiplexing
+   *          domain socket.
+   * @param allowedCID The permitted CID, or {@link AFVSOCKSocketAddress#VMADDR_CID_ANY} for "any".
+   * @return The instance.
+   */
+  public static AFSocketConnector<AFVSOCKSocketAddress, AFSocketAddress> openFirecrackerStyleConnector(
+      AFUNIXSocketAddress connectorAddress, int allowedCID) {
+    return new AFVSOCKProxySocketConnector(connectorAddress, allowedCID);
+  }
+
+  /**
+   * Returns an instance that is configured to connect directly to the given address.
+   *
+   * @return The direct instance.
+   */
+  public static AFSocketConnector<AFVSOCKSocketAddress, AFSocketAddress> openDirectConnector() {
+    return DIRECT_CONNECTOR;
+  }
+
+  /**
+   * Connects to the given AF_VSOCK address.
+   *
+   * @param vsockAddress The address to connect to.
+   * @return The connected socket.
+   * @throws IOException on error.
+   * @throws AddressUnavailableSocketException if the CID is not covered by this connector.
+   */
+  @Override
+  public AFSocket<?> connect(AFVSOCKSocketAddress vsockAddress) throws IOException {
+    int cid = vsockAddress.getVSOCKCID();
+    if (cid != allowedCID && cid != AFVSOCKSocketAddress.VMADDR_CID_ANY
+        && allowedCID != AFVSOCKSocketAddress.VMADDR_CID_ANY) {
+      throw new AddressUnavailableSocketException("Connector does not cover CID " + cid);
+    }
+
+    @SuppressWarnings("resource")
+    AFUNIXSocket sock = connectorAddress.newConnectedSocket();
+    InputStream in = sock.getInputStream();
+    OutputStream out = sock.getOutputStream();
+
+    boolean success = false;
+
+    try { // NOPMD.UseTryWithResources
+      String connectLine = "CONNECT " + vsockAddress.getVSOCKPort() + "\n";
+      out.write(connectLine.getBytes(StandardCharsets.ISO_8859_1));
+
+      byte[] buf = new byte[16];
+      int b;
+      int i = 0;
+      while ((b = in.read()) != -1 && b != '\n' && i < buf.length) {
+        buf[i] = (byte) b;
+        if (i < 3) {
+          if (OK[i] != b) {
+            break;
+          }
+        }
+        i++;
+      }
+      if (b == '\n' && i > 3) {
+        Matcher m = PAT_OK.matcher(new String(buf, 0, i, StandardCharsets.ISO_8859_1));
+        if (m.matches()) {
+          /* int hostPort = */ Integer.parseInt(m.group(1));
+          success = true;
+        }
+      }
+    } finally { // NOPMD.DoNotThrowExceptionInFinally
+      if (!success) {
+        sock.close();
+        throw new SocketException("Unexpected response from proxy socket");
+      }
+    }
+
+    return sock;
+  }
+}
diff --git a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSelectorProvider.java b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSelectorProvider.java
index 82f450f..6fb5a87 100644
--- a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSelectorProvider.java
+++ b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSelectorProvider.java
@@ -99,7 +99,7 @@ public final class AFVSOCKSelectorProvider extends AFSelectorProvider<AFVSOCKSoc
 
   /**
    * Returns the singleton instance.
-   * 
+   *
    * @return The instance.
    */
   @SuppressFBWarnings("MS_EXPOSE_REP")
@@ -109,7 +109,7 @@ public final class AFVSOCKSelectorProvider extends AFSelectorProvider<AFVSOCKSoc
 
   /**
    * Returns the singleton instance.
-   * 
+   *
    * @return The instance.
    */
   public static AFVSOCKSelectorProvider provider() {
@@ -118,7 +118,7 @@ public final class AFVSOCKSelectorProvider extends AFSelectorProvider<AFVSOCKSoc
 
   /**
    * Constructs a new socket pair from two sockets.
-   * 
+   *
    * @param s1 Some socket, the first one.
    * @param s2 Some socket, the second one.
    * @return The pair.
diff --git a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKServerSocket.java b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKServerSocket.java
index 01e2043..defd2da 100644
--- a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKServerSocket.java
+++ b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKServerSocket.java
@@ -30,7 +30,7 @@ import org.newsclub.net.unix.AFVSOCKSocketAddress;
 
 /**
  * The server part of an {@code AF_VSOCK} socket.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public class AFVSOCKServerSocket extends AFServerSocket<AFVSOCKSocketAddress> {
@@ -50,7 +50,7 @@ public class AFVSOCKServerSocket extends AFServerSocket<AFVSOCKSocketAddress> {
 
   /**
    * Returns a new, unbound AF_VSOCK {@link ServerSocket}.
-   * 
+   *
    * @return The new, unbound {@link AFServerSocket}.
    * @throws IOException if the operation fails.
    */
@@ -67,7 +67,7 @@ public class AFVSOCKServerSocket extends AFServerSocket<AFVSOCKSocketAddress> {
   /**
    * Returns a new AF_VSOCK {@link ServerSocket} that is bound to the given
    * {@link AFVSOCKSocketAddress}.
-   * 
+   *
    * @param addr The socket file to bind to.
    * @return The new, bound {@link AFServerSocket}.
    * @throws IOException if the operation fails.
@@ -78,7 +78,7 @@ public class AFVSOCKServerSocket extends AFServerSocket<AFVSOCKSocketAddress> {
 
   /**
    * Returns a new AF_VSOCK {@link ServerSocket} that is bound to the given {@link AFSocketAddress}.
-   * 
+   *
    * @param addr The socket file to bind to.
    * @param deleteOnClose If {@code true}, the socket file (if the address points to a file) will be
    *          deleted upon {@link #close}.
@@ -94,7 +94,7 @@ public class AFVSOCKServerSocket extends AFServerSocket<AFVSOCKSocketAddress> {
   /**
    * Returns a new, <em>unbound</em> AF_VSOCK {@link ServerSocket} that will always bind to the
    * given address, regardless of any socket address used in a call to <code>bind</code>.
-   * 
+   *
    * @param forceAddr The address to use.
    * @return The new, yet unbound {@link AFServerSocket}.
    * @throws IOException if an exception occurs.
diff --git a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKServerSocketChannel.java b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKServerSocketChannel.java
index 5e1ed3d..3add333 100644
--- a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKServerSocketChannel.java
+++ b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKServerSocketChannel.java
@@ -24,7 +24,7 @@ import org.newsclub.net.unix.AFVSOCKSocketAddress;
 
 /**
  * A selectable channel for stream-oriented listening sockets.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFVSOCKServerSocketChannel extends AFServerSocketChannel<AFVSOCKSocketAddress> {
diff --git a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocket.java b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocket.java
index 13d325c..6bf4b4f 100644
--- a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocket.java
+++ b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocket.java
@@ -30,7 +30,7 @@ import org.newsclub.net.unix.AFVSOCKSocketImplExtensions;
 
 /**
  * Implementation of an {@code AF_VSOCK} socket.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFVSOCKSocket extends AFSocket<AFVSOCKSocketAddress> implements
@@ -42,7 +42,6 @@ public final class AFVSOCKSocket extends AFSocket<AFVSOCKSocketAddress> implemen
     super(new AFVSOCKSocketImpl(fdObj), factory);
   }
 
-  @SuppressWarnings("unused")
   private static synchronized AFVSOCKSocketImplExtensions getStaticImplExtensions()
       throws IOException {
     if (staticExtensions == null) {
@@ -56,13 +55,13 @@ public final class AFVSOCKSocket extends AFSocket<AFVSOCKSocketAddress> implemen
   /**
    * Returns <code>true</code> iff {@link AFVSOCKSocket}s (sockets of type "AF_VSOCK") are supported
    * by the current Java VM and the kernel.
-   * 
+   *
    * To support {@link AFVSOCKSocket}s, a custom JNI library must be loaded that is supplied with
    * <em>junixsocket</em>, and the system must support AF_VSOCK sockets.
-   * 
+   *
    * This call is equivalent to checking {@link AFSocket#isSupported()} and
    * {@link AFSocket#supports(AFSocketCapability)} with {@link AFSocketCapability#CAPABILITY_VSOCK}.
-   * 
+   *
    * @return {@code true} iff supported.
    */
   public static boolean isSupported() {
@@ -76,12 +75,12 @@ public final class AFVSOCKSocket extends AFSocket<AFVSOCKSocketAddress> implemen
 
   /**
    * Creates a new, unbound {@link AFSocket}.
-   * 
+   *
    * This "default" implementation is a bit "lenient" with respect to the specification.
-   * 
+   *
    * In particular, we ignore calls to {@link Socket#getTcpNoDelay()} and
    * {@link Socket#setTcpNoDelay(boolean)}.
-   * 
+   *
    * @return A new, unbound socket.
    * @throws IOException if the operation fails.
    */
@@ -95,10 +94,10 @@ public final class AFVSOCKSocket extends AFSocket<AFVSOCKSocketAddress> implemen
 
   /**
    * Creates a new, unbound, "strict" {@link AFSocket}.
-   * 
+   *
    * This call uses an implementation that tries to be closer to the specification than
    * {@link #newInstance()}, at least for some cases.
-   * 
+   *
    * @return A new, unbound socket.
    * @throws IOException if the operation fails.
    */
@@ -108,7 +107,7 @@ public final class AFVSOCKSocket extends AFSocket<AFVSOCKSocketAddress> implemen
 
   /**
    * Creates a new {@link AFSocket} and connects it to the given {@link AFVSOCKSocketAddress}.
-   * 
+   *
    * @param addr The address to connect to.
    * @return A new, connected socket.
    * @throws IOException if the operation fails.
@@ -124,7 +123,7 @@ public final class AFVSOCKSocket extends AFSocket<AFVSOCKSocketAddress> implemen
 
   /**
    * Returns the local CID.
-   * 
+   *
    * If the system does not support vsock, or status about support cannot be retrieved, -1
    * ({@link AFVSOCKSocketAddress#VMADDR_CID_ANY}) is returned. The value may be cached upon
    * initialization of the library.
@@ -138,9 +137,9 @@ public final class AFVSOCKSocket extends AFSocket<AFVSOCKSocketAddress> implemen
 
   /**
    * Very basic self-test function.
-   * 
+   *
    * Prints "supported" and "capabilities" status to System.out.
-   * 
+   *
    * @param args ignored.
    */
   public static void main(String[] args) {
diff --git a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketChannel.java b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketChannel.java
index 1b42310..d967b5f 100644
--- a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketChannel.java
+++ b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketChannel.java
@@ -22,7 +22,7 @@ import org.newsclub.net.unix.AFVSOCKSocketAddress;
 
 /**
  * A selectable channel for stream-oriented connecting sockets.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public final class AFVSOCKSocketChannel extends AFSocketChannel<AFVSOCKSocketAddress> implements
diff --git a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketExtensions.java b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketExtensions.java
index 343a538..5a823a1 100644
--- a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketExtensions.java
+++ b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketExtensions.java
@@ -22,7 +22,7 @@ import org.newsclub.net.unix.AFSocketExtensions;
 /**
  * Defines certain methods that all junixsocket AF_VSOCK socket implementations share and extend
  * beyond the standard socket API.
- * 
+ *
  * @author Christian Kohlschütter
  */
 public interface AFVSOCKSocketExtensions extends AFSocketExtensions {
diff --git a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketFactory.java b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketFactory.java
index 2936062..38a3055 100644
--- a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketFactory.java
+++ b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketFactory.java
@@ -49,7 +49,7 @@ public abstract class AFVSOCKSocketFactory extends AFSocketFactory<AFVSOCKSocket
 
   /**
    * Performs some optional configuration on a newly created socket.
-   * 
+   *
    * @param sock The socket.
    * @return The very socket.
    * @throws SocketException on error.
diff --git a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketOptions.java b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketOptions.java
index 758e18e..e619c1a 100644
--- a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketOptions.java
+++ b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketOptions.java
@@ -24,7 +24,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
 
 /**
  * VSOCK-specific socket options.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @NonNullByDefault
diff --git a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketPair.java b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketPair.java
index 079c853..87cbbb7 100644
--- a/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketPair.java
+++ b/junixsocket-vsock/src/main/java/org/newsclub/net/unix/vsock/AFVSOCKSocketPair.java
@@ -24,14 +24,14 @@ import org.newsclub.net.unix.AFSomeSocket;
 
 /**
  * A pair of sockets.
- * 
+ *
  * @param <T> The socket type.
  * @author Christian Kohlschütter
  */
 public final class AFVSOCKSocketPair<T extends AFSomeSocket> extends AFSocketPair<T> {
   /**
    * Creates a new socket pair.
-   * 
+   *
    * @param socket1 The first socket.
    * @param socket2 The second socket.
    */
@@ -41,7 +41,7 @@ public final class AFVSOCKSocketPair<T extends AFSomeSocket> extends AFSocketPai
 
   /**
    * Opens a socket pair of interconnected channels.
-   * 
+   *
    * @return The new channel pair.
    * @throws IOException on error.
    */
@@ -51,7 +51,7 @@ public final class AFVSOCKSocketPair<T extends AFSomeSocket> extends AFSocketPai
 
   /**
    * Opens a socket pair of interconnected datagram channels.
-   * 
+   *
    * @return The new channel pair.
    * @throws IOException on error.
    */
diff --git a/junixsocket-vsock/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-vsock/jni-config.json b/junixsocket-vsock/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-vsock/jni-config.json
new file mode 100644
index 0000000..fab1c71
--- /dev/null
+++ b/junixsocket-vsock/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-vsock/jni-config.json
@@ -0,0 +1,17 @@
+[
+{
+  "name":"org.newsclub.net.unix.vsock.AFVSOCKDatagramSocket"
+},
+{
+  "name":"org.newsclub.net.unix.vsock.AFVSOCKDatagramSocketImpl"
+},
+{
+  "name":"org.newsclub.net.unix.vsock.AFVSOCKSocket"
+},
+{
+  "name":"org.newsclub.net.unix.vsock.AFVSOCKSocketImpl"
+},
+{
+  "name":"org.newsclub.net.unix.vsock.AFVSOCKServerSocket"
+}
+]
diff --git a/junixsocket-vsock/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-vsock/reflect-config.json b/junixsocket-vsock/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-vsock/reflect-config.json
new file mode 100644
index 0000000..a18eb42
--- /dev/null
+++ b/junixsocket-vsock/src/main/resources/META-INF/native-image/com.kohlschutter.junixsocket/junixsocket-vsock/reflect-config.json
@@ -0,0 +1,5 @@
+[
+{
+  "name":"org.newsclub.net.unix.vsock.AFVSOCKSelectorProvider"
+}
+]
\ No newline at end of file
diff --git a/junixsocket-vsock/src/test/java/org/newsclub/net/unix/vsock/SelftestProvider.java b/junixsocket-vsock/src/test/java/org/newsclub/net/unix/vsock/SelftestProvider.java
index 331cc59..fb0888d 100644
--- a/junixsocket-vsock/src/test/java/org/newsclub/net/unix/vsock/SelftestProvider.java
+++ b/junixsocket-vsock/src/test/java/org/newsclub/net/unix/vsock/SelftestProvider.java
@@ -29,7 +29,7 @@ import org.newsclub.net.unix.SocketTestBase;
 /**
  * Provides references to all "junixsocket-vsock" tests that should be included in
  * junixsocket-selftest.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @SuppressWarnings("PMD.CouplingBetweenObjects")
diff --git a/junixsocket-vsock/src/test/java/org/newsclub/net/unix/vsock/SocketTest.java b/junixsocket-vsock/src/test/java/org/newsclub/net/unix/vsock/SocketTest.java
index da28086..3e2592c 100644
--- a/junixsocket-vsock/src/test/java/org/newsclub/net/unix/vsock/SocketTest.java
+++ b/junixsocket-vsock/src/test/java/org/newsclub/net/unix/vsock/SocketTest.java
@@ -28,7 +28,7 @@ import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
 
 /**
  * Tests some otherwise uncovered methods of {@link AFVSOCKSocket}.
- * 
+ *
  * @author Christian Kohlschütter
  */
 @AFSocketCapabilityRequirement(AFSocketCapability.CAPABILITY_VSOCK)
diff --git a/pom.xml b/pom.xml
index 2e8799c..4f48654 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,12 +3,12 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.kohlschutter.junixsocket</groupId>
     <artifactId>junixsocket</artifactId>
-    <version>2.6.1</version>
+    <version>2.6.2</version>
     <packaging>pom</packaging>
     <parent>
         <groupId>com.kohlschutter</groupId>
         <artifactId>kohlschutter-parent-multirelease</artifactId>
-        <version>1.5.1</version>
+        <version>1.5.2</version>
         <relativePath>../kohlschutter-parent/kohlschutter-parent-multirelease/pom.xml</relativePath>
     </parent>
     <name>junixsocket</name>
@@ -71,6 +71,9 @@ In contrast to other implementations, junixsocket extends the Java Sockets API (
         <junixsocket.skip.native>${m2e.version}</junixsocket.skip.native>
 
         <kohlschutter.multirelease.java8.release>8</kohlschutter.multirelease.java8.release>
+        <kohlschutter.multirelease.java.release>9</kohlschutter.multirelease.java.release>
+
+        <kohlschutter.custom.package.folder>org/newsclub</kohlschutter.custom.package.folder>
     </properties>
 
     <modules>
diff --git a/src/site/markdown/changelog.md b/src/site/markdown/changelog.md
index d2513e6..7343020 100644
--- a/src/site/markdown/changelog.md
+++ b/src/site/markdown/changelog.md
@@ -9,6 +9,16 @@ The existing API should always be backwards compatible between minor releases (e
 When upgrading from versions older than 2.4.0, please note that `junixsocket-core` is now a POM-only
 artifact (`<type>pom</type>`); see [Add junixsocket to your project](dependency.html) for details.
 
+### _(2022-02-08)_ **junixsocket 2.6.2**
+
+- Add socket connectors for AF_VSOCK, Firecracker
+- Add mayStopServerForce to AFSocketServerConnector
+- Fix false-positive selftest failure on slow machines
+- Fix potential hang in send
+- Fix support for TIPC/VSOCK when building GraalVM native images
+- Fix serialization of AFSocketAddresses
+- Update dependencies, especially use the new mysql.connector.j
+
 ### _(2022-10-26)_ **junixsocket 2.6.1**
 
  - Add AFSocket.checkConnectionClosed to probe connection status
diff --git a/src/site/markdown/compatibility.md b/src/site/markdown/compatibility.md
index 45e0d89..91f1a3a 100644
--- a/src/site/markdown/compatibility.md
+++ b/src/site/markdown/compatibility.md
@@ -11,7 +11,7 @@ should be backwards compatible to releases of the same "major version" (e.g., 2.
 
 ## Supported Java versions
 
-junixsocket 2.6.1 is fully compatible with Java 8 and newer (tested up to Java 19).
+junixsocket 2.6.2 is fully compatible with Java 8 and newer (tested up to Java 19).
 
 ## Supported Java VMs
 
@@ -76,7 +76,7 @@ Please reach out if you have some feature in mind that may be supported on these
 ## Additional Platforms and Architectures
 
 Upon request, support for additional systems, platforms and architectures may be added,
-such as OpenVMS, FUJITSU BS2000/OSD, Unisys ClearPath OS 2200, QNX, VxWorks, HP-UX, Haiku, etc.
+such as IBM z/TPF, OpenVMS, FUJITSU BS2000/OSD, Unisys ClearPath OS 2200, QNX, VxWorks, HP-UX, Haiku, etc.
 
 If you are interested in using junixsocket on another platform, or willing to sponsor development
 (by providing access to such platforms, covering licensing costs, etc.), feel free to
@@ -87,7 +87,7 @@ or [contact Christian Kohlschütter via email](mailto:christian@kohlschutter.com
 
 A reliable way to ensure that junixsocket works in your environment is to run the "[selftest](selftest.html)".
 
-    java -jar junixsocket-selftest-2.6.1-jar-with-dependencies.jar
+    java -jar junixsocket-selftest-2.6.2-jar-with-dependencies.jar
 
 The last line should say "Selftest PASSED", and you're good to go.
 
diff --git a/src/site/markdown/customarch.md b/src/site/markdown/customarch.md
index 9c70aa4..3ff6a18 100644
--- a/src/site/markdown/customarch.md
+++ b/src/site/markdown/customarch.md
@@ -86,7 +86,7 @@ for development and testing purposes:
     <dependency>
       <groupId>com.kohlschutter.junixsocket</groupId>
       <artifactId>junixsocket-native-custom</artifactId>
-      <version>2.6.1</version>
+      <version>2.6.2</version>
       <classifier>amd64-Linux-gpp-jni</classifier>
     </dependency>
 
diff --git a/src/site/markdown/dependency.md b/src/site/markdown/dependency.md
index 4599b18..8746acf 100644
--- a/src/site/markdown/dependency.md
+++ b/src/site/markdown/dependency.md
@@ -14,7 +14,7 @@ Add the following dependency to your Maven project
     <dependency>
       <groupId>com.kohlschutter.junixsocket</groupId>
       <artifactId>junixsocket-core</artifactId>
-      <version>2.6.1</version>
+      <version>2.6.2</version>
       <type>pom</type>
     </dependency>
 
@@ -26,7 +26,7 @@ following two dependencies instead:
     <dependency>
       <groupId>com.kohlschutter.junixsocket</groupId>
       <artifactId>junixsocket-common</artifactId>
-      <version>2.6.1</version>
+      <version>2.6.2</version>
     </dependency>
 
 and
@@ -34,7 +34,7 @@ and
     <dependency>
       <groupId>com.kohlschutter.junixsocket</groupId>
       <artifactId>junixsocket-native-common</artifactId>
-      <version>2.6.1</version>
+      <version>2.6.2</version>
     </dependency>
  
 ### Optional dependencies
@@ -44,7 +44,7 @@ If you're going to use AFUNIXSocketServer code, add the following dependency:
     <dependency>
       <groupId>com.kohlschutter.junixsocket</groupId>
       <artifactId>junixsocket-server</artifactId>
-      <version>2.6.1</version>
+      <version>2.6.2</version>
     </dependency>
     
 If you're going to use RMI over Unix sockets, add the following dependency:
@@ -52,7 +52,7 @@ If you're going to use RMI over Unix sockets, add the following dependency:
     <dependency>
       <groupId>com.kohlschutter.junixsocket</groupId>
       <artifactId>junixsocket-rmi</artifactId>
-      <version>2.6.1</version>
+      <version>2.6.2</version>
     </dependency>
 
 If you're going to use the mySQL Connector for Unix sockets, add the following dependency:
@@ -60,7 +60,7 @@ If you're going to use the mySQL Connector for Unix sockets, add the following d
     <dependency>
       <groupId>com.kohlschutter.junixsocket</groupId>
       <artifactId>junixsocket-mysql</artifactId>
-      <version>2.6.1</version>
+      <version>2.6.2</version>
     </dependency>
  
 If you're going to use TIPC, add the following dependency:
@@ -68,7 +68,7 @@ If you're going to use TIPC, add the following dependency:
     <dependency>
       <groupId>com.kohlschutter.junixsocket</groupId>
       <artifactId>junixsocket-tipc</artifactId>
-      <version>2.6.1</version>
+      <version>2.6.2</version>
     </dependency>
  
 If you're going to use VSOCK, add the following dependency:
@@ -76,7 +76,7 @@ If you're going to use VSOCK, add the following dependency:
     <dependency>
       <groupId>com.kohlschutter.junixsocket</groupId>
       <artifactId>junixsocket-vsock</artifactId>
-      <version>2.6.1</version>
+      <version>2.6.2</version>
     </dependency>
   
 If you're going to use the Jetty connectors, add the following dependency:
@@ -84,7 +84,7 @@ If you're going to use the Jetty connectors, add the following dependency:
     <dependency>
       <groupId>com.kohlschutter.junixsocket</groupId>
       <artifactId>junixsocket-jetty</artifactId>
-      <version>2.6.1</version>
+      <version>2.6.2</version>
     </dependency>
 
 
@@ -119,35 +119,35 @@ Add the following statements to `build.gradle`; if you have existing dependencie
 For the common Java code and common native libraries, add:
 
 	dependencies {
-		implementation 'com.kohlschutter.junixsocket:junixsocket-core:2.6.1'
+		implementation 'com.kohlschutter.junixsocket:junixsocket-core:2.6.2'
 	}
 
 Some older Gradle versions require `compile` instead of `implementation`, and some older versions have trouble resolving the `junixsocket-core` POM artifact. If you're running into problems (and only then), try the following:
 
 	dependencies {
-		implementation 'com.kohlschutter.junixsocket:junixsocket-common:2.6.1'
-		implementation 'com.kohlschutter.junixsocket:junixsocket-native-scommon:2.6.1'
+		implementation 'com.kohlschutter.junixsocket:junixsocket-common:2.6.2'
+		implementation 'com.kohlschutter.junixsocket:junixsocket-native-scommon:2.6.2'
 	}
  
 For RMI support, add:
  
-		implementation 'com.kohlschutter.junixsocket:junixsocket-rmi:2.6.1'
+		implementation 'com.kohlschutter.junixsocket:junixsocket-rmi:2.6.2'
  
 For MySQL support, add:
  
-		implementation 'com.kohlschutter.junixsocket:junixsocket-mysql:2.6.1'
+		implementation 'com.kohlschutter.junixsocket:junixsocket-mysql:2.6.2'
  
 For TIPC support, add:
  
-		implementation 'com.kohlschutter.junixsocket:junixsocket-tipc:2.6.1'
+		implementation 'com.kohlschutter.junixsocket:junixsocket-tipc:2.6.2'
  
 For VSOCK support, add:
  
-		implementation 'com.kohlschutter.junixsocket:junixsocket-vsock:2.6.1'
+		implementation 'com.kohlschutter.junixsocket:junixsocket-vsock:2.6.2'
  
 For Jetty support, add:
  
-		implementation 'com.kohlschutter.junixsocket:junixsocket-jetty:2.6.1'
+		implementation 'com.kohlschutter.junixsocket:junixsocket-jetty:2.6.2'
 
 ### Snapshot versions
 
@@ -182,13 +182,13 @@ databases such as PostgreSQL.
 
 ### MySQL
 
-Make sure that the following jars are on your classpath:
+If you can't use Maven (instructions above), make sure that the following jars are on your classpath:
 
- * junixsocket-common-2.6.1.jar
- * junixsocket-mysql-2.6.1.jar
- * mysql-connector-java-8.0.14.jar (or newer; earlier versions should work, too)
- * (typically, omit if you use the custom library below) junixsocket-native-common-2.6.1.jar
- * (optionally, if you have a custom architecture) junixsocket-native-custom-2.6.1.jar
+ * junixsocket-common-2.6.2.jar
+ * junixsocket-mysql-2.6.2.jar
+ * mysql-connector-j-8.0.31.jar (or newer)
+ * (typically required; can be skipped if you use the custom library below) junixsocket-native-common-2.6.2.jar
+ * (optionally, if you have a custom architecture) junixsocket-native-custom-2.6.2.jar
 
 Use the following connection properties (along with `user`, `password`, and other properties you may
 have).
@@ -217,10 +217,10 @@ to disable SSL with older versions of Connector/J.
 
 Make sure that the following jars are on your classpath:
 
- * junixsocket-common-2.6.1.jar
+ * junixsocket-common-2.6.2.jar
  * postgresql-42.2.5.jar (or newer; earlier versions should work, too)
- * (typically, omit if you use the custom library below) junixsocket-native-common-2.6.1.jar
- * (optionally, if you have a custom architecture) junixsocket-native-custom-2.6.1.jar
+ * (typically, omit if you use the custom library below) junixsocket-native-common-2.6.2.jar
+ * (optionally, if you have a custom architecture) junixsocket-native-custom-2.6.2.jar
 
 
 Use the following connection properties (along with `user`, `password`, and other properties you may
diff --git a/src/site/markdown/eclipse.md b/src/site/markdown/eclipse.md
index d8be5be..b54e562 100644
--- a/src/site/markdown/eclipse.md
+++ b/src/site/markdown/eclipse.md
@@ -38,7 +38,7 @@ above the `junixsocket` parent project).
 You are encouraged to import the corresponding configuration files to your Eclipse workspace.
 
 If you don't want to apply these settings to your other projects, create a new Eclipse workspace
-for junixsocket. You can also run `mvn formatter:format` to apply the formatting rules from the command line. 
+for junixsocket. You can also run `mvn process-sources -Preformat` to apply the formatting rules (along with other reformatting operations) from the command line. 
 
 ## Code quality checks
 
diff --git a/src/site/markdown/graalvm.md b/src/site/markdown/graalvm.md
index 6f80ffb..7f161de 100644
--- a/src/site/markdown/graalvm.md
+++ b/src/site/markdown/graalvm.md
@@ -59,6 +59,45 @@ The above binary, even though it currently cannot be built on Alpine Linux (musl
 adding `gcompat`:
 
 	sudo apk add gcompat
+	
+## Known issues
+
+### native-image needs a lot of RAM
+
+When you see an error message `Error: Image build request failed with exit status 137` coming from the Maven build of `junixsocket-selftest-native-image`, there was not enough RAM, and the kernel terminated the process. Either add some swap space or more RAM.
+
+### NoSuchMethodException: ...DatagramSocketImpl.peekData
+
+When you see errors like this, try building with a Java 19 GraalVM instead of Java 11 GraalVM:
+
+```
+Fatal error: org.graalvm.compiler.debug.GraalError: com.oracle.svm.util.ReflectionUtil$ReflectionUtilError: java.lang.NoSuchMethodException: org.newsclub.net.unix.vsock.AFVSOCKDatagramSocketImpl.peekData(java.net.DatagramPacket)
+	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.AnalysisFuture.setException(AnalysisFuture.java:49)
+	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:269)
+	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.AnalysisFuture.ensureDone(AnalysisFuture.java:63)
+	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.meta.AnalysisElement.lambda$execute$2(AnalysisElement.java:170)
+	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:193)
+	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:177)
+	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
+	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
+	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
+	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
+	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
+	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
+Caused by: com.oracle.svm.util.ReflectionUtil$ReflectionUtilError: java.lang.NoSuchMethodException: org.newsclub.net.unix.vsock.AFVSOCKDatagramSocketImpl.peekData(java.net.DatagramPacket)
+	at org.graalvm.nativeimage.base/com.oracle.svm.util.ReflectionUtil.lookupMethod(ReflectionUtil.java:82)
+	at org.graalvm.nativeimage.base/com.oracle.svm.util.ReflectionUtil.lookupMethod(ReflectionUtil.java:69)
+	at org.graalvm.nativeimage.builder/com.oracle.svm.core.jdk.JNIRegistrationUtil.method(JNIRegistrationUtil.java:91)
+	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.jdk.JNIRegistrationJavaNet.lambda$registerDatagramSocketCheckOldImpl$0(JNIRegistrationJavaNet.java:230)
+	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.meta.AnalysisElement$SubtypeReachableNotification.lambda$notifyCallback$0(AnalysisElement.java:129)
+	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
+	... 10 more
+Caused by: java.lang.NoSuchMethodException: org.newsclub.net.unix.vsock.AFVSOCKDatagramSocketImpl.peekData(java.net.DatagramPacket)
+	at java.base/java.lang.Class.getDeclaredMethod(Class.java:2475)
+	at org.graalvm.nativeimage.base/com.oracle.svm.util.ReflectionUtil.lookupMethod(ReflectionUtil.java:74)
+	... 15 more
+```
+
 
 ## Building and Maintaining junixsocket's Reachability Metadata
 
diff --git a/src/site/markdown/release.md b/src/site/markdown/release.md
index 3cf3738..9a6a624 100644
--- a/src/site/markdown/release.md
+++ b/src/site/markdown/release.md
@@ -31,7 +31,8 @@ Instructions for macOS
 
  * Enable pinentry-mac
  
-   This gives a nice GUI for the passphrase, and allows us to store the GPG key passphrase in the macOS keychain)
+   This gives a nice GUI for the passphrase, and allows us to store the GPG key passphrase in the
+   macOS keychain)
 
  * Open or create `~/.gnupg/gpg-agent.conf`
    then add the following line if it doesn't exist yet:
@@ -51,16 +52,19 @@ Instructions for macOS
 ### Build environment for other platforms
 
 Currently, the easiest way to build for other platforms is to have a working Java 9 (or later)
-environment, Maven 3+ and the junixsocket project ready. Just spin up a virtual machine (or emulator),
-install Java, Maven and junixsocket, and you should be good to go.
+environment, Maven 3+ and the junixsocket project ready.  Just spin up a virtual machine (or
+emulator), install Java, Maven and junixsocket, and you should be good to go.
     
 ## Common tasks
 
 ### Update changelog, website, README.md
 
-Update `junixsocket/src/site/markdown/changelog.md` with a section for the new version and all noteworthy changes.
+Update `junixsocket/src/site/markdown/changelog.md` with a section for the new version and all
+noteworthy changes.
 
-Check all mentions (execpet for `changelog.md`) of the current junixsocket under `junixsocket/src/site/markdown`, and replace accordingly: `grep X.Y.Z src/site/markdown/* | grep -v changelog.md:`
+Check all mentions (execpet for `changelog.md`) of the current junixsocket under
+`junixsocket/src/site/markdown`, and replace accordingly:
+`grep X.Y.Z src/site/markdown/* | grep -v changelog.md:`
 
 Also update the dependency statement in `junixsocket/README.md`.
 
@@ -68,16 +72,19 @@ Also update the dependency statement in `junixsocket/README.md`.
 
 ### Ensure GraalVM native configs are still up-to-date
 
-Run `junixsocket-native-graalvm/bin/graalvm junixsocket-native-graalvm/bin/build-selftest`
+Run `junixsocket-native-graalvm/bin/with-graalvm junixsocket-native-graalvm/bin/build-selftest`
 
-If, at the end, you see changes to the json files in `junixsocket-native-graalvm/output`, review them, modify the json files in `junixsocket-{common,tipc,vsock,selftest,...}/src/main/resources/META-INF/native-image` accordingly, and add/commit both sets of changes.
+If, at the end, you see changes to the json files in `junixsocket-native-graalvm/output`, review
+them, modify the json files in
+`junixsocket-{common,tipc,vsock,selftest,...}/src/main/resources/META-INF/native-image` accordingly,
+and add/commit both sets of changes.
 
 ### Ensure the code is properly formatted and licenses are in place
 
+First, view the `LICENSE` file and verify that it's up to date. Then run the code formatters and commit.
+
     cd junixsocket
-    # review LICENSE file and verify that it's up-to-date
-    mvn formatter:format
-    mvn license:format
+    mvn process-sources -Preformat
     # git add / commit here...
 
 ### Bump project version
@@ -137,9 +144,11 @@ Run `java -jar junixsocket-selftest/target/junixsocket-selftest-X.Y.Z-jar-with-d
 
 Also run the selftest with Java 8, e.g.:
 
-	/Library/Java/JavaVirtualMachines/1.8.0.jdk/Contents/Home/bin/java -jar junixsocket-selftest/target/junixsocket-selftest-2.6.1-jar-with-dependencies.jar
+	/Library/Java/JavaVirtualMachines/1.8.0.jdk/Contents/Home/bin/java -jar junixsocket-selftest/target/junixsocket-selftest-2.6.2-jar-with-dependencies.jar
 
-Run `junixsocket-native-graalvm/bin/graalvm mvn package -pl junixsocket-selftest-native-image -Pnative` (on all native-image supported platforms) to build the GraalVM native-image. Test the native-image by running `junixsocket-selftest-native-image/target/junixsocket-selftest-native-image-X.Y.Z`.
+Run `junixsocket-native-graalvm/bin/with-graalvm mvn package -pl junixsocket-selftest-native-image -Pnative`
+(on all native-image supported platforms) to build the GraalVM native-image.  Test the native-image
+by running `junixsocket-selftest-native-image/target/junixsocket-selftest-native-image-X.Y.Z`.
 
 > **NOTE:** (Replace X.Y.Z with the actual version)
 

More details

Full run details

Historical runs