Java Unix Domain Socket implementation providing AF_UNIX, AF_TIPC, AF_VSOCK, and AF_SYSTEM socket support with traditional and NIO APIs
—
Remote Method Invocation support over Unix Domain Sockets enabling efficient distributed computing within the same system, eliminating network overhead for local inter-process communication.
RMI socket factory implementation for creating Unix Domain Socket connections for RMI communication.
/**
* Unix Domain Socket RMI factory implementation
*/
public class AFUNIXRMISocketFactory extends AFRMISocketFactory {
/**
* Gets the singleton AFUNIXRMISocketFactory instance
* @return AFUNIXRMISocketFactory instance
* @throws IOException if factory creation fails
*/
public static AFUNIXRMISocketFactory getInstance() throws IOException;
/**
* Creates AFUNIXRMISocketFactory with custom socket address
* @param socketAddress The socket address for RMI communication
* @return AFUNIXRMISocketFactory instance
* @throws IOException if factory creation fails
*/
public static AFUNIXRMISocketFactory getInstance(AFUNIXSocketAddress socketAddress) throws IOException;
// RMISocketFactory implementation
public Socket createSocket(String host, int port) throws IOException;
public ServerSocket createServerSocket(int port) throws IOException;
// Socket factory configuration
public void setSocketAddress(AFUNIXSocketAddress socketAddress);
public AFUNIXSocketAddress getSocketAddress();
}Usage Examples:
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.io.File;
import org.newsclub.net.unix.*;
// Define RMI service interface
public interface HelloService extends Remote {
String sayHello(String name) throws RemoteException;
int calculate(int a, int b) throws RemoteException;
}
// RMI server setup
public class RMIServer {
public static void main(String[] args) throws Exception {
// Create socket address for RMI
File rmiSocket = new File("/tmp/rmi-server.sock");
AFUNIXSocketAddress rmiAddress = AFUNIXSocketAddress.of(rmiSocket);
// Configure RMI to use Unix Domain Sockets
AFUNIXRMISocketFactory socketFactory = AFUNIXRMISocketFactory.getInstance(rmiAddress);
System.setProperty("java.rmi.server.hostname", rmiAddress.toString());
// Create and register service
HelloService service = new HelloServiceImpl();
HelloService stub = (HelloService) UnicastRemoteObject.exportObject(
service, 0, socketFactory, socketFactory);
// Bind service in registry (using file-based registry)
AFUNIXRegistry registry = AFUNIXRegistry.createRegistry(rmiAddress);
registry.bind("HelloService", stub);
System.out.println("RMI Server ready on: " + rmiSocket);
// Keep server running
Thread.sleep(Long.MAX_VALUE);
}
}
// RMI client
public class RMIClient {
public static void main(String[] args) throws Exception {
File rmiSocket = new File("/tmp/rmi-server.sock");
AFUNIXSocketAddress rmiAddress = AFUNIXSocketAddress.of(rmiSocket);
// Configure client to use Unix Domain Sockets
AFUNIXRMISocketFactory socketFactory = AFUNIXRMISocketFactory.getInstance(rmiAddress);
// Look up service
AFUNIXRegistry registry = AFUNIXRegistry.getRegistry(rmiAddress);
HelloService service = (HelloService) registry.lookup("HelloService");
// Call remote methods
String greeting = service.sayHello("World");
System.out.println("Server says: " + greeting);
int result = service.calculate(10, 20);
System.out.println("Calculation result: " + result);
}
}Base interface for RMI services providing Unix Domain Socket-specific functionality.
/**
* RMI service interface for AF sockets
*/
public interface AFRMIService extends Remote {
/**
* Gets the socket address used by this RMI service
* @return Socket address for the service
* @throws RemoteException if operation fails
*/
AFSocketAddress getServiceAddress() throws RemoteException;
/**
* Checks if the service is available
* @return true if service is available
* @throws RemoteException if operation fails
*/
boolean isServiceAvailable() throws RemoteException;
/**
* Gets service metadata
* @return Service information
* @throws RemoteException if operation fails
*/
String getServiceInfo() throws RemoteException;
}Service Implementation Example:
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import org.newsclub.net.unix.*;
// Service implementation
public class HelloServiceImpl extends UnicastRemoteObject implements HelloService, AFRMIService {
private final AFUNIXSocketAddress serviceAddress;
public HelloServiceImpl(AFUNIXSocketAddress address) throws RemoteException {
super();
this.serviceAddress = address;
}
@Override
public String sayHello(String name) throws RemoteException {
return "Hello, " + name + "! (via Unix Domain Socket RMI)";
}
@Override
public int calculate(int a, int b) throws RemoteException {
return a + b;
}
@Override
public AFSocketAddress getServiceAddress() throws RemoteException {
return serviceAddress;
}
@Override
public boolean isServiceAvailable() throws RemoteException {
return true;
}
@Override
public String getServiceInfo() throws RemoteException {
return "HelloService v1.0 - Unix Domain Socket RMI Implementation";
}
}Unix Domain Socket-based RMI registry for service discovery and binding without network exposure.
/**
* Unix Domain Socket RMI registry
*/
public class AFUNIXRegistry extends AFRegistry {
/**
* Creates a new registry bound to the specified address
* @param address The socket address for the registry
* @return AFUNIXRegistry instance
* @throws RemoteException if registry creation fails
*/
public static AFUNIXRegistry createRegistry(AFUNIXSocketAddress address) throws RemoteException;
/**
* Gets a reference to an existing registry
* @param address The socket address of the registry
* @return AFUNIXRegistry instance
* @throws RemoteException if registry access fails
*/
public static AFUNIXRegistry getRegistry(AFUNIXSocketAddress address) throws RemoteException;
// Registry operations
public void bind(String name, Remote obj) throws RemoteException, AlreadyBoundException;
public void rebind(String name, Remote obj) throws RemoteException;
public void unbind(String name) throws RemoteException, NotBoundException;
public Remote lookup(String name) throws RemoteException, NotBoundException;
public String[] list() throws RemoteException;
// Registry properties
public AFUNIXSocketAddress getRegistryAddress();
public boolean isRegistryRunning();
}Registry Usage Examples:
// Registry server
public class RegistryServer {
public static void main(String[] args) throws Exception {
File registrySocket = new File("/tmp/rmi-registry.sock");
AFUNIXSocketAddress registryAddr = AFUNIXSocketAddress.of(registrySocket);
// Create registry
AFUNIXRegistry registry = AFUNIXRegistry.createRegistry(registryAddr);
// Register multiple services
HelloService helloService = new HelloServiceImpl(registryAddr);
CalculatorService calcService = new CalculatorServiceImpl(registryAddr);
registry.bind("HelloService", helloService);
registry.bind("CalculatorService", calcService);
System.out.println("Registry running with services:");
String[] services = registry.list();
for (String service : services) {
System.out.println(" - " + service);
}
// Keep registry running
Thread.sleep(Long.MAX_VALUE);
}
}
// Service discovery client
public class ServiceDiscoveryClient {
public static void main(String[] args) throws Exception {
File registrySocket = new File("/tmp/rmi-registry.sock");
AFUNIXSocketAddress registryAddr = AFUNIXSocketAddress.of(registrySocket);
// Connect to registry
AFUNIXRegistry registry = AFUNIXRegistry.getRegistry(registryAddr);
// List available services
System.out.println("Available services:");
String[] services = registry.list();
for (String serviceName : services) {
System.out.println(" - " + serviceName);
// Look up service details
Remote service = registry.lookup(serviceName);
if (service instanceof AFRMIService) {
AFRMIService afService = (AFRMIService) service;
System.out.println(" Info: " + afService.getServiceInfo());
System.out.println(" Address: " + afService.getServiceAddress());
}
}
}
}/**
* Base class for AF RMI socket factories
*/
public abstract class AFRMISocketFactory implements RMIClientSocketFactory, RMIServerSocketFactory {
// Factory configuration
public abstract void setSocketAddress(AFSocketAddress address);
public abstract AFSocketAddress getSocketAddress();
// Socket creation with custom parameters
public abstract Socket createSocket(String host, int port, SocketAddress localAddr, int timeout) throws IOException;
public abstract ServerSocket createServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException;
// Factory management
public static void setDefaultSocketFactory(AFRMISocketFactory factory);
public static AFRMISocketFactory getDefaultSocketFactory();
}Custom Factory Example:
// Custom RMI socket factory with connection pooling
public class PooledRMISocketFactory extends AFUNIXRMISocketFactory {
private final ObjectPool<Socket> socketPool;
private final int maxPoolSize;
public PooledRMISocketFactory(AFUNIXSocketAddress address, int maxPoolSize) throws IOException {
super(address);
this.maxPoolSize = maxPoolSize;
this.socketPool = new SocketPool(maxPoolSize);
}
@Override
public Socket createSocket(String host, int port) throws IOException {
Socket socket = socketPool.acquire();
if (socket == null || socket.isClosed()) {
socket = super.createSocket(host, port);
}
return new PooledSocket(socket, socketPool);
}
private static class SocketPool extends ObjectPool<Socket> {
public SocketPool(int maxSize) {
super(maxSize);
}
@Override
protected Socket createObject() {
return null; // Created externally
}
@Override
protected boolean validateObject(Socket socket) {
return socket != null && !socket.isClosed() && socket.isConnected();
}
}
private static class PooledSocket extends Socket {
private final Socket delegate;
private final ObjectPool<Socket> pool;
public PooledSocket(Socket delegate, ObjectPool<Socket> pool) {
this.delegate = delegate;
this.pool = pool;
}
@Override
public void close() throws IOException {
// Return to pool instead of closing
pool.release(delegate);
}
// Delegate all other methods to the wrapped socket
// ... delegation methods
}
}// RMI security configuration for Unix Domain Sockets
public class RMISecurityConfig {
public static void configureSecureRMI(AFUNIXSocketAddress address) throws Exception {
// Set socket factory
AFUNIXRMISocketFactory factory = AFUNIXRMISocketFactory.getInstance(address);
// Configure RMI properties
System.setProperty("java.rmi.server.hostname", address.toString());
System.setProperty("java.rmi.server.randomIDs", "true");
System.setProperty("java.rmi.dgc.leaseValue", "600000"); // 10 minutes
// Install security manager if needed
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
// Set socket factory as default
AFRMISocketFactory.setDefaultSocketFactory(factory);
}
public static void configurePeerCredentials(AFUNIXRMISocketFactory factory) throws IOException {
// Enable peer credential checking
factory.setSocketAddress(factory.getSocketAddress());
// Custom socket creation with credential validation
// Implementation would check peer credentials on connection
}
}// RMI service manager for multiple services
public class RMIServiceManager {
private final AFUNIXRegistry registry;
private final Map<String, Remote> services = new ConcurrentHashMap<>();
private final AFUNIXRMISocketFactory socketFactory;
public RMIServiceManager(AFUNIXSocketAddress registryAddress) throws Exception {
this.socketFactory = AFUNIXRMISocketFactory.getInstance(registryAddress);
this.registry = AFUNIXRegistry.createRegistry(registryAddress);
}
public void registerService(String name, Remote service) throws RemoteException {
try {
// Export service with Unix Domain Socket factory
Remote stub = UnicastRemoteObject.exportObject(service, 0, socketFactory, socketFactory);
// Bind in registry
registry.bind(name, stub);
services.put(name, service);
System.out.println("Registered service: " + name);
} catch (AlreadyBoundException e) {
// Rebind if already exists
registry.rebind(name, service);
services.put(name, service);
System.out.println("Re-registered service: " + name);
}
}
public void unregisterService(String name) throws RemoteException, NotBoundException {
registry.unbind(name);
Remote service = services.remove(name);
if (service != null) {
try {
UnicastRemoteObject.unexportObject(service, true);
} catch (NoSuchObjectException e) {
// Service already unexported
}
}
System.out.println("Unregistered service: " + name);
}
public String[] listServices() throws RemoteException {
return registry.list();
}
public void shutdown() throws RemoteException {
// Unregister all services
for (String serviceName : services.keySet()) {
try {
unregisterService(serviceName);
} catch (Exception e) {
System.err.println("Error unregistering " + serviceName + ": " + e.getMessage());
}
}
// Shutdown registry (implementation specific)
// registry.shutdown();
}
}RMI-specific exception handling patterns:
// RMI exceptions
public class RemoteException extends IOException;
public class NotBoundException extends Exception;
public class AlreadyBoundException extends Exception;
public class NoSuchObjectException extends RemoteException;
public class ConnectException extends RemoteException;
public class ServerException extends RemoteException;Error Handling Examples:
try {
AFUNIXRegistry registry = AFUNIXRegistry.getRegistry(registryAddress);
HelloService service = (HelloService) registry.lookup("HelloService");
String result = service.sayHello("Client");
System.out.println("Result: " + result);
} catch (NotBoundException e) {
System.err.println("Service not found in registry: " + e.getMessage());
} catch (ConnectException e) {
System.err.println("Failed to connect to RMI service: " + e.getMessage());
} catch (ServerException e) {
System.err.println("Server-side error: " + e.getMessage());
} catch (RemoteException e) {
System.err.println("RMI communication error: " + e.getMessage());
} catch (ClassCastException e) {
System.err.println("Service interface mismatch: " + e.getMessage());
}
// Registry binding error handling
try {
registry.bind("MyService", serviceImpl);
} catch (AlreadyBoundException e) {
System.out.println("Service already bound, rebinding...");
registry.rebind("MyService", serviceImpl);
} catch (RemoteException e) {
System.err.println("Failed to bind service: " + e.getMessage());
}// Efficient RMI connection handling
public class OptimizedRMIClient {
private final AFUNIXRegistry registry;
private final Map<Class<?>, Remote> serviceCache = new ConcurrentHashMap<>();
public OptimizedRMIClient(AFUNIXSocketAddress registryAddr) throws RemoteException {
this.registry = AFUNIXRegistry.getRegistry(registryAddr);
}
@SuppressWarnings("unchecked")
public <T extends Remote> T getService(String serviceName, Class<T> serviceInterface) throws RemoteException, NotBoundException {
// Check cache first
T service = (T) serviceCache.get(serviceInterface);
if (service != null) {
try {
// Test connection
if (service instanceof AFRMIService) {
((AFRMIService) service).isServiceAvailable();
}
return service;
} catch (RemoteException e) {
// Service unavailable, remove from cache
serviceCache.remove(serviceInterface);
}
}
// Look up service
service = (T) registry.lookup(serviceName);
serviceCache.put(serviceInterface, service);
return service;
}
public void clearCache() {
serviceCache.clear();
}
}Install with Tessl CLI
npx tessl i tessl/maven-com-kohlschutter-junixsocket--junixsocket-core