Gradle, Ikonli, fatJar

ThHi

Mitglied
Hi,
ich habe da ein sehr seltsames Problem beim Bauen eines fatJar mit Gradle und der Lib Ikonli.
Es funktioniert, wenn ich das Programm im Debugger starte oder mit: "gradle run"
Habe zwei Icons aus zwei unterschiedlichen Ikonli-Libs eingebunden. Die werde dann auch beide angezeigt.

Wenn ich eine FatJar baue, wird immer nur ein Icon aus der Lib die im build.gradle zuerst kommt, angezeigt. Das zweite Icon wird dann nicht gefunden und wirft eine Exception???? Habe da schon einiges probiert, (auch das 'com.github.johnrengelman.shadow'), aber immer mit dem selben Erfolg. Macht auch keine Unterschied, ob ich die Libs von einem lokalem Verzeichnis einbinde oder direkt über maven.

Hänge mal meinen src und das build.gradle an, vielleicht hat da jemand noch eine Idee dazu. Danke schon mal

sorry, für den zweiten Eintrag, wollte mein build.gradle nicht annehmen und ist dann beim Ändern passiert
 

Anhänge

  • Icon.java
    1,5 KB · Aufrufe: 0
  • Main.java
    204 Bytes · Aufrufe: 0
  • build.gradle.txt
    1,8 KB · Aufrufe: 0
Zuletzt bearbeitet:

KonradN

Super-Moderator
Mitarbeiter
Statt Dateien einzuhängen ist es immer besser, den Code selbst zu posten. Dann kann man sich den Code direkt im Browser ansehen und muss nicht erst Dateien herunterladen um diese dann zu öffnen ... Daher bitte zukünftig den </> Knopf links oberhalb des Eingabebereiches für Code nutzen.

Was das Problem angeht: Ikonli nutzt sogenannte Services. Das ist ein Mechanismus, über den Elemente in Jar Dateien gefunden bzw. bereit gestellt werden können. Das findet sich dann in den jar Dateien in META-INF/services.

So findet sich in den jar Dateien z.B.
inflating: META-INF/services/org.kordamp.ikonli.IkonHandler
inflating: META-INF/services/org.kordamp.ikonli.IkonProvider

Ich habe mir das nicht weiter im Detail angeschaut, aber das könnte das Problem sein, wenn Du hier Dinge aus zwei jar Dateien haben willst, die über die gleichen Services gefunden werden.

Was ist das Problem im Detail:
  • Mehrere jar Dateien beinhalten die gleichen Dateien (unter services)
  • wenn Du beim fatJar einfach nur jar Dateien entpackst um es dann zusammen zu packen, dann hat eine Datei die andere überschrieben
  • das führt dazu, das nur die services bereit stehen, dessen Datei sozusagen "gewonnen" hat,

Das kann man in Gradle z.B. mit dem shadow Plugin machen. Das wäre dann etwas wie:
Code:
plugins {
    id("com.github.johnrengelman.shadow") version "8.1.1"
}

tasks.shadowJar {
    mergeServiceFiles()
}
 

KonradN

Super-Moderator
Mitarbeiter
Du brauchst keinen extra fatJar-Task... schmeiß den raus, dafür gibt es keinen Grund.
Das finde ich sehr vermessen. Woher willst Du wissen, dass der TE keinen Grund hat? Offensichtlich hat er einen Grund, denn ganz ohne Grund wird er es nicht wollen.... Und wenn der Grund einfach nur ein falsches Verständnis von irgend wem ist .... Aber vermutlich wolltest Du einfach nur genau das ausdrücken.

Einfach einmal meine Sichtweise etwas ausführlicher, da es nun einmal thematisiert wurde: die Weitergabe einer Java Anwendung einfach per JAR Datei, die dann bitte per Doppelklick zu starten ist, ist (zum Glück) am aussterben (Das ist wohl der Hauptgrund für die Anforderung gefolgt von schlichter Unwissenheit, was sonst noch möglich ist). Es macht mehr Sinn, eine Anwendung sauber weiter zu geben, idealer Weise mit einem Image (Hier wäre dann vor allem JPackage zu nennen. GralVM ist noch ein Thema, aber mit JavaFX ist das eher problematisch).
Der bessere Ansatz ist also aus meiner Sicht tatsächlich auch, dass man in die eigene jar Datei keine Abhängigkeiten packt. Statt dessen sollten man halt z.B.:
  • Abhängigkeiten in ein Verzeichnis kopieren (z.B. lib) und dann in dem Manifest entsprechend verlinken lassen.
  • JPackage nutzen, um ein Image der Anwendung zu bekommen.

Der Vorteil von JPackage ist weiterhin, dass man eine passende Java Runtime mit gibt. Der Nutzer hat also weder die Notwendigkeit, hier noch etwas passendes zu installieren und es gibt keine Probleme mit mehreren Anwendungen die unterschiedliche Java Versionen wollen.

Ich arbeite mit Maven und habe Templates auf GitHub), wie sowas aussehen könnte. Mit Gradle habe ich sowas bisher noch nicht gemacht, daher kann ich da nicht viel weiterhelfen.
 

Lennox-n

Mitglied
Das finde ich sehr vermessen. Woher willst Du wissen, dass der TE keinen Grund hat?
Offensichtlich will er doch nur eine jar mit allen Abhängigkeiten bauen, dafür braucht er aber keinen zweiten Jar-Task aus meiner Sicht.

die Weitergabe einer Java Anwendung einfach per JAR Datei, die dann bitte per Doppelklick zu starten ist, ist (zum Glück) am aussterben
Du kritisierst sein Vorhaben grundsätzlich, aber ob es ausstirbt ist noch offen...
 

KonradN

Super-Moderator
Mitarbeiter
Offensichtlich will er doch nur eine jar mit allen Abhängigkeiten bauen, dafür braucht er aber keinen zweiten Jar-Task aus meiner Sicht.
Wie baust du eine fat jar ohne einen solchen Task bzw. ohne ein Plugin, dass die Services vereint?

Du kritisierst sein Vorhaben grundsätzlich, aber ob es ausstirbt ist noch offen...
Ich habe ihm als erstes bei seinem technischen Problem geholfen. Dabei habe ich auf jegliche Wertung verzichtet.

Die Wertung kam erst, nachdem Du angefangen hast diesbezüglich etwas zu schreiben und ihm sogar absprachst, einen Grund zu haben. Darauf habe ich dann geantwortet und habe meine Sichtweise dargestellt. Und die Bewertung, ob etwas ausstirbt oder nicht, ist einfach egal. Diese Aussage zeigt einfach meine Bewertung dieser Technologie. Dies kann man gerne diskutieren, aber das erfordert dann klare Argumente. Evtl. willst Du ja welche beisteuern?
 

Lennox-n

Mitglied
Wie baust du eine fat jar

Code:
jar {
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    manifest {
        attributes 'Main-Class': application.getMainClass()
        attributes 'Multi-Release': 'true'
    }
    from {
        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
    }
    exclude('META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA')
}

Die Wertung kam erst, nachdem Du angefangen hast

Ich lasse mir nur ungern das Wort von dir im Mund verdrehen, auch wenn du hier Häuptling bist ... Außer, dass ich gesagt habe dass seine Tasks Schwachsinn sind habe ich gar nichts "gewertet". Also mach den Kopf zu und beruhig dich wieder.
 

KonradN

Super-Moderator
Mitarbeiter
Sorry, aber hier geht es doch weniger um Worte im Mund verdrehen sondern schlicht um missverstandene Posts.

Genau das, was Du jetzt gepostet hast hättest Du einfach direkt als Verbesserungsvorschlag senden können. Das wäre für den TE hilfreich und verständlich gewesen und es wäre klar gewesen, dass Du nicht gegen einen Task bist, der ein fat jar baut sondern nur dagegen, dass dies ein separater Task macht statt einfach den jar Task anzupassen.

Daher danke für die Richtigstellung, wie Deine Aussage zu verstehen war.
 

KonradN

Super-Moderator
Mitarbeiter
Ich habe schlicht falsche Dinge in Deine Posts hineininterpretiert. Wenn Du das als "überinterpretiert" bezeichnen willst, dann ist das ok für mich.

Daher noch einmal Danke, dass Du es klar gestellt hast und sorry, dass ich es falsch interpretiert hatte.
 

ThHi

Mitglied
Das in dem Beispiel, war auf das nötigste verkürzt. Ich lasse mir unterschiedliche Pakete bauen und dafür brauch ich den fatJar, hat also schon einen Grund, und meine Programme haben auch das JRE mit dabei, ist in einem Verzeichnis parallel zum JAR. Bisher hat sich auch noch keiner beschwert. Das ganze wird dann als Zip oder installable-exe verpackt.
Wer nur das Jar lädt (und java installiert hat), kann es dann auch ohne weitere Abhängkeiten (oder weitere Verzeichnisse) einfach per Doppelklick starten, find das praktischer und übesichlicher als ein JPackage.

Ansonsten war der Vorschlag hilfreich, musste nur noch das ergänzen, dann gings, danke:

Java:
tasks.shadowJar {
    duplicatesStrategy = DuplicatesStrategy.INCLUDE // <---
    mergeServiceFiles()
}
 

ThHi

Mitglied
Java:
tasks.shadowJar {
     duplicatesStrategy = DuplicatesStrategy.INCLUDE 
    mergeServiceFiles()
}

Code:
jar {
    manifest {
        attributes("Manifest-Version": "1.0",
                "Main-Class": theMainClass);
    }
     duplicatesStrategy = DuplicatesStrategy.INCLUDE
}

in der Anleitung (Website) zum ShadowJar war das mit der DuplicateStrtegy auch beschrieben. Bei mir reichte es nicht, wenn die im Jar-Task stand (war sogar egal ob überhaupt). Die musste im shadowJar-Task stehen, nur so ging es.
 

Lennox-n

Mitglied
Danke für die Info!

Ich habe nur Vermutung dazu, und die jetzt zu äußern, würde den Thread nicht produktiv voranbringen.

Gut, dass es gelöst ist. Ich glaube, Konrad traf den Nagel auf den Kopf.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
C Gradle startet SpringBoot-Anwendung nicht (Build aber successfull) Tools - Maven, Gradle, Ant & mehr 1
8u3631984 In Gitlab Pipleline Dokcer Image pushen mit gradle bootBuildImage Tools - Maven, Gradle, Ant & mehr 0
N No Main Manifest Attribute trotz Eintrag bei Gradle Tools - Maven, Gradle, Ant & mehr 1
8u3631984 Gradle und NPM wie strukturieren Tools - Maven, Gradle, Ant & mehr 3
S Gradle kann Lottie Implementation nicht finden Tools - Maven, Gradle, Ant & mehr 5
Gradle build funktioniert nicht Tools - Maven, Gradle, Ant & mehr 10
Moman2022 Hauptklasse kann nicht gefunden werden gradle build Tools - Maven, Gradle, Ant & mehr 3
8u3631984 Gradle nicht benötigte Dependencies finden Tools - Maven, Gradle, Ant & mehr 3
B Gradle Terminal/Console Encoder Tools - Maven, Gradle, Ant & mehr 9
S "Wer" löscht JARs aus meinem Gradle-cache? Tools - Maven, Gradle, Ant & mehr 3
von Spotz Gradle: Warum wird das Plugin nicht geladen? Tools - Maven, Gradle, Ant & mehr 4
8u3631984 Verschachteltes Gradle Projekt Tools - Maven, Gradle, Ant & mehr 0
von Spotz Gradle: Dependencies und Plugins vom root Projekt für die child-Projekte verfügbar machen Tools - Maven, Gradle, Ant & mehr 5
J Gradle signing Plugin Tools - Maven, Gradle, Ant & mehr 0
Y Gradle finished with non-zero exit value 1 mit Gradle Tools - Maven, Gradle, Ant & mehr 1
L Gradle Ein lokales Eclipse Projekt in Gradle dependency einbinden Tools - Maven, Gradle, Ant & mehr 2
8u3631984 Gradle : Baue anderes Modul und packe es in einen Docker Container Tools - Maven, Gradle, Ant & mehr 0
M Was ist besser für den Anfang, Maven oder Gradle? Tools - Maven, Gradle, Ant & mehr 6
P Gradle Dependencies in Module vererben Tools - Maven, Gradle, Ant & mehr 2
J [Gradle] Task Reihenfolge pusblishMaven vor codenarcTest Tools - Maven, Gradle, Ant & mehr 0
J netbeans - jasperreports - gradle - klappt nicht Tools - Maven, Gradle, Ant & mehr 0
sascha-sphw Maven vs Gradle Tools - Maven, Gradle, Ant & mehr 24
L Gradle src-gen zum Classpath hinzufügen Tools - Maven, Gradle, Ant & mehr 0
N Gradle Tools - Maven, Gradle, Ant & mehr 4
W Gradle in Netbeans ... wie? Tools - Maven, Gradle, Ant & mehr 28
N Gradle für Tests 2 Frameworks Tools - Maven, Gradle, Ant & mehr 2
E Gradle Build Tools - Maven, Gradle, Ant & mehr 1
C Gradle create project within application Tools - Maven, Gradle, Ant & mehr 0
Tom299 (Gradle) Wie die JAR eines 2. Projektes "includieren" Tools - Maven, Gradle, Ant & mehr 1
Psypsy Multi-Projekt mit Gradle Tools - Maven, Gradle, Ant & mehr 1
Kr0e Best practices / Gradle und co Tools - Maven, Gradle, Ant & mehr 7

Ähnliche Java Themen

Neue Themen


Oben