Gradle- ไม่มีแอตทริบิวต์รายการหลัก


93

ฉันแทบจะบ้ากับข้อผิดพลาดนี้ที่ฉันได้รับเมื่อเรียกใช้ไฟล์ JAR ที่สร้างขึ้นจาก Gradle ข้อผิดพลาดอ่าน "ไม่มีแอตทริบิวต์รายการหลักใน RxJavaDemo.jar" ฉันพยายามจัดการคุณสมบัติ Manifest แต่ฉันคิดว่าฉันลืมเพิ่มการอ้างอิงหรือบางอย่างลงไป ฉันทำอะไรผิดกันแน่?

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) }
}

คำตอบ:


143

ลองเปลี่ยนแอตทริบิวต์รายการของคุณเช่น:

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

จากนั้นเปลี่ยน'hello.helloWorld'เป็น'<your packagename>.<the name of your Main class>'(โดยที่คลาสหลักของคุณมีเมธอดหลัก) ในกรณีนี้คุณสร้างแอตทริบิวต์ในรายการของคุณซึ่งชี้ไปที่คลาสนี้จากนั้น jar กำลังทำงาน


1
@Stanislav ค่า 'Main-Class' คือคลาสหลัก? สวัสดีและ helloWorld ในตัวอย่างของคุณคืออะไร?
Daniela Maia

2
@DanielaMaia เป็นเพียงชื่อคลาสที่มีคุณสมบัติครบถ้วนแน่นอนว่าจะต้องเขียนว่า hello HelloWorld ซึ่งสวัสดีคือแพ็คเกจที่คลาส HelloWorld ตั้งอยู่
Stanislav

9
ฉันจำเป็นต้องลบcollect {}ส่วนนั้นออกเพื่อให้มันใช้งานได้ รหัสของคุณถือว่าการอ้างอิงทั้งหมดอยู่ในโฟลเดอร์เดียวกับคลาสหลักของคุณ
AutonomousApps

1

FWIW - ฉันใช้งาน jar ต่อไปนี้เพื่อรวบรวมการอ้างอิงการคอมไพล์ทั้งหมดลงในไฟล์ jar และใช้คำแนะนำข้างต้นเพื่อตั้งค่า class-path อย่างถูกต้อง

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 ''   
}

1

ในการทำให้jarไฟล์ทำงานได้ (เพื่อให้java -jarคำสั่งทำงาน) ให้ระบุMain-Classแอตทริบิวต์ในMANIFEST.MF.

ใน Gradle คุณสามารถทำได้โดยกำหนดค่าjarงาน

  • สำหรับGroovy DSL ดูคำตอบเหล่านี้ ( [1] , [2] )
  • สำหรับKotlin DSL คุณสามารถใช้ข้อมูลโค้ดต่อไปนี้:
tasks.withType<Jar> {
    manifest {
        attributes["Main-Class"] = "com.caco3.Main"
    }
}

ทำไมmainClassNameไม่ได้ผลตามที่คาดหวัง?

หรือทำไมmainClassNameไม่ระบุแอตทริบิวต์ในไฟล์ Manifest?

mainClassNameคุณสมบัติมาจากปลั๊กอินapplication ปลั๊กอิน:

ทำให้ง่ายต่อการเริ่มต้นโปรแกรมเฉพาะในระหว่างการพัฒนาและแพคเกจการประยุกต์ใช้เป็นTARและ / หรือZIP รวมทั้งการดำเนินงานสคริปต์เริ่มต้นระบบที่เฉพาะเจาะจง

ดังนั้นapplicationปลั๊กอินไม่ได้มุ่งหวังที่การผลิตปฏิบัติการjars

เมื่อmainClassNameตั้งค่าคุณสมบัติแล้ว:

  1. $ ./gradlew runจะเปิดใช้mainเมธอดในคลาสที่ระบุในแอตทริบิวต์
  2. zip/ tarเก็บถาวรสร้างขึ้นโดยใช้distZip/ distTarงานจะมีสคริปต์ซึ่งจะเปิดตัวmainวิธีการของระดับก่อนหน้านี้ที่ระบุ

นี่คือบรรทัดของเชลล์สคริปต์ที่ตั้งค่าคลาสหลัก:

$ grep Main2 gradletest
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLETEST_OPTS -classpath "\"$CLASSPATH\"" com.caco3.gradletest.Main2 "$APP_ARGS"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.