0
# Cross-Language Features
1
2
Complete Python and C++ integration enabling polyglot distributed computing workflows with seamless interoperability across language boundaries.
3
4
## Capabilities
5
6
### Python Integration
7
8
Execute Python functions and create Python actors from Java code with full type safety.
9
10
```java { .api }
11
// Python function representation
12
public class PyFunction<R> {
13
/**
14
* Create Python function reference.
15
* @param moduleName Python module name
16
* @param functionName Python function name
17
* @return PyFunction instance for untyped result
18
*/
19
public static PyFunction<Object> of(String moduleName, String functionName);
20
21
/**
22
* Create typed Python function reference.
23
* @param moduleName Python module name
24
* @param functionName Python function name
25
* @param returnType Expected return type
26
* @return PyFunction instance for typed result
27
*/
28
public static <R> PyFunction<R> of(String moduleName, String functionName, Class<R> returnType);
29
}
30
31
// Python task execution (0-6 Object parameters)
32
public static <R> PyTaskCaller<R> task(PyFunction<R> pyFunction);
33
public static <R> PyTaskCaller<R> task(PyFunction<R> pyFunction, Object obj0);
34
public static <R> PyTaskCaller<R> task(PyFunction<R> pyFunction, Object obj0, Object obj1);
35
public static <R> PyTaskCaller<R> task(PyFunction<R> pyFunction, Object obj0, Object obj1, Object obj2);
36
public static <R> PyTaskCaller<R> task(PyFunction<R> pyFunction, Object obj0, Object obj1, Object obj2, Object obj3);
37
public static <R> PyTaskCaller<R> task(PyFunction<R> pyFunction, Object obj0, Object obj1, Object obj2, Object obj3, Object obj4);
38
public static <R> PyTaskCaller<R> task(PyFunction<R> pyFunction, Object obj0, Object obj1, Object obj2, Object obj3, Object obj4, Object obj5);
39
```
40
41
**Usage Examples:**
42
43
```java
44
import io.ray.api.Ray;
45
import io.ray.api.ObjectRef;
46
import io.ray.api.function.PyFunction;
47
48
public class PythonIntegration {
49
public static void main(String[] args) {
50
Ray.init();
51
52
// Call Python function without type specification
53
PyFunction<Object> pyFunc = PyFunction.of("math", "sqrt");
54
ObjectRef<Object> result1 = Ray.task(pyFunc, 16.0).remote();
55
System.out.println("Square root: " + Ray.get(result1)); // 4.0
56
57
// Call Python function with type safety
58
PyFunction<Double> typedFunc = PyFunction.of("math", "pow", Double.class);
59
ObjectRef<Double> result2 = Ray.task(typedFunc, 2.0, 3.0).remote();
60
System.out.println("Power: " + Ray.get(result2)); // 8.0
61
62
// Call custom Python module
63
PyFunction<String> customFunc = PyFunction.of("my_module", "process_data", String.class);
64
ObjectRef<String> result3 = Ray.task(customFunc, "input data", 42).remote();
65
System.out.println("Processed: " + Ray.get(result3));
66
67
Ray.shutdown();
68
}
69
}
70
```
71
72
### Python Actors
73
74
Create and interact with Python actors from Java.
75
76
```java { .api }
77
// Python actor class representation
78
public class PyActorClass {
79
// Represents a Python actor class
80
}
81
82
// Python actor method representation
83
public class PyActorMethod {
84
// Represents a Python actor method
85
}
86
87
// Python actor creation (0-6 Object parameters)
88
public static PyActorCreator actor(PyActorClass pyActorClass);
89
public static PyActorCreator actor(PyActorClass pyActorClass, Object obj0);
90
public static PyActorCreator actor(PyActorClass pyActorClass, Object obj0, Object obj1);
91
public static PyActorCreator actor(PyActorClass pyActorClass, Object obj0, Object obj1, Object obj2);
92
public static PyActorCreator actor(PyActorClass pyActorClass, Object obj0, Object obj1, Object obj2, Object obj3);
93
public static PyActorCreator actor(PyActorClass pyActorClass, Object obj0, Object obj1, Object obj2, Object obj3, Object obj4);
94
public static PyActorCreator actor(PyActorClass pyActorClass, Object obj0, Object obj1, Object obj2, Object obj3, Object obj4, Object obj5);
95
96
public interface PyActorHandle extends BaseActorHandle {
97
// Python actor handle with method calling capability
98
}
99
100
public interface PyActorCreator {
101
/**
102
* Create Python actor remotely.
103
* @return PyActorHandle for calling Python actor methods
104
*/
105
PyActorHandle remote();
106
}
107
108
public interface PyActorTaskCaller<R> {
109
/**
110
* Execute Python actor method call.
111
* @return ObjectRef to the method result
112
*/
113
ObjectRef<R> remote();
114
}
115
```
116
117
**Usage Examples:**
118
119
```java
120
// Assuming you have a Python actor class like:
121
// class Counter:
122
// def __init__(self, initial_value):
123
// self.count = initial_value
124
//
125
// def increment(self):
126
// self.count += 1
127
// return self.count
128
//
129
// def get_value(self):
130
// return self.count
131
132
public class PythonActors {
133
public static void main(String[] args) {
134
Ray.init();
135
136
// Create Python actor class reference
137
PyActorClass counterClass = new PyActorClass(); // Implementation details abstracted
138
139
// Create Python actor with constructor arguments
140
PyActorHandle counter = Ray.actor(counterClass, 10).remote();
141
142
// Call Python actor methods
143
// Note: Actual method calling syntax may vary in implementation
144
// This shows the conceptual approach
145
146
Ray.shutdown();
147
}
148
}
149
```
150
151
### C++ Integration
152
153
Execute C++ functions and create C++ actors from Java code.
154
155
```java { .api }
156
// C++ function representation
157
public class CppFunction<R> {
158
// Represents a C++ function
159
}
160
161
// C++ actor class representation
162
public class CppActorClass {
163
// Represents a C++ actor class
164
}
165
166
// C++ actor method representation
167
public class CppActorMethod {
168
// Represents a C++ actor method
169
}
170
171
// C++ task execution (0-6 Object parameters)
172
public static <R> CppTaskCaller<R> task(CppFunction<R> cppFunction);
173
public static <R> CppTaskCaller<R> task(CppFunction<R> cppFunction, Object obj0);
174
public static <R> CppTaskCaller<R> task(CppFunction<R> cppFunction, Object obj0, Object obj1);
175
public static <R> CppTaskCaller<R> task(CppFunction<R> cppFunction, Object obj0, Object obj1, Object obj2);
176
public static <R> CppTaskCaller<R> task(CppFunction<R> cppFunction, Object obj0, Object obj1, Object obj2, Object obj3);
177
public static <R> CppTaskCaller<R> task(CppFunction<R> cppFunction, Object obj0, Object obj1, Object obj2, Object obj3, Object obj4);
178
public static <R> CppTaskCaller<R> task(CppFunction<R> cppFunction, Object obj0, Object obj1, Object obj2, Object obj3, Object obj4, Object obj5);
179
180
// C++ actor creation (0-6 Object parameters)
181
public static CppActorCreator actor(CppActorClass cppActorClass);
182
public static CppActorCreator actor(CppActorClass cppActorClass, Object obj0);
183
public static CppActorCreator actor(CppActorClass cppActorClass, Object obj0, Object obj1);
184
public static CppActorCreator actor(CppActorClass cppActorClass, Object obj0, Object obj1, Object obj2);
185
public static CppActorCreator actor(CppActorClass cppActorClass, Object obj0, Object obj1, Object obj2, Object obj3);
186
public static CppActorCreator actor(CppActorClass cppActorClass, Object obj0, Object obj1, Object obj2, Object obj3, Object obj4);
187
public static CppActorCreator actor(CppActorClass cppActorClass, Object obj0, Object obj1, Object obj2, Object obj3, Object obj4, Object obj5);
188
```
189
190
**Usage Examples:**
191
192
```java
193
import io.ray.api.Ray;
194
import io.ray.api.ObjectRef;
195
import io.ray.api.function.CppFunction;
196
197
public class CppIntegration {
198
public static void main(String[] args) {
199
Ray.init();
200
201
// Create C++ function reference
202
CppFunction<Double> cppMathFunc = new CppFunction<>(); // Implementation details abstracted
203
204
// Call C++ function
205
ObjectRef<Double> result = Ray.task(cppMathFunc, 5.0, 3.0).remote();
206
System.out.println("C++ result: " + Ray.get(result));
207
208
Ray.shutdown();
209
}
210
}
211
```
212
213
### Cross-Language Handle Types
214
215
Handle different types of actors from different languages.
216
217
```java { .api }
218
// Base actor handle (language-agnostic)
219
public interface BaseActorHandle {
220
ActorId getId();
221
void kill();
222
void kill(boolean noRestart);
223
}
224
225
// Java actor handle (typed)
226
public interface ActorHandle<A> extends BaseActorHandle {
227
// Type-safe method calling for Java actors
228
}
229
230
// Python actor handle
231
public interface PyActorHandle extends BaseActorHandle {
232
// Python-specific actor operations
233
}
234
235
// C++ actor handle
236
public interface CppActorHandle extends BaseActorHandle {
237
// C++-specific actor operations
238
}
239
```
240
241
## Cross-Language Task Callers
242
243
### Task Caller Interfaces
244
245
```java { .api }
246
// Java task caller
247
public interface TaskCaller<R> {
248
ObjectRef<R> remote();
249
}
250
251
// Python task caller
252
public interface PyTaskCaller<R> {
253
ObjectRef<R> remote();
254
}
255
256
// C++ task caller
257
public interface CppTaskCaller<R> {
258
ObjectRef<R> remote();
259
}
260
261
// Actor task callers
262
public interface ActorTaskCaller<R> {
263
ObjectRef<R> remote();
264
}
265
266
public interface PyActorTaskCaller<R> {
267
ObjectRef<R> remote();
268
}
269
270
public interface CppActorTaskCaller<R> {
271
ObjectRef<R> remote();
272
}
273
```
274
275
## Practical Cross-Language Workflows
276
277
### Polyglot Data Pipeline
278
279
```java
280
public class PolyglotPipeline {
281
public static void main(String[] args) {
282
Ray.init();
283
284
// Step 1: Load data with Java
285
ObjectRef<List<String>> rawData = Ray.task(JavaDataLoader::loadData, "source.csv").remote();
286
287
// Step 2: Process with Python (using pandas, numpy, etc.)
288
PyFunction<Object> pythonProcessor = PyFunction.of("data_processing", "clean_and_transform");
289
ObjectRef<Object> cleanedData = Ray.task(pythonProcessor, rawData).remote();
290
291
// Step 3: Analyze with C++ (high-performance algorithms)
292
CppFunction<Double> cppAnalyzer = new CppFunction<>(); // Implementation abstracted
293
ObjectRef<Double> analysisResult = Ray.task(cppAnalyzer, cleanedData).remote();
294
295
// Step 4: Generate report with Java
296
ObjectRef<String> report = Ray.task(JavaReportGenerator::generateReport, analysisResult).remote();
297
298
System.out.println("Final report: " + Ray.get(report));
299
300
Ray.shutdown();
301
}
302
}
303
304
class JavaDataLoader {
305
public static List<String> loadData(String source) {
306
// Java data loading logic
307
return Arrays.asList("data1", "data2", "data3");
308
}
309
}
310
311
class JavaReportGenerator {
312
public static String generateReport(Double result) {
313
return "Analysis Result: " + result;
314
}
315
}
316
```
317
318
### Mixed-Language Actor System
319
320
```java
321
public class MixedActorSystem {
322
public static void main(String[] args) {
323
Ray.init();
324
325
// Create Java coordinator actor
326
ActorHandle<Coordinator> coordinator = Ray.actor(Coordinator::new).remote();
327
328
// Create Python worker actors
329
PyActorClass pythonWorkerClass = new PyActorClass(); // Implementation abstracted
330
PyActorHandle pythonWorker1 = Ray.actor(pythonWorkerClass, "worker1").remote();
331
PyActorHandle pythonWorker2 = Ray.actor(pythonWorkerClass, "worker2").remote();
332
333
// Create C++ compute actor
334
CppActorClass cppComputeClass = new CppActorClass(); // Implementation abstracted
335
CppActorHandle cppCompute = Ray.actor(cppComputeClass).remote();
336
337
// Coordinate work across languages
338
ObjectRef<String> result = coordinator.task(Coordinator::orchestrateWork,
339
Arrays.asList(pythonWorker1, pythonWorker2), cppCompute).remote();
340
341
System.out.println("Orchestration result: " + Ray.get(result));
342
343
Ray.shutdown();
344
}
345
}
346
347
class Coordinator {
348
public String orchestrateWork(List<PyActorHandle> pythonWorkers, CppActorHandle cppCompute) {
349
// Coordinate work between different language actors
350
// Implementation would involve calling methods on the different actor types
351
return "Work orchestrated successfully";
352
}
353
}
354
```
355
356
## Exception Handling
357
358
### Cross-Language Exceptions
359
360
```java { .api }
361
/**
362
* Exception thrown when cross-language operations fail.
363
*/
364
public class CrossLanguageException extends RayException {
365
// Cross-language integration specific exceptions
366
}
367
```
368
369
**Usage Example:**
370
371
```java
372
try {
373
PyFunction<String> pyFunc = PyFunction.of("invalid_module", "invalid_function", String.class);
374
ObjectRef<String> result = Ray.task(pyFunc, "data").remote();
375
String value = Ray.get(result);
376
} catch (CrossLanguageException e) {
377
System.out.println("Cross-language call failed: " + e.getMessage());
378
} catch (RayTaskException e) {
379
System.out.println("Python task failed: " + e.getMessage());
380
}
381
```
382
383
## Best Practices
384
385
### Type Safety
386
387
```java
388
// Use typed function references when possible
389
PyFunction<Double> mathFunc = PyFunction.of("math", "sqrt", Double.class);
390
ObjectRef<Double> result = Ray.task(mathFunc, 25.0).remote();
391
Double value = Ray.get(result); // Type-safe result
392
393
// Handle untyped results carefully
394
PyFunction<Object> untypedFunc = PyFunction.of("my_module", "complex_function");
395
ObjectRef<Object> untypedResult = Ray.task(untypedFunc, "input").remote();
396
Object value = Ray.get(untypedResult);
397
// Cast carefully based on expected Python return type
398
```
399
400
### Data Serialization
401
402
```java
403
// Ray handles serialization across languages automatically
404
// Complex Java objects are serialized and can be used in Python/C++
405
List<CustomData> javaData = createComplexData();
406
ObjectRef<List<CustomData>> dataRef = Ray.put(javaData);
407
408
// Pass to Python function
409
PyFunction<Object> processor = PyFunction.of("processor", "handle_java_data");
410
ObjectRef<Object> result = Ray.task(processor, dataRef).remote();
411
```
412
413
### Error Handling
414
415
```java
416
// Always wrap cross-language calls in appropriate try-catch blocks
417
try {
418
PyFunction<String> pyFunc = PyFunction.of("data_module", "process", String.class);
419
ObjectRef<String> result = Ray.task(pyFunc, inputData).remote();
420
String processedData = Ray.get(result);
421
// Handle successful result
422
} catch (CrossLanguageException e) {
423
// Handle cross-language integration errors
424
System.err.println("Cross-language error: " + e.getMessage());
425
} catch (RayTaskException e) {
426
// Handle Python/C++ task execution errors
427
System.err.println("Task execution error: " + e.getMessage());
428
} catch (RayException e) {
429
// Handle other Ray-related errors
430
System.err.println("Ray error: " + e.getMessage());
431
}
432
```