0
# Utility Functions
1
2
Comprehensive utilities for classpath extraction, ClassLoader management, source code position tracking, error reporting, and JVM-specific operations. These utilities provide essential support functionality for the scripting framework.
3
4
## Capabilities
5
6
### Kotlin Runtime JAR Management
7
8
Utility object for finding and managing Kotlin runtime JAR files required for script compilation and execution.
9
10
```kotlin { .api }
11
/**
12
* Utility for finding Kotlin runtime JARs
13
* Provides access to standard Kotlin libraries and compiler components
14
*/
15
object KotlinJars {
16
/** Full compiler classpath including all compiler dependencies */
17
val compilerClasspath: List<File>
18
19
/** Compiler classpath with scripting support libraries */
20
val compilerWithScriptingClasspath: List<File>
21
22
/** Kotlin standard library JAR (nullable) */
23
val stdlibOrNull: File?
24
25
/** Kotlin standard library JAR (throws if not found) */
26
val stdlib: File
27
28
/** Kotlin reflection library JAR (nullable) */
29
val reflectOrNull: File?
30
31
/** Kotlin script runtime JAR (nullable) */
32
val scriptRuntimeOrNull: File?
33
34
/** Kotlin script runtime JAR (throws if not found) */
35
val scriptRuntime: File
36
37
/** Standard Kotlin JARs for scripting */
38
val kotlinScriptStandardJars: List<File>
39
40
/** Standard Kotlin JARs with reflection support */
41
val kotlinScriptStandardJarsWithReflect: List<File>
42
43
/**
44
* Get library JAR by name and marker class
45
* @param propertyName System property name for JAR location
46
* @param jarName Expected JAR file name
47
* @param markerClass Class that should exist in the JAR
48
* @param classLoader ClassLoader to search in (default: caller's ClassLoader)
49
* @return File pointing to JAR or null if not found
50
*/
51
fun getLib(
52
propertyName: String,
53
jarName: String,
54
markerClass: KClass<*>,
55
classLoader: ClassLoader? = null
56
): File?
57
58
/**
59
* Get library JAR by name and marker class name
60
* @param propertyName System property name for JAR location
61
* @param jarName Expected JAR file name
62
* @param markerClassName Fully qualified class name that should exist in JAR
63
* @param classLoader ClassLoader to search in (default: caller's ClassLoader)
64
* @return File pointing to JAR or null if not found
65
*/
66
fun getLib(
67
propertyName: String,
68
jarName: String,
69
markerClassName: String,
70
classLoader: ClassLoader? = null
71
): File?
72
}
73
```
74
75
**Usage Examples:**
76
77
```kotlin
78
import kotlin.script.experimental.jvm.util.KotlinJars
79
80
// Get standard Kotlin libraries
81
val stdlibJar = KotlinJars.stdlib
82
println("Kotlin stdlib: ${stdlibJar.absolutePath}")
83
84
val scriptJars = KotlinJars.kotlinScriptStandardJars
85
println("Script JARs: ${scriptJars.map { it.name }}")
86
87
// Use in compilation configuration
88
val compilationConfig = ScriptCompilationConfiguration {
89
dependencies(JvmDependency(KotlinJars.kotlinScriptStandardJarsWithReflect))
90
}
91
92
// Custom library detection
93
val myLibJar = KotlinJars.getLib(
94
"my.lib.path",
95
"my-library.jar",
96
MyLibraryClass::class
97
)
98
```
99
100
### Classpath Extraction Utilities
101
102
Functions for extracting classpath information from various sources including ClassLoaders, system properties, and execution context.
103
104
```kotlin { .api }
105
/**
106
* Extract classpath from ClassLoader
107
* @param currentClassLoader ClassLoader to analyze
108
* @param unpackJarCollections Whether to unpack nested JAR collections
109
* @return List of classpath files or null if extraction fails
110
*/
111
fun classpathFromClassloader(
112
currentClassLoader: ClassLoader,
113
unpackJarCollections: Boolean = false
114
): List<File>?
115
116
/**
117
* Extract classpath from system property
118
* @return List of classpath files from java.class.path property
119
*/
120
fun classpathFromClasspathProperty(): List<File>?
121
122
/**
123
* Extract classpath from specific class location
124
* @param classLoader ClassLoader containing the class
125
* @param klass Class to find classpath for
126
* @return List of files containing the class
127
*/
128
fun classpathFromClass(
129
classLoader: ClassLoader,
130
klass: KClass<out Any>
131
): List<File>?
132
133
/**
134
* Extract classpath from class using its ClassLoader
135
* @param klass Class to find classpath for
136
* @return List of files containing the class
137
*/
138
fun classpathFromClass(klass: KClass<out Any>): List<File>?
139
140
/**
141
* Extract classpath from class by reified type
142
* @return List of files containing the class
143
*/
144
inline fun <reified T : Any> classpathFromClass(): List<File>?
145
146
/**
147
* Extract classpath from fully qualified class name
148
* @param classLoader ClassLoader to search in
149
* @param fqn Fully qualified class name
150
* @return List of files containing the class
151
*/
152
fun classpathFromFQN(
153
classLoader: ClassLoader,
154
fqn: String
155
): List<File>?
156
```
157
158
**Usage Examples:**
159
160
```kotlin
161
// Extract from current ClassLoader
162
val currentClasspath = classpathFromClassloader(
163
Thread.currentThread().contextClassLoader,
164
unpackJarCollections = true
165
)
166
167
// Extract from system property
168
val systemClasspath = classpathFromClasspathProperty()
169
170
// Extract from specific class
171
val kotlinClasspath = classpathFromClass<String>()
172
val myClasspath = classpathFromClass(MyClass::class)
173
174
// Use in script configuration
175
val detectedClasspath = classpathFromClassloader(
176
MyApp::class.java.classLoader
177
) ?: emptyList()
178
179
val config = ScriptCompilationConfiguration {
180
dependencies(JvmDependency(detectedClasspath))
181
}
182
```
183
184
### Script Compilation Classpath Utilities
185
186
Specialized functions for determining appropriate classpath for script compilation based on context.
187
188
```kotlin { .api }
189
/**
190
* Get script compilation classpath from context or null
191
* @param wholeClasspath Whether to include entire classpath
192
* @param unpackJarCollections Whether to unpack JAR collections
193
* @param classLoader Optional specific ClassLoader
194
* @return Classpath files or null if unable to determine
195
*/
196
fun scriptCompilationClasspathFromContextOrNull(
197
wholeClasspath: Boolean = false,
198
unpackJarCollections: Boolean = true,
199
classLoader: ClassLoader? = Thread.currentThread().contextClassLoader
200
): List<File>?
201
202
/**
203
* Get script compilation classpath from context with stdlib fallback
204
* @param wholeClasspath Whether to include entire classpath
205
* @param unpackJarCollections Whether to unpack JAR collections
206
* @param classLoader Optional specific ClassLoader
207
* @return Classpath files or Kotlin standard libraries if context unavailable
208
*/
209
fun scriptCompilationClasspathFromContextOrStdlib(
210
wholeClasspath: Boolean = false,
211
unpackJarCollections: Boolean = true,
212
classLoader: ClassLoader? = Thread.currentThread().contextClassLoader
213
): List<File>
214
215
/**
216
* Get script compilation classpath from context (throws on failure)
217
* @param wholeClasspath Whether to include entire classpath
218
* @param unpackJarCollections Whether to unpack JAR collections
219
* @param classLoader Optional specific ClassLoader
220
* @return Classpath files
221
* @throws IllegalStateException if unable to determine classpath
222
*/
223
fun scriptCompilationClasspathFromContext(
224
wholeClasspath: Boolean = false,
225
unpackJarCollections: Boolean = true,
226
classLoader: ClassLoader? = Thread.currentThread().contextClassLoader
227
): List<File>
228
```
229
230
**Usage Examples:**
231
232
```kotlin
233
// Safe classpath detection with fallback
234
val classpath = scriptCompilationClasspathFromContextOrStdlib(
235
wholeClasspath = true,
236
unpackJarCollections = false
237
)
238
239
// Use in configuration
240
val config = ScriptCompilationConfiguration {
241
jvm {
242
val scriptClasspath = scriptCompilationClasspathFromContext(wholeClasspath = false)
243
dependencies(JvmDependency(scriptClasspath))
244
}
245
}
246
```
247
248
### File Matching Utilities
249
250
Utilities for file pattern matching and path analysis.
251
252
```kotlin { .api }
253
/**
254
* Check if file matches possibly versioned filename
255
* @param baseName Base name to match (without version)
256
* @return True if file matches pattern with optional version suffix
257
*/
258
fun File.matchMaybeVersionedFile(baseName: String): Boolean
259
260
/**
261
* Check if file has parent directory with given name
262
* @param baseName Parent directory name to check
263
* @return True if any parent directory matches the name
264
*/
265
fun File.hasParentNamed(baseName: String): Boolean
266
```
267
268
**Usage Examples:**
269
270
```kotlin
271
import java.io.File
272
273
val jarFile = File("/path/to/kotlin-stdlib-1.8.0.jar")
274
val matches = jarFile.matchMaybeVersionedFile("kotlin-stdlib")
275
// Returns: true
276
277
val sourceFile = File("/project/src/main/kotlin/MyScript.kt")
278
val hasKotlinParent = sourceFile.hasParentNamed("kotlin")
279
// Returns: true
280
```
281
282
### ClassLoader Resource Utilities
283
284
Advanced ClassLoader operations for resource discovery and classpath analysis.
285
286
```kotlin { .api }
287
/**
288
* Process all matching files in ClassLoader
289
* @param namePattern Pattern to match file names
290
* @param keyResourcePaths Key resource paths to search
291
* @param body Function to process each matching file
292
*/
293
fun ClassLoader.forAllMatchingFiles(
294
namePattern: String,
295
vararg keyResourcePaths: String,
296
body: (String, InputStream) -> Unit
297
)
298
299
/**
300
* Extract classpath from typical resource URLs
301
* @return Sequence of File objects representing classpath entries
302
*/
303
fun ClassLoader.classPathFromTypicalResourceUrls(): Sequence<File>
304
```
305
306
**Usage Examples:**
307
308
```kotlin
309
// Process all matching resource files
310
MyClass::class.java.classLoader.forAllMatchingFiles(
311
"*.properties",
312
"META-INF",
313
"config"
314
) { fileName, inputStream ->
315
println("Processing: $fileName")
316
val properties = Properties()
317
properties.load(inputStream)
318
// Process properties...
319
}
320
321
// Extract classpath from ClassLoader
322
val classLoader = Thread.currentThread().contextClassLoader
323
val classpathFiles = classLoader.classPathFromTypicalResourceUrls().toList()
324
```
325
326
### String and Identifier Utilities
327
328
Utilities for working with JVM identifiers and string manipulation.
329
330
```kotlin { .api }
331
/**
332
* Convert string to valid JVM identifier
333
* Replaces invalid characters with valid alternatives
334
* @return Valid JVM identifier string
335
*/
336
fun String.toValidJvmIdentifier(): String
337
```
338
339
**Usage Example:**
340
341
```kotlin
342
val invalidId = "my-script@version:1.0"
343
val validId = invalidId.toValidJvmIdentifier()
344
// Returns: "my_script_version_1_0"
345
346
// Use for generating class names
347
val scriptClassName = "Script_${sourceFileName.toValidJvmIdentifier()}"
348
```
349
350
### Source Code Position Utilities
351
352
Utilities for working with source code positions and location mapping.
353
354
```kotlin { .api }
355
/**
356
* Absolute position in source code
357
* @param line Line number (1-based)
358
* @param col Column number (1-based)
359
* @param absolutePos Absolute character position (0-based)
360
*/
361
data class AbsSourceCodePosition(
362
val line: Int,
363
val col: Int,
364
val absolutePos: Int
365
) : Serializable
366
367
/**
368
* Convert absolute position to source code position
369
* @param code Source code to map position in
370
* @return SourceCode.Position object
371
*/
372
fun Int.toSourceCodePosition(code: SourceCode): SourceCode.Position
373
374
/**
375
* Determine line separator used in string
376
* @return Line separator string ("\n", "\r\n", or "\r")
377
*/
378
fun String.determineSep(): String
379
380
/**
381
* Calculate absolute position from source code position
382
* @param code Source code containing the position
383
* @return Absolute character position
384
*/
385
fun SourceCode.Position.calcAbsolute(code: SourceCode): Int
386
```
387
388
**Usage Examples:**
389
390
```kotlin
391
import kotlin.script.experimental.api.SourceCode
392
393
// Create absolute position
394
val position = AbsSourceCodePosition(line = 10, col = 5, absolutePos = 145)
395
396
// Convert position types
397
val sourceCode = "line1\nline2\nline3".toScriptSource()
398
val absolutePos = 8
399
val sourcePosition = absolutePos.toSourceCodePosition(sourceCode)
400
401
// Determine line separator
402
val windowsCode = "line1\r\nline2\r\nline3"
403
val separator = windowsCode.determineSep() // Returns: "\r\n"
404
405
// Calculate absolute position
406
val pos = SourceCode.Position(2, 3)
407
val absolute = pos.calcAbsolute(sourceCode)
408
```
409
410
### Error Reporting Utilities
411
412
Utilities for rendering errors and diagnostic information in user-friendly formats.
413
414
```kotlin { .api }
415
/**
416
* Render error to PrintStream
417
* @param stream PrintStream to write error information
418
*/
419
fun ResultValue.Error.renderError(stream: PrintStream)
420
421
/**
422
* Render error to string
423
* @return Formatted error message string
424
*/
425
fun ResultValue.Error.renderError(): String
426
```
427
428
**Usage Examples:**
429
430
```kotlin
431
import kotlin.script.experimental.api.ResultValue
432
433
// Handle script execution error
434
val evaluationResult: ResultValue = // ... from script evaluation
435
436
when (evaluationResult) {
437
is ResultValue.Error -> {
438
// Print to console
439
evaluationResult.renderError(System.out)
440
441
// Get as string for logging
442
val errorMessage = evaluationResult.renderError()
443
logger.error("Script execution failed: $errorMessage")
444
}
445
is ResultValue.Value -> {
446
println("Success: ${evaluationResult.value}")
447
}
448
}
449
```
450
451
### Diagnostic Utilities
452
453
Utilities for working with diagnostic results and error conditions.
454
455
```kotlin { .api }
456
/**
457
* Check if result represents incomplete compilation/evaluation
458
* @return True if result is incomplete
459
*/
460
fun <T> ResultWithDiagnostics<T>.isIncomplete(): Boolean
461
462
/**
463
* Check if result represents an error condition
464
* @return True if result contains errors
465
*/
466
fun <T> ResultWithDiagnostics<T>.isError(): Boolean
467
```
468
469
**Usage Examples:**
470
471
```kotlin
472
import kotlin.script.experimental.api.ResultWithDiagnostics
473
474
// Check compilation results
475
val compilationResult: ResultWithDiagnostics<CompiledScript> = // ... from compilation
476
477
when {
478
compilationResult.isError() -> {
479
println("Compilation failed with errors")
480
compilationResult.reports.forEach { report ->
481
println("${report.severity}: ${report.message}")
482
}
483
}
484
compilationResult.isIncomplete() -> {
485
println("Compilation incomplete, missing dependencies or context")
486
}
487
else -> {
488
println("Compilation successful")
489
val script = compilationResult.valueOrNull()
490
}
491
}
492
```
493
494
### Exception Types
495
496
```kotlin { .api }
497
/**
498
* Exception thrown when classpath extraction fails
499
* @param message Error description
500
*/
501
class ClasspathExtractionException(message: String) : Exception
502
```
503
504
**Usage Example:**
505
506
```kotlin
507
try {
508
val classpath = classpathFromClassloader(someClassLoader)
509
?: throw ClasspathExtractionException("Unable to extract classpath from ClassLoader")
510
} catch (e: ClasspathExtractionException) {
511
logger.warn("Classpath extraction failed: ${e.message}")
512
// Fallback to standard libraries
513
val fallbackClasspath = KotlinJars.kotlinScriptStandardJars
514
}
515
```
516
517
## Constants
518
519
### JAR File Names
520
521
```kotlin { .api }
522
val KOTLIN_JAVA_STDLIB_JAR: String
523
val KOTLIN_JAVA_REFLECT_JAR: String
524
// ... additional JAR name constants
525
```
526
527
### System Properties
528
529
```kotlin { .api }
530
val KOTLIN_SCRIPT_CLASSPATH_PROPERTY: String
531
val KOTLIN_COMPILER_CLASSPATH_PROPERTY: String
532
// ... additional property name constants
533
```