I'm trying to build a jar from a kotlin app using intelliJ idea, everything works from intellij, it's able to run kotlin files with the main
method, however after building the jar with gradle jar
I get:
java -cp build/libs/sensorPreprocessor-1.0-SNAPSHOT.jar co.myapp.sensorPreprocessor.MqttPollerKt
Error: Could not find or load main class co.myapp.sensorPreprocessor.MqttPollerKt
my build.gradle
is this:
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.3.31'
id "com.commercehub.gradle.plugin.avro" version '0.16.0'
}
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName = 'co.myapp.sensorPreprocessor.MqttPollerKt'
group 'co.myapp'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
jcenter()
maven {
url "https://dl.bintray.com/cbeust/maven"
}
maven {
url "http://packages.confluent.io/maven/"
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
compile "org.jetbrains.kotlin:kotlin-reflect:1.3.31"
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'org.apache.kafka', name: 'kafka-streams', version: '2.2.0'
compile group: 'com.igormaznitsa', name: 'jbbp', version: '1.4.1'
compile group: 'software.amazon.awssdk', name: 'sqs', version: '2.5.45'
compile group: 'com.amazonaws', name: 'aws-iot-device-sdk-java', version: '1.3.0'
compile group: 'com.amazonaws', name: 'aws-iot-device-sdk-java-samples', version: '1.3.0'
compile group: 'com.beust', name: 'klaxon', version: '5.0.5'
compile group: 'org.apache.kafka', name: 'kafka-clients', version: '2.2.0'
compile group: 'io.confluent', name: 'kafka-avro-serializer', version: '5.2.1'
compile group: 'io.confluent', name: 'kafka-streams-avro-serde', version: '5.2.1'
compile group: 'io.confluent', name: 'monitoring-interceptors', version: '5.2.1'
compile group: 'org.apache.avro', name: 'avro', version: '1.9.0'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
jar {
manifest {
attributes 'Main-Class': 'co.myapp.sensorPreprocessor.MqttPollerKt'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
my main file is this:
package co.myapp.sensorPreprocessor
import software.amazon.awssdk.services.sqs.model.Message as AwsSqsMessage
....
class MqttPoller {
companion object {
@JvmStatic fun main(args: Array<String>) {
start()
}
fun start() {
...
}
}
}
class MessagesTopic(topic: String, qos: AWSIotQos, private val kafkaProducer: KafkaProducer<String, SensorData>) : AWSIotTopic(topic, qos) {
override fun onMessage(message: AWSIotMessage?) {
....
}
}
fun main() {
MqttPoller.start()
}
I've tried both co.myapp.sensorPreprocessor.MqttPollerKt
and co.myapp.sensorPreprocessor.MqttPoller
with the same results.
If after I type java -cp JAR_PATH <tab>
I try to autocomplete I can see it autocompletes with my class names, but still it doesn't work.
If I try to use javap
it also shows the class:
➜ iot-services-sensor-preprocessor git:(master) ✗ javap -cp build/libs/sensorPreprocessor-1.0-SNAPSHOT.jar co.myapp.sensorPreprocessor.MqttPollerKt
Compiled from "MqttPoller.kt"
public final class co.myapp.sensorPreprocessor.MqttPollerKt {
public static final void main();
public static void main(java.lang.String[]);
}
➜ iot-services-sensor-preprocessor git:(master) ✗ javap -verbose -cp build/libs/sensorPreprocessor-1.0-SNAPSHOT.jar co.myapp.sensorPreprocessor.MqttPollerKt
Classfile jar:file:///Users/alex/Projects/myapp/build/libs/sensorPreprocessor-1.0-SNAPSHOT.jar!/co/myapp/sensorPreprocessor/MqttPollerKt.class
Last modified May 21, 2019; size 754 bytes
MD5 checksum 52febc7a2f38ef786ded2198193827b3
Compiled from "MqttPoller.kt"
public final class co.myapp.sensorPreprocessor.MqttPollerKt
minor version: 0
major version: 52
flags: (0x0031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER
this_class: #2 // co/myapp/sensorPreprocessor/MqttPollerKt
super_class: #4 // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 2
Constant pool:
#1 = Utf8 co/myapp/sensorPreprocessor/MqttPollerKt
#2 = Class #1 // co/myapp/sensorPreprocessor/MqttPollerKt
#3 = Utf8 java/lang/Object
#4 = Class #3 // java/lang/Object
#5 = Utf8 main
#6 = Utf8 ()V
#7 = Utf8 ([Ljava/lang/String;)V
#8 = NameAndType #5:#6 // main:()V
#9 = Methodref #2.#8 // co/myapp/sensorPreprocessor/MqttPollerKt.main:()V
#10 = Utf8 co/myapp/sensorPreprocessor/MqttPoller
#11 = Class #10 // co/myapp/sensorPreprocessor/MqttPoller
#12 = Utf8 Companion
#13 = Utf8 Lco/myapp/sensorPreprocessor/MqttPoller$Companion;
#14 = NameAndType #12:#13 // Companion:Lco/myapp/sensorPreprocessor/MqttPoller$Companion;
#15 = Fieldref #11.#14 // co/myapp/sensorPreprocessor/MqttPoller.Companion:Lco/myapp/sensorPreprocessor/MqttPoller$Companion;
#16 = Utf8 co/myapp/sensorPreprocessor/MqttPoller$Companion
#17 = Class #16 // co/myapp/sensorPreprocessor/MqttPoller$Companion
#18 = Utf8 start
#19 = NameAndType #18:#6 // start:()V
#20 = Methodref #17.#19 // co/myapp/sensorPreprocessor/MqttPoller$Companion.start:()V
#21 = Utf8 Lkotlin/Metadata;
#22 = Utf8 mv
#23 = Integer 1
#24 = Integer 15
#25 = Utf8 bv
#26 = Integer 0
#27 = Integer 3
#28 = Utf8 k
#29 = Integer 2
#30 = Utf8 d1
#31 = Utf8 \u0000\b\n\u0000\n\u0002\u0010\u0002\n\u0000\u001a\u0006\u0010\u0000\u001a\u00020\u0001¨\u0006\u0002
#32 = Utf8 d2
#33 = Utf8
#34 = Utf8 sensorPreprocessor
#35 = Utf8 MqttPoller.kt
#36 = Utf8 Code
#37 = Utf8 LineNumberTable
#38 = Utf8 SourceFile
#39 = Utf8 RuntimeVisibleAnnotations
{
public static final void main();
descriptor: ()V
flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
Code:
stack=1, locals=0, args_size=0
0: getstatic #15 // Field co/myapp/sensorPreprocessor/MqttPoller.Companion:Lco/myapp/sensorPreprocessor/MqttPoller$Companion;
3: invokevirtual #20 // Method co/myapp/sensorPreprocessor/MqttPoller$Companion.start:()V
6: return
LineNumberTable:
line 78: 0
line 79: 6
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x1009) ACC_PUBLIC, ACC_STATIC, ACC_SYNTHETIC
Code:
stack=0, locals=1, args_size=1
0: invokestatic #9 // Method main:()V
3: return
}
SourceFile: "MqttPoller.kt"
RuntimeVisibleAnnotations:
0: #21(#22=[I#23,I#23,I#24],#25=[I#23,I#26,I#27],#28=I#29,#30=[s#31],#32=[s#5,s#33,s#34])
kotlin.Metadata(
mv=[1,1,15]
bv=[1,0,3]
k=2
d1=["\u0000\b\n\u0000\n\u0002\u0010\u0002\n\u0000\u001a\u0006\u0010\u0000\u001a\u00020\u0001¨\u0006\u0002"]
d2=["main","","sensorPreprocessor"]
)
When you get the message "Could not find or load main class ...", that means that the first step has failed. The java command was not able to find the class. And indeed, the "..." in the message will be the fully qualified class name that java is looking for.
The error 'Could not find or load main class' occurs when using a java command in the command prompt to launch a Java program by specifying the class name in the terminal. The reason why this happens is mostly due to the user's programming mistake while declaring the class.
Wrong Class Name And it failed with the error “Could not find or load main class helloworld.” As discussed earlier, the compiler will generate the . class file with the exact same name given to the Java class in the program. So in our case, the main class will have the name HelloWorld, not helloworld.
I've found the issue, in the jar task I had to add
exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
so it becomes:
jar {
manifest {
attributes 'Main-Class': 'co.myapp.sensorPreprocessor.MqttPollerKt'
}
exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'
from {
(configurations.compile).collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With