fix: Resolve ClassNotFoundException for .kts scripts by ensuring pack… #427
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
…age alignment
This commit addresses a 'missing linkage' issue where kscript's wrapper could fail to load the main class compiled from a .kts script, resulting in a ClassNotFoundException.
Problem Analysis:
.kts
scripts without an explicitpackage
declaration, kscript internally assigns a default package (e.g.,kscript.scriplet
).Main_ScriptName.kt
) is generated to provide a standardmain
method entry point. This wrapper attempts to load the compiled.kts
script's class using reflection, qualified with the assigned package name (e.g.,kscript.scriplet.ScriptName
)..kts
file content (without an explicit package statement) was written to a temporary file and compiled bykotlinc
.kotlinc
would place such a class in the default (unnamed) package.kscript.scriplet.ScriptName
, but class actually beingScriptName
in the default package) caused theClassNotFoundException
.Solution Implemented:
The
JarArtifactCreator.create()
method has been modified. Before a.kts
script's content is written to a temporary file for compilation, the logic now checks:.kts
file.package
declaration.If these conditions are met, the determined package declaration (e.g.,
package kscript.scriplet;
) is prepended to the script content. This ensures thatkotlinc
compiles the.kts
script's class into the same package that the wrapper expects, resolving the ClassNotFoundException.Further Considerations for Full Robustness (Future Work):
While this commit fixes a critical classloading issue for
.kts
scripts, another area related to classloading and "missing linkage" has been identified, particularly for scripts packaged using the--package
option:--package
option uses Gradle tocreate a fat JAR. The current Gradle template uses
DuplicatesStrategy.INCLUDE
. This can lead to runtime issues(e.g.,
NoSuchMethodError
, services not loading) if dependencieshave conflicting class versions or
META-INF/services
files, as onlyone version of a conflicting file will be included, potentially the
wrong one.
template should be updated to use a dedicated fat JAR plugin like
com.github.johnrengelman.shadow
, which offers better strategies fordependency conflict resolution and resource merging.
This fix provides a significant improvement in the reliable execution of .kts files. Further work on the packaging mechanism can enhance robustness for distributed scripts.