Gradle- tidak ada atribut manifes utama

92

Saya agak gila dengan kesalahan ini yang saya dapatkan saat menjalankan file JAR yang dibangun dari Gradle. Kesalahan membaca "tidak ada atribut manifes utama, di RxJavaDemo.jar" Saya mencoba memanipulasi properti Manifest tetapi saya pikir saya lupa menambahkan dependensi atau sesuatu ke dalamnya. Apa sebenarnya yang saya lakukan salah?

apply plugin: 'java'
apply plugin: 'application'

mainClassName = 'demo.MainDashboard'

dependencies {
    compile files ("H:/Processes/Development/libraries/hikari-cp/HikariCP-2.4.1.jar")
    compile files ("H:/Processes/Development/libraries/controls-fx/controlsfx.jar")
    compile files ("H:/Processes/Development/libraries/database_connections/sqlite-jdbc-3.8.6.jar")
    compile files ("H:/Processes/Development/libraries/guava/guava-18.0.jar")
    compile files ("H:/Processes/Development/libraries/rxjava/rxjava-1.0.12.jar")
    compile files ("H:/Processes/Development/libraries/rxjava-extras/rxjava-extras-0.5.15.jar")
    compile files ("H:/Processes/Development/libraries/rxjavafx/RxJavaFX-1.0.0-RC1-SNAPSHOT.jar")
    compile files ("H:/Processes/Development/libraries/rxjavaguava/rxjava-guava-1.0.3.jar")
    compile files ("H:/Processes/Development/libraries/rxjava-jdbc/rxjava-jdbc-0.6.3.jar")
    compile files ("H:/Processes/Development/libraries/slf4j/slf4j-api-1.7.12.jar")
    compile files ("H:/Processes/Development/libraries/tom-commons/tom-commons.jar")
}

sourceSets {
    main.java.srcDir "src/main/java"
    main.resources.srcDir "src/main/resources"
}

jar { 
    manifest {
    attributes(
        "Class-Path": configurations.compile.collect { it.getName() }.join(' '))
    }
    from configurations.compile.collect { entry -> zipTree(entry) }
}
tmn
sumber

Jawaban:

143

Cobalah untuk mengubah atribut manifes Anda seperti:

jar {
  manifest {
    attributes(
      'Class-Path': configurations.compile.collect { it.getName() }.join(' '),
      'Main-Class': 'hello.HelloWorld'
    )
  }
}

Dan kemudian ubah saja 'hello.helloWorld'ke '<your packagename>.<the name of your Main class>'(di mana kelas Utama Anda memiliki metode utama). Dalam hal ini, Anda membuat di manifes Anda atribut, yang mengarah ke kelas ini, lalu stoples sedang berjalan.

Stanislav
sumber
1
@ Nilai 'Main-Class' Stanislav adalah kelas utama? Apa hello dan helloWorld dalam contoh Anda?
Daniela Maia
2
@DanielaMaia itu hanya nama kelas yang memenuhi syarat, pasti harus ditulis sebagai halo. Halo Dunia, di mana halo adalah paket tempat kelas HelloWorld berada
Stanislav
9
Saya perlu menghapus collect {}bagiannya agar berfungsi untuk saya. Kode Anda mengasumsikan bahwa semua dependensi berada dalam folder yang sama dengan kelas utama Anda.
AutonomousApps
1

FWIW - Saya menggunakan tugas jar berikut untuk mengumpulkan semua dependensi kompilasi saya ke dalam file jar, dan menggunakan rekomendasi di atas untuk mengatur jalur kelas dengan benar

apply plugin: 'java-library'

jar {
  manifest {
    attributes(
      'Class-Path': configurations.compile.collect { it.getName() }.join(' '),
      'Main-Class': 'your.main.class.goes.here'
    )
  }

  // You can reference any part of the dependency configurations,
  // and you can have as many from statements as you need
  from configurations.compile  
  // I just copied them into the top of the jar, so it looks like the eclipse exported 
  // runnable jar, but you could designate a lib directory, and reference that in the 
  // classpath as "lib/$it.name" instead of it.getName()
  into ''   
}
Eric Hallander
sumber
0

Untuk membuat jarfile dapat dieksekusi (agar java -jarperintah berfungsi), tentukan Main-Classatribut di MANIFEST.MF.

Di Gradle, Anda dapat melakukannya dengan mengonfigurasi jartugas.

  • untuk Groovy DSL lihat jawaban ini ( [1] , [2] )
  • untuk Kotlin DSL, Anda dapat menggunakan cuplikan kode berikut:
tasks.withType<Jar> {
    manifest {
        attributes["Main-Class"] = "com.caco3.Main"
    }
}

Mengapa mainClassNametidak berfungsi seperti yang diharapkan?

Atau mengapa mainClassNametidak menentukan atribut dalam manifes?

The mainClassNameproperti berasal dari applicationPlugin . Plugin:

memudahkan untuk memulai aplikasi secara lokal selama pengembangan, dan untuk mengemas aplikasi sebagai TAR dan / atau ZIP termasuk skrip awal khusus sistem operasi .

Jadi applicationPlugin tidak bertujuan untuk menghasilkan executable jars

Ketika sebuah mainClassNameproperti ditetapkan, maka:

  1. $ ./gradlew runakan meluncurkan mainmetode di kelas yang ditentukan dalam atribut
  2. yang zip/ tararsip dibangun menggunakan distZip/ distTartugas akan berisi script, yang akan meluncurkan mainmetode kelas yang ditentukan sebelumnya.

Berikut adalah baris skrip shell yang mengatur kelas utama:

$ grep Main2 gradletest
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLETEST_OPTS -classpath "\"$CLASSPATH\"" com.caco3.gradletest.Main2 "$APP_ARGS"
Denis Zavedeev
sumber