Gradle: nessun attributo manifest principale


91

Sto impazzendo con questo errore che ottengo durante l'esecuzione di un file JAR creato da Gradle. L'errore legge "nessun attributo manifest principale, in RxJavaDemo.jar" Ho provato a manipolare la proprietà Manifest ma penso che mi stia dimenticando di aggiungere le dipendenze o qualcosa del genere. Cosa sto facendo di sbagliato esattamente?

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

Risposte:


142

Prova a modificare i tuoi attributi manifest come:

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

E poi cambia semplicemente 'hello.helloWorld'in '<your packagename>.<the name of your Main class>'(dove la tua classe Main ha un metodo principale). In questo caso, crei nel tuo manifest un attributo, che punta a questa classe, quindi un jar è in esecuzione.


1
@Stanislav "Main-Class" valore è la classe principale? Cosa sono hello e helloWorld nel tuo esempio?
Daniela Maia

2
@DanielaMaia è solo un nome di classe completo, sicuramente deve essere scritto come hello.HelloWorld, dove hello è il pacchetto in cui si trova la classe HelloWorld
Stanislav

9
Avevo bisogno di rimuovere la collect {}porzione per farlo funzionare per me. Il codice presume che tutte le dipendenze si trovino nella stessa cartella della classe principale.
AutonomousApps

1

FWIW - Ho usato la seguente attività jar per assemblare tutte le mie dipendenze di compilazione nel file jar e ho usato la raccomandazione sopra per ottenere il percorso di classe impostato correttamente

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

0

Per rendere il jarfile eseguibile (in modo che il java -jarcomando funzioni), specificare l' Main-Classattributo in MANIFEST.MF.

In Gradle, puoi farlo configurando l' jarattività.

  • per Groovy DSL vedi queste risposte ( [1] , [2] )
  • per Kotlin DSL puoi utilizzare il seguente frammento di codice:
tasks.withType<Jar> {
    manifest {
        attributes["Main-Class"] = "com.caco3.Main"
    }
}

Perché mainClassNamenon funziona come previsto?

O perché mainClassNamenon specifica l'attributo nel manifest?

La mainClassNameproprietà proviene dal applicationplugin . Il plugin:

semplifica l' avvio dell'applicazione in locale durante lo sviluppo e il pacchetto dell'applicazione come TAR e / o ZIP inclusi gli script di avvio specifici del sistema operativo .

Così il applicationplug-in non mira a produrre eseguibili jars

Quando una mainClassNameproprietà viene impostata, allora:

  1. $ ./gradlew runlancerà il mainmetodo nella classe specificata nell'attributo
  2. l ' zip/ tararchive costruito usando distZip/ distTartasks conterrà uno script, che avvierà il mainmetodo della classe specificata in precedenza.

Ecco la riga dello script di shell che imposta la classe principale:

$ grep Main2 gradletest
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLETEST_OPTS -classpath "\"$CLASSPATH\"" com.caco3.gradletest.Main2 "$APP_ARGS"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.