Reputation: 2849
I have a multi modular Gradle project with Kotlin. One of the modules have the main method and dependencies to others. I need to create an executable jar from this module. So I have tried to do that by creating a Jar task like this
jar {
manifest {
attributes(
'Main-Class': 'my_package.RunnerKt'
)
}
from {
configurations.compileClasspath.filter{ it.exists() }.collect { it.isDirectory() ? it : zipTree(it) }
}
}
And also I tried the Shadow Gradle Plugin.
In both cases the fat jar is created as expected, it seems to have all my classes and dependencies. But when I run the jar with java -jar
I get the following error:
java.lang.NoClassDefFoundError: Could not initialize class my_kotlin_object_class
where my_kotlin_object_class
is just a kotlin object
with some variables.
In the stacktrace there are no other exceptions which could cause this one, so seems it just has a problem with this class itself. When I look into the jar, I can see this file there.
I don't understand is this a problem with kotlin object itself and executable jars, or I am doing something wrong?
Upvotes: 5
Views: 3616
Reputation: 2849
So actually there was another exception behind this one!
The strange thing was that as long as the class that the exception was happening in was a Kotlin Object
I was not able to see the real exception in stacktrace (I don't know why).
As soon as I changed the object
with a class
I saw the real cause of the error. I fixed it, changed back it to object
and everything worked as expected.
So the problem itself was specific to my code, but someone might benefit from it as well.
Actually in that object I was reading some configuration files with val url = ClassLoader.getSystemClassLoader().getResource("path_to_file")
these files were in the resources\configs
directory of my module. And after packing them into fat jar they were in the root of the jar inside configs folder.
The path_to_file was a relative path starting with ./
e.g. ./configs/my_config.json
which is working fine when I run the project in IntelliJ, but inside fat jar it was failing to load the files.
The solution, very surprisingly for me, was just to remove the ./
prefix from the path leaving it just configs/my_config.json
. And everything worked as expected.
Upvotes: 5