CLI: Allow running class files with '.class' extension in 'kotlin' script

Catch NoClassDefFoundError and print message with cause.

 #KT-11164 Fixed
 #KT-46171 Fixed
This commit is contained in:
Xin Wang
2021-11-11 15:34:55 +08:00
committed by Alexander Udalov
parent b7d88be41a
commit b24c3a106e
4 changed files with 123 additions and 2 deletions
@@ -144,7 +144,19 @@ object Main {
break
}
else {
setRunner(MainClassRunner(arg))
val workingDir = File(".")
val classFile = File(arg)
// Allow running class files with '.class' extension.
// In order to infer its fully qualified name, it should be located in the current working directory or a subdirectory of it
val className =
if (arg.endsWith(".class") && classFile.exists() && classFile.canonicalPath.contains(workingDir.canonicalPath)) {
classFile.canonicalFile.toRelativeString(workingDir.canonicalFile)
.removeSuffix(".class")
.replace(File.separatorChar, '.')
} else arg
setRunner(MainClassRunner(className))
restAsArguments()
break
}
@@ -25,7 +25,7 @@ import java.net.URLClassLoader
import java.util.jar.Attributes
import java.util.jar.JarFile
class RunnerException(message: String) : RuntimeException(message)
class RunnerException(message: String, cause: Throwable? = null) : RuntimeException(message, cause)
abstract class AbstractRunner : Runner {
protected abstract val className: String
@@ -40,6 +40,12 @@ abstract class AbstractRunner : Runner {
}
catch (e: ClassNotFoundException) {
throw RunnerException("could not find or load main class $className")
} catch (e: NoClassDefFoundError) {
val message = """
could not find or load main class $className
Caused by: $e
""".trimIndent()
throw RunnerException(message)
}
val main = try {