or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

addressing.mdcapabilities.mddatagram-sockets.mdexceptions.mdfile-descriptors.mdindex.mdnio-channels.mdrmi.mdsocket-pairs.mdunix-sockets.mdutilities.md

rmi.mddocs/

0

# RMI Integration

1

2

Remote Method Invocation support over Unix Domain Sockets enabling efficient distributed computing within the same system, eliminating network overhead for local inter-process communication.

3

4

## Capabilities

5

6

### AFUNIXRMISocketFactory

7

8

RMI socket factory implementation for creating Unix Domain Socket connections for RMI communication.

9

10

```java { .api }

11

/**

12

* Unix Domain Socket RMI factory implementation

13

*/

14

public class AFUNIXRMISocketFactory extends AFRMISocketFactory {

15

16

/**

17

* Gets the singleton AFUNIXRMISocketFactory instance

18

* @return AFUNIXRMISocketFactory instance

19

* @throws IOException if factory creation fails

20

*/

21

public static AFUNIXRMISocketFactory getInstance() throws IOException;

22

23

/**

24

* Creates AFUNIXRMISocketFactory with custom socket address

25

* @param socketAddress The socket address for RMI communication

26

* @return AFUNIXRMISocketFactory instance

27

* @throws IOException if factory creation fails

28

*/

29

public static AFUNIXRMISocketFactory getInstance(AFUNIXSocketAddress socketAddress) throws IOException;

30

31

// RMISocketFactory implementation

32

public Socket createSocket(String host, int port) throws IOException;

33

public ServerSocket createServerSocket(int port) throws IOException;

34

35

// Socket factory configuration

36

public void setSocketAddress(AFUNIXSocketAddress socketAddress);

37

public AFUNIXSocketAddress getSocketAddress();

38

}

39

```

40

41

**Usage Examples:**

42

43

```java

44

import java.rmi.Naming;

45

import java.rmi.Remote;

46

import java.rmi.RemoteException;

47

import java.rmi.server.UnicastRemoteObject;

48

import java.io.File;

49

import org.newsclub.net.unix.*;

50

51

// Define RMI service interface

52

public interface HelloService extends Remote {

53

String sayHello(String name) throws RemoteException;

54

int calculate(int a, int b) throws RemoteException;

55

}

56

57

// RMI server setup

58

public class RMIServer {

59

public static void main(String[] args) throws Exception {

60

// Create socket address for RMI

61

File rmiSocket = new File("/tmp/rmi-server.sock");

62

AFUNIXSocketAddress rmiAddress = AFUNIXSocketAddress.of(rmiSocket);

63

64

// Configure RMI to use Unix Domain Sockets

65

AFUNIXRMISocketFactory socketFactory = AFUNIXRMISocketFactory.getInstance(rmiAddress);

66

System.setProperty("java.rmi.server.hostname", rmiAddress.toString());

67

68

// Create and register service

69

HelloService service = new HelloServiceImpl();

70

HelloService stub = (HelloService) UnicastRemoteObject.exportObject(

71

service, 0, socketFactory, socketFactory);

72

73

// Bind service in registry (using file-based registry)

74

AFUNIXRegistry registry = AFUNIXRegistry.createRegistry(rmiAddress);

75

registry.bind("HelloService", stub);

76

77

System.out.println("RMI Server ready on: " + rmiSocket);

78

79

// Keep server running

80

Thread.sleep(Long.MAX_VALUE);

81

}

82

}

83

84

// RMI client

85

public class RMIClient {

86

public static void main(String[] args) throws Exception {

87

File rmiSocket = new File("/tmp/rmi-server.sock");

88

AFUNIXSocketAddress rmiAddress = AFUNIXSocketAddress.of(rmiSocket);

89

90

// Configure client to use Unix Domain Sockets

91

AFUNIXRMISocketFactory socketFactory = AFUNIXRMISocketFactory.getInstance(rmiAddress);

92

93

// Look up service

94

AFUNIXRegistry registry = AFUNIXRegistry.getRegistry(rmiAddress);

95

HelloService service = (HelloService) registry.lookup("HelloService");

96

97

// Call remote methods

98

String greeting = service.sayHello("World");

99

System.out.println("Server says: " + greeting);

100

101

int result = service.calculate(10, 20);

102

System.out.println("Calculation result: " + result);

103

}

104

}

105

```

106

107

### AFRMIService

108

109

Base interface for RMI services providing Unix Domain Socket-specific functionality.

110

111

```java { .api }

112

/**

113

* RMI service interface for AF sockets

114

*/

115

public interface AFRMIService extends Remote {

116

117

/**

118

* Gets the socket address used by this RMI service

119

* @return Socket address for the service

120

* @throws RemoteException if operation fails

121

*/

122

AFSocketAddress getServiceAddress() throws RemoteException;

123

124

/**

125

* Checks if the service is available

126

* @return true if service is available

127

* @throws RemoteException if operation fails

128

*/

129

boolean isServiceAvailable() throws RemoteException;

130

131

/**

132

* Gets service metadata

133

* @return Service information

134

* @throws RemoteException if operation fails

135

*/

136

String getServiceInfo() throws RemoteException;

137

}

138

```

139

140

**Service Implementation Example:**

141

142

```java

143

import java.rmi.RemoteException;

144

import java.rmi.server.UnicastRemoteObject;

145

import org.newsclub.net.unix.*;

146

147

// Service implementation

148

public class HelloServiceImpl extends UnicastRemoteObject implements HelloService, AFRMIService {

149

private final AFUNIXSocketAddress serviceAddress;

150

151

public HelloServiceImpl(AFUNIXSocketAddress address) throws RemoteException {

152

super();

153

this.serviceAddress = address;

154

}

155

156

@Override

157

public String sayHello(String name) throws RemoteException {

158

return "Hello, " + name + "! (via Unix Domain Socket RMI)";

159

}

160

161

@Override

162

public int calculate(int a, int b) throws RemoteException {

163

return a + b;

164

}

165

166

@Override

167

public AFSocketAddress getServiceAddress() throws RemoteException {

168

return serviceAddress;

169

}

170

171

@Override

172

public boolean isServiceAvailable() throws RemoteException {

173

return true;

174

}

175

176

@Override

177

public String getServiceInfo() throws RemoteException {

178

return "HelloService v1.0 - Unix Domain Socket RMI Implementation";

179

}

180

}

181

```

182

183

### AFUNIXRegistry

184

185

Unix Domain Socket-based RMI registry for service discovery and binding without network exposure.

186

187

```java { .api }

188

/**

189

* Unix Domain Socket RMI registry

190

*/

191

public class AFUNIXRegistry extends AFRegistry {

192

193

/**

194

* Creates a new registry bound to the specified address

195

* @param address The socket address for the registry

196

* @return AFUNIXRegistry instance

197

* @throws RemoteException if registry creation fails

198

*/

199

public static AFUNIXRegistry createRegistry(AFUNIXSocketAddress address) throws RemoteException;

200

201

/**

202

* Gets a reference to an existing registry

203

* @param address The socket address of the registry

204

* @return AFUNIXRegistry instance

205

* @throws RemoteException if registry access fails

206

*/

207

public static AFUNIXRegistry getRegistry(AFUNIXSocketAddress address) throws RemoteException;

208

209

// Registry operations

210

public void bind(String name, Remote obj) throws RemoteException, AlreadyBoundException;

211

public void rebind(String name, Remote obj) throws RemoteException;

212

public void unbind(String name) throws RemoteException, NotBoundException;

213

public Remote lookup(String name) throws RemoteException, NotBoundException;

214

public String[] list() throws RemoteException;

215

216

// Registry properties

217

public AFUNIXSocketAddress getRegistryAddress();

218

public boolean isRegistryRunning();

219

}

220

```

221

222

**Registry Usage Examples:**

223

224

```java

225

// Registry server

226

public class RegistryServer {

227

public static void main(String[] args) throws Exception {

228

File registrySocket = new File("/tmp/rmi-registry.sock");

229

AFUNIXSocketAddress registryAddr = AFUNIXSocketAddress.of(registrySocket);

230

231

// Create registry

232

AFUNIXRegistry registry = AFUNIXRegistry.createRegistry(registryAddr);

233

234

// Register multiple services

235

HelloService helloService = new HelloServiceImpl(registryAddr);

236

CalculatorService calcService = new CalculatorServiceImpl(registryAddr);

237

238

registry.bind("HelloService", helloService);

239

registry.bind("CalculatorService", calcService);

240

241

System.out.println("Registry running with services:");

242

String[] services = registry.list();

243

for (String service : services) {

244

System.out.println(" - " + service);

245

}

246

247

// Keep registry running

248

Thread.sleep(Long.MAX_VALUE);

249

}

250

}

251

252

// Service discovery client

253

public class ServiceDiscoveryClient {

254

public static void main(String[] args) throws Exception {

255

File registrySocket = new File("/tmp/rmi-registry.sock");

256

AFUNIXSocketAddress registryAddr = AFUNIXSocketAddress.of(registrySocket);

257

258

// Connect to registry

259

AFUNIXRegistry registry = AFUNIXRegistry.getRegistry(registryAddr);

260

261

// List available services

262

System.out.println("Available services:");

263

String[] services = registry.list();

264

for (String serviceName : services) {

265

System.out.println(" - " + serviceName);

266

267

// Look up service details

268

Remote service = registry.lookup(serviceName);

269

if (service instanceof AFRMIService) {

270

AFRMIService afService = (AFRMIService) service;

271

System.out.println(" Info: " + afService.getServiceInfo());

272

System.out.println(" Address: " + afService.getServiceAddress());

273

}

274

}

275

}

276

}

277

```

278

279

## Advanced RMI Features

280

281

### Custom RMI Socket Factory

282

283

```java { .api }

284

/**

285

* Base class for AF RMI socket factories

286

*/

287

public abstract class AFRMISocketFactory implements RMIClientSocketFactory, RMIServerSocketFactory {

288

289

// Factory configuration

290

public abstract void setSocketAddress(AFSocketAddress address);

291

public abstract AFSocketAddress getSocketAddress();

292

293

// Socket creation with custom parameters

294

public abstract Socket createSocket(String host, int port, SocketAddress localAddr, int timeout) throws IOException;

295

public abstract ServerSocket createServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException;

296

297

// Factory management

298

public static void setDefaultSocketFactory(AFRMISocketFactory factory);

299

public static AFRMISocketFactory getDefaultSocketFactory();

300

}

301

```

302

303

**Custom Factory Example:**

304

305

```java

306

// Custom RMI socket factory with connection pooling

307

public class PooledRMISocketFactory extends AFUNIXRMISocketFactory {

308

private final ObjectPool<Socket> socketPool;

309

private final int maxPoolSize;

310

311

public PooledRMISocketFactory(AFUNIXSocketAddress address, int maxPoolSize) throws IOException {

312

super(address);

313

this.maxPoolSize = maxPoolSize;

314

this.socketPool = new SocketPool(maxPoolSize);

315

}

316

317

@Override

318

public Socket createSocket(String host, int port) throws IOException {

319

Socket socket = socketPool.acquire();

320

if (socket == null || socket.isClosed()) {

321

socket = super.createSocket(host, port);

322

}

323

return new PooledSocket(socket, socketPool);

324

}

325

326

private static class SocketPool extends ObjectPool<Socket> {

327

public SocketPool(int maxSize) {

328

super(maxSize);

329

}

330

331

@Override

332

protected Socket createObject() {

333

return null; // Created externally

334

}

335

336

@Override

337

protected boolean validateObject(Socket socket) {

338

return socket != null && !socket.isClosed() && socket.isConnected();

339

}

340

}

341

342

private static class PooledSocket extends Socket {

343

private final Socket delegate;

344

private final ObjectPool<Socket> pool;

345

346

public PooledSocket(Socket delegate, ObjectPool<Socket> pool) {

347

this.delegate = delegate;

348

this.pool = pool;

349

}

350

351

@Override

352

public void close() throws IOException {

353

// Return to pool instead of closing

354

pool.release(delegate);

355

}

356

357

// Delegate all other methods to the wrapped socket

358

// ... delegation methods

359

}

360

}

361

```

362

363

### RMI Security and Configuration

364

365

```java

366

// RMI security configuration for Unix Domain Sockets

367

public class RMISecurityConfig {

368

369

public static void configureSecureRMI(AFUNIXSocketAddress address) throws Exception {

370

// Set socket factory

371

AFUNIXRMISocketFactory factory = AFUNIXRMISocketFactory.getInstance(address);

372

373

// Configure RMI properties

374

System.setProperty("java.rmi.server.hostname", address.toString());

375

System.setProperty("java.rmi.server.randomIDs", "true");

376

System.setProperty("java.rmi.dgc.leaseValue", "600000"); // 10 minutes

377

378

// Install security manager if needed

379

if (System.getSecurityManager() == null) {

380

System.setSecurityManager(new SecurityManager());

381

}

382

383

// Set socket factory as default

384

AFRMISocketFactory.setDefaultSocketFactory(factory);

385

}

386

387

public static void configurePeerCredentials(AFUNIXRMISocketFactory factory) throws IOException {

388

// Enable peer credential checking

389

factory.setSocketAddress(factory.getSocketAddress());

390

391

// Custom socket creation with credential validation

392

// Implementation would check peer credentials on connection

393

}

394

}

395

```

396

397

### Multi-Service RMI Management

398

399

```java

400

// RMI service manager for multiple services

401

public class RMIServiceManager {

402

private final AFUNIXRegistry registry;

403

private final Map<String, Remote> services = new ConcurrentHashMap<>();

404

private final AFUNIXRMISocketFactory socketFactory;

405

406

public RMIServiceManager(AFUNIXSocketAddress registryAddress) throws Exception {

407

this.socketFactory = AFUNIXRMISocketFactory.getInstance(registryAddress);

408

this.registry = AFUNIXRegistry.createRegistry(registryAddress);

409

}

410

411

public void registerService(String name, Remote service) throws RemoteException {

412

try {

413

// Export service with Unix Domain Socket factory

414

Remote stub = UnicastRemoteObject.exportObject(service, 0, socketFactory, socketFactory);

415

416

// Bind in registry

417

registry.bind(name, stub);

418

services.put(name, service);

419

420

System.out.println("Registered service: " + name);

421

} catch (AlreadyBoundException e) {

422

// Rebind if already exists

423

registry.rebind(name, service);

424

services.put(name, service);

425

System.out.println("Re-registered service: " + name);

426

}

427

}

428

429

public void unregisterService(String name) throws RemoteException, NotBoundException {

430

registry.unbind(name);

431

Remote service = services.remove(name);

432

433

if (service != null) {

434

try {

435

UnicastRemoteObject.unexportObject(service, true);

436

} catch (NoSuchObjectException e) {

437

// Service already unexported

438

}

439

}

440

441

System.out.println("Unregistered service: " + name);

442

}

443

444

public String[] listServices() throws RemoteException {

445

return registry.list();

446

}

447

448

public void shutdown() throws RemoteException {

449

// Unregister all services

450

for (String serviceName : services.keySet()) {

451

try {

452

unregisterService(serviceName);

453

} catch (Exception e) {

454

System.err.println("Error unregistering " + serviceName + ": " + e.getMessage());

455

}

456

}

457

458

// Shutdown registry (implementation specific)

459

// registry.shutdown();

460

}

461

}

462

```

463

464

## Error Handling

465

466

RMI-specific exception handling patterns:

467

468

```java { .api }

469

// RMI exceptions

470

public class RemoteException extends IOException;

471

public class NotBoundException extends Exception;

472

public class AlreadyBoundException extends Exception;

473

public class NoSuchObjectException extends RemoteException;

474

public class ConnectException extends RemoteException;

475

public class ServerException extends RemoteException;

476

```

477

478

**Error Handling Examples:**

479

480

```java

481

try {

482

AFUNIXRegistry registry = AFUNIXRegistry.getRegistry(registryAddress);

483

HelloService service = (HelloService) registry.lookup("HelloService");

484

485

String result = service.sayHello("Client");

486

System.out.println("Result: " + result);

487

488

} catch (NotBoundException e) {

489

System.err.println("Service not found in registry: " + e.getMessage());

490

} catch (ConnectException e) {

491

System.err.println("Failed to connect to RMI service: " + e.getMessage());

492

} catch (ServerException e) {

493

System.err.println("Server-side error: " + e.getMessage());

494

} catch (RemoteException e) {

495

System.err.println("RMI communication error: " + e.getMessage());

496

} catch (ClassCastException e) {

497

System.err.println("Service interface mismatch: " + e.getMessage());

498

}

499

500

// Registry binding error handling

501

try {

502

registry.bind("MyService", serviceImpl);

503

} catch (AlreadyBoundException e) {

504

System.out.println("Service already bound, rebinding...");

505

registry.rebind("MyService", serviceImpl);

506

} catch (RemoteException e) {

507

System.err.println("Failed to bind service: " + e.getMessage());

508

}

509

```

510

511

## Performance Considerations

512

513

### Connection Management

514

515

```java

516

// Efficient RMI connection handling

517

public class OptimizedRMIClient {

518

private final AFUNIXRegistry registry;

519

private final Map<Class<?>, Remote> serviceCache = new ConcurrentHashMap<>();

520

521

public OptimizedRMIClient(AFUNIXSocketAddress registryAddr) throws RemoteException {

522

this.registry = AFUNIXRegistry.getRegistry(registryAddr);

523

}

524

525

@SuppressWarnings("unchecked")

526

public <T extends Remote> T getService(String serviceName, Class<T> serviceInterface) throws RemoteException, NotBoundException {

527

// Check cache first

528

T service = (T) serviceCache.get(serviceInterface);

529

if (service != null) {

530

try {

531

// Test connection

532

if (service instanceof AFRMIService) {

533

((AFRMIService) service).isServiceAvailable();

534

}

535

return service;

536

} catch (RemoteException e) {

537

// Service unavailable, remove from cache

538

serviceCache.remove(serviceInterface);

539

}

540

}

541

542

// Look up service

543

service = (T) registry.lookup(serviceName);

544

serviceCache.put(serviceInterface, service);

545

return service;

546

}

547

548

public void clearCache() {

549

serviceCache.clear();

550

}

551

}

552

```