or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-processing.mddistributed-execution.mddynamic-compilation.mdexecution-contexts.mdhttp-services.mdindex.mdruntime-providers.mdtransaction-management.md

dynamic-compilation.mddocs/

0

# Dynamic Compilation and Interpretation

1

2

Dynamic Scala compilation and interpretation capabilities that enable runtime code generation, interactive development, and flexible application behavior modification within Spark applications running on the CDAP platform.

3

4

## Capabilities

5

6

### Default Spark Compiler

7

8

Scala compiler implementation that provides dynamic compilation capabilities for runtime code generation and flexible application behavior.

9

10

```scala { .api }

11

/**

12

* Default compiler for dynamic Scala code compilation in Spark

13

* Enables runtime compilation of Scala code within CDAP Spark applications

14

*/

15

class DefaultSparkCompiler extends SparkCompiler {

16

/**

17

* Compiles Scala code and returns the resulting class

18

* @param code Scala source code to compile

19

* @return Option containing the compiled class, or None if compilation fails

20

* @throws CompilationException if compilation errors occur

21

*/

22

def compile(code: String): Option[Class[_]]

23

24

/**

25

* Compiles Scala code with a specific class name

26

* @param className Fully qualified name for the compiled class

27

* @param code Scala source code to compile

28

* @return Option containing the compiled class, or None if compilation fails

29

* @throws CompilationException if compilation errors occur

30

*/

31

def compileClass(className: String, code: String): Option[Class[_]]

32

33

/**

34

* Compiles multiple Scala source files

35

* @param sources Map of class names to source code

36

* @return Map of class names to compiled classes

37

* @throws CompilationException if compilation errors occur

38

*/

39

def compileClasses(sources: Map[String, String]): Map[String, Class[_]]

40

41

/**

42

* Sets the compiler class path

43

* @param classpath Array of classpath entries

44

*/

45

def setClassPath(classpath: Array[String]): Unit

46

47

/**

48

* Gets the current compiler settings

49

* @return CompilerSettings containing current configuration

50

*/

51

def getSettings: CompilerSettings

52

53

/**

54

* Validates Scala code syntax without compilation

55

* @param code Scala source code to validate

56

* @return ValidationResult containing validation status and errors

57

*/

58

def validate(code: String): ValidationResult

59

}

60

```

61

62

### Default Spark Interpreter

63

64

Scala interpreter implementation that provides interactive code execution and REPL-like capabilities within Spark applications.

65

66

```scala { .api }

67

/**

68

* Default interpreter for dynamic Scala code execution in Spark

69

* Provides REPL-like capabilities for interactive development

70

*/

71

class DefaultSparkInterpreter extends SparkInterpreter {

72

/**

73

* Interprets and executes Scala code

74

* @param code Scala code to interpret and execute

75

* @throws InterpretationException if interpretation or execution fails

76

*/

77

def interpret(code: String): Unit

78

79

/**

80

* Interprets code and returns the result

81

* @param code Scala expression to evaluate

82

* @tparam T Expected return type

83

* @return Result of the expression evaluation

84

* @throws InterpretationException if interpretation fails

85

*/

86

def interpretAndReturn[T](code: String): T

87

88

/**

89

* Binds a variable to the interpreter context

90

* @param name Variable name

91

* @param value Variable value

92

* @tparam T Type of the value

93

*/

94

def bind[T](name: String, value: T): Unit

95

96

/**

97

* Binds a variable with explicit type

98

* @param name Variable name

99

* @param tpe Type information

100

* @param value Variable value

101

*/

102

def bind(name: String, tpe: String, value: Any): Unit

103

104

/**

105

* Resets the interpreter state

106

* Clears all bindings and compiled code

107

*/

108

def reset(): Unit

109

110

/**

111

* Gets a bound variable value

112

* @param name Variable name

113

* @tparam T Expected type

114

* @return Variable value

115

* @throws NoSuchElementException if variable not found

116

*/

117

def get[T](name: String): T

118

119

/**

120

* Checks if a variable is bound

121

* @param name Variable name

122

* @return true if variable exists in interpreter context

123

*/

124

def isBound(name: String): Boolean

125

126

/**

127

* Gets all bound variable names

128

* @return Set of bound variable names

129

*/

130

def getBoundNames: Set[String]

131

}

132

```

133

134

### Spark Compiler Interface

135

136

Base interface defining the contract for Spark compiler implementations.

137

138

```scala { .api }

139

/**

140

* Interface for Spark compiler implementations

141

* Defines the contract for dynamic Scala compilation

142

*/

143

trait SparkCompiler {

144

/**

145

* Compiles Scala source code

146

* @param code Source code to compile

147

* @return Option containing compiled class or None if compilation fails

148

*/

149

def compile(code: String): Option[Class[_]]

150

151

/**

152

* Compiles code with specific class name

153

* @param className Target class name

154

* @param code Source code to compile

155

* @return Option containing compiled class or None if compilation fails

156

*/

157

def compileClass(className: String, code: String): Option[Class[_]]

158

159

/**

160

* Gets compiler configuration settings

161

* @return Current compiler settings

162

*/

163

def getSettings: CompilerSettings

164

}

165

```

166

167

### Spark Interpreter Interface

168

169

Base interface defining the contract for Spark interpreter implementations.

170

171

```scala { .api }

172

/**

173

* Interface for Spark interpreter implementations

174

* Defines the contract for interactive Scala code execution

175

*/

176

trait SparkInterpreter {

177

/**

178

* Interprets and executes Scala code

179

* @param code Code to interpret

180

*/

181

def interpret(code: String): Unit

182

183

/**

184

* Binds a variable to interpreter context

185

* @param name Variable name

186

* @param value Variable value

187

*/

188

def bind(name: String, value: Any): Unit

189

190

/**

191

* Resets interpreter state

192

*/

193

def reset(): Unit

194

}

195

```

196

197

## Usage Examples

198

199

**Dynamic Compilation:**

200

201

```scala

202

import co.cask.cdap.app.runtime.spark.dynamic.DefaultSparkCompiler

203

204

// Create compiler instance

205

val compiler = new DefaultSparkCompiler()

206

207

// Set up classpath

208

compiler.setClassPath(Array(

209

"/path/to/spark-core.jar",

210

"/path/to/cdap-api.jar"

211

))

212

213

// Compile simple class

214

val code = """

215

class DynamicTransform {

216

def transform(input: String): String = {

217

input.toUpperCase.reverse

218

}

219

}

220

"""

221

222

compiler.compile(code) match {

223

case Some(clazz) =>

224

// Create instance and use

225

val instance = clazz.newInstance()

226

val method = clazz.getMethod("transform", classOf[String])

227

val result = method.invoke(instance, "hello world")

228

println(s"Result: $result") // Result: DLROW OLLEH

229

230

case None =>

231

println("Compilation failed")

232

}

233

234

// Compile with specific class name

235

val transformerCode = """

236

package com.example

237

class CustomTransformer(multiplier: Int) {

238

def process(values: Array[Int]): Array[Int] = {

239

values.map(_ * multiplier)

240

}

241

}

242

"""

243

244

compiler.compileClass("com.example.CustomTransformer", transformerCode) match {

245

case Some(clazz) =>

246

val constructor = clazz.getConstructor(classOf[Int])

247

val transformer = constructor.newInstance(Int.box(2))

248

// Use transformer...

249

case None =>

250

println("Compilation failed")

251

}

252

```

253

254

**Interactive Interpretation:**

255

256

```scala

257

import co.cask.cdap.app.runtime.spark.dynamic.DefaultSparkInterpreter

258

259

// Create interpreter instance

260

val interpreter = new DefaultSparkInterpreter()

261

262

// Bind variables

263

interpreter.bind("sparkContext", sparkContext)

264

interpreter.bind("inputData", Array(1, 2, 3, 4, 5))

265

266

// Execute code interactively

267

interpreter.interpret("val doubled = inputData.map(_ * 2)")

268

interpreter.interpret("println(s\"Doubled: ${doubled.mkString(', ')}\")")

269

270

// Get results back

271

val result = interpreter.interpretAndReturn[Array[Int]]("doubled")

272

println(s"Result array: ${result.mkString(", ")}")

273

274

// Check bindings

275

if (interpreter.isBound("doubled")) {

276

val boundValue = interpreter.get[Array[Int]]("doubled")

277

println(s"Bound value: ${boundValue.mkString(", ")}")

278

}

279

280

// Reset interpreter

281

interpreter.reset()

282

```

283

284

**Spark Integration Example:**

285

286

```scala

287

import org.apache.spark.SparkContext

288

import co.cask.cdap.app.runtime.spark.dynamic.{DefaultSparkCompiler, DefaultSparkInterpreter}

289

290

// Create Spark RDD processing with dynamic code

291

def processWithDynamicCode(sc: SparkContext,

292

data: Array[String],

293

transformCode: String): Array[String] = {

294

295

val compiler = new DefaultSparkCompiler()

296

297

// Compile transform function

298

val wrapperCode = s"""

299

class DynamicProcessor {

300

def process(input: String): String = {

301

$transformCode

302

}

303

}

304

"""

305

306

compiler.compile(wrapperCode) match {

307

case Some(clazz) =>

308

// Create RDD and apply dynamic transformation

309

val rdd = sc.parallelize(data)

310

val transformedRDD = rdd.map { item =>

311

val processor = clazz.newInstance()

312

val method = clazz.getMethod("process", classOf[String])

313

method.invoke(processor, item).asInstanceOf[String]

314

}

315

transformedRDD.collect()

316

317

case None =>

318

throw new RuntimeException("Failed to compile transformation code")

319

}

320

}

321

322

// Usage

323

val inputData = Array("apple", "banana", "cherry")

324

val transformCode = "input.toUpperCase + \"_PROCESSED\""

325

val results = processWithDynamicCode(sparkContext, inputData, transformCode)

326

// Results: Array("APPLE_PROCESSED", "BANANA_PROCESSED", "CHERRY_PROCESSED")

327

```

328

329

**REPL-like Development:**

330

331

```scala

332

import co.cask.cdap.app.runtime.spark.dynamic.DefaultSparkInterpreter

333

334

// Create development environment

335

class SparkREPL(sparkContext: SparkContext) {

336

private val interpreter = new DefaultSparkInterpreter()

337

338

// Initialize with common imports and bindings

339

interpreter.interpret("import org.apache.spark.SparkContext")

340

interpreter.interpret("import org.apache.spark.rdd.RDD")

341

interpreter.bind("sc", sparkContext)

342

343

def execute(code: String): Unit = {

344

try {

345

interpreter.interpret(code)

346

} catch {

347

case e: Exception => println(s"Error: ${e.getMessage}")

348

}

349

}

350

351

def bindData(name: String, data: Any): Unit = {

352

interpreter.bind(name, data)

353

}

354

355

def getResult[T](expression: String): T = {

356

interpreter.interpretAndReturn[T](expression)

357

}

358

}

359

360

// Usage

361

val repl = new SparkREPL(sparkContext)

362

363

// Bind data

364

repl.bindData("numbers", Array(1, 2, 3, 4, 5))

365

366

// Execute transformations

367

repl.execute("val rdd = sc.parallelize(numbers)")

368

repl.execute("val squares = rdd.map(x => x * x)")

369

repl.execute("val sum = squares.reduce(_ + _)")

370

371

// Get results

372

val finalSum = repl.getResult[Int]("sum")

373

println(s"Sum of squares: $finalSum") // Sum of squares: 55

374

```

375

376

## Types

377

378

```scala { .api }

379

/**

380

* Compiler configuration settings

381

*/

382

case class CompilerSettings(

383

/**

384

* Classpath entries for compilation

385

*/

386

classpath: Array[String],

387

388

/**

389

* Output directory for compiled classes

390

*/

391

outputDirectory: String,

392

393

/**

394

* Scala compiler options

395

*/

396

options: Map[String, String],

397

398

/**

399

* Maximum compilation time in milliseconds

400

*/

401

maxCompilationTime: Long

402

)

403

404

/**

405

* Result of code validation

406

*/

407

case class ValidationResult(

408

/**

409

* Whether the code is syntactically valid

410

*/

411

isValid: Boolean,

412

413

/**

414

* Compilation errors if any

415

*/

416

errors: List[CompilationError],

417

418

/**

419

* Compilation warnings if any

420

*/

421

warnings: List[CompilationWarning]

422

)

423

424

/**

425

* Compilation error information

426

*/

427

case class CompilationError(

428

/**

429

* Error message

430

*/

431

message: String,

432

433

/**

434

* Line number where error occurred

435

*/

436

line: Int,

437

438

/**

439

* Column number where error occurred

440

*/

441

column: Int,

442

443

/**

444

* Severity level of the error

445

*/

446

severity: ErrorSeverity

447

)

448

449

/**

450

* Compilation warning information

451

*/

452

case class CompilationWarning(

453

/**

454

* Warning message

455

*/

456

message: String,

457

458

/**

459

* Line number where warning occurred

460

*/

461

line: Int,

462

463

/**

464

* Column number where warning occurred

465

*/

466

column: Int

467

)

468

469

/**

470

* Error severity levels

471

*/

472

sealed trait ErrorSeverity

473

object ErrorSeverity {

474

case object Info extends ErrorSeverity

475

case object Warning extends ErrorSeverity

476

case object Error extends ErrorSeverity

477

case object Fatal extends ErrorSeverity

478

}

479

480

/**

481

* Exception thrown during compilation

482

*/

483

class CompilationException(message: String, cause: Throwable = null) extends Exception(message, cause)

484

485

/**

486

* Exception thrown during interpretation

487

*/

488

class InterpretationException(message: String, cause: Throwable = null) extends Exception(message, cause)

489

```