Here is my step for reproducing the issue:
com/example/Library.kt
package com.example
class Library {
fun getValue(): Int {
return 123
}
}
MyCode.kt
import com.example.Library
fun main() {
println("Hello World")
println(Library().getValue())
}
I can compile both files with command below, without any error:
kotlinc com/example/Library.kt -d Library.jar
kotlinc -cp Library.jar MyCode.kt -d MyCode.jar
File structure after compile:
$ tree
.
├── Library.jar
├── MyCode.jar
├── MyCode.kt
└── com
└── example
└── Library.kt
However, I cannot execute MyCode.jar
$ java -cp Library.jar -jar MyCode.jar
Hello world
Exception in thread "main" java.lang.NoClassDefFoundError: com/example/Library
at MyCodeKt.main(MyCode.kt:5)
at MyCodeKt.main(MyCode.kt)
Caused by: java.lang.ClassNotFoundException: com.example.Library
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
... 2 more
Neither works using kotlin instead of java:
$ kotlin -cp Library.jar MyCode.jar
Hello world
Exception in thread "main" java.lang.NoClassDefFoundError: com/example/Library
at MyCodeKt.main(MyCode.kt:5)
at MyCodeKt.main(MyCode.kt)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.jetbrains.kotlin.runner.AbstractRunner.run(runners.kt:70)
at org.jetbrains.kotlin.runner.Main.run(Main.kt:194)
at org.jetbrains.kotlin.runner.Main.main(Main.kt:204)
Caused by: java.lang.ClassNotFoundException: com.example.Library
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:593)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
... 7 more
Can anyone please tell me what is the problem here?
(Maven / Gradle is not an option, I am trying to build a fast tool to compile users' codes)
The reason for the error is given by the kotlin -help
command:
app.jar Runs the given JAR file as 'java -jar' would do
So we need to look at what java -jar
does. For that, see the Java documentation:
-jar jarfile
Executes a program encapsulated in a JAR file. The jarfile argument is the name of a JAR file with a manifest that contains a line in the form Main-Class:classname that defines the class with the public static void main(String[] args) method that serves as your application's starting point. When you use -jar, the specified JAR file is the source of all user classes, and other class path settings are ignored. If you're using JAR files, then see jar.
The relevant sentence is the one I've made bold. So kotlin MyCode.jar
ignores the -cp
argument. The fix is to either run it the way you've given in your own answer, or put the Library.class
file inside your MyCode.jar
.