# gradlew funktioniert nicht



## White_Fox (25. Nov 2022)

Moin Leute

Folgendes: Ich habe Gradle nach Anleitung installiert, und es scheint zu laufen, jedenfalls liefert der Befehl gradle --version das zurück was ich erwarte.

Ein Projekt mit gradle init zu erstellen hat auch gut funktioniert.

Der Befehl gradlew tasks kommt aber mit einer Fehlermeldung, Powershell sagt:
gradlew : Die Benennung "gradlew" wurde nicht als Name eines Cmdlet, einer Funktion, einer Skriptdatei oder eines ausführbaren
Programms erkannt. Überprüfen Sie die Schreibweise des Namens, oder ob der Pfad korrekt ist (sofern enthalten), und wiederholen Sie
den Vorgang.

Hat jemand eine Ahnung, was da nicht stimmt?


----------



## KonradN (25. Nov 2022)

Ich vermute, du hast ein Denkfehler:

gradlew ist der Gradle Wrapper. Der dient dazu, dass Du eben kein gradle auf Deinem Rechner installiert hast. Das hat u.a. den Vorteil, dass Du in unterschiedlichen Projekten unterschiedliche Gradle Versionen nutzen kannst.

Jetzt hast Du aber gradle installiert. Ist auch ok - dann kannst Du gradle starten mit gradle. So das Projekt die installierte gradle Version unterstützt, kannst Du einfach gradlew durch gradle ersetzen - also statt
`gradlew tasks``
gibst Du einfach ein:
`gradle tasks``

Du kannst aber auch in dem Projekt einfach den Gradle Wrapper installieren. IntelliJ erzeugt den beim erstellen eines Projektes auch gleich mit. Nachträglich geht es aber mit
`gradle wrapper`
hinzu fügen. Das erzeugt dann unter anderem gradlew Scripte für Unix und Windows so dass ein gradlew (bzw. ./gradlew Aufruf) funktioniert.

Und der Hinweis zu dem Aufruf auf Unix artigen Systemen: Entgegen dem Standard bei Windows ist der aktuelle Pfad nicht im Path enthalten. Wenn Du also ein Script im aktuellen Verzeichnis starten willst, reicht nicht der Name des Scripts. Du musst das Verzeichnis mit angeben, also statt einfach gradlew musst du ./gradlew schreiben. (Das wäre die Alternative.)

Siehe dazu auch in der Dokumentation:




__





						The Gradle Wrapper
					





					docs.gradle.org


----------



## White_Fox (25. Nov 2022)

Ah...danke, dann habe ich das Tutorial wohl falsch verstanden.


----------



## White_Fox (26. Nov 2022)

Ich glaube, ich habe da gleich noch mehr Fragen:

Ich habe mit gradle init ein Projekt erstellt: Application, mit zusätzlichen Bibliotheken. Jetzt sind in diesem Ordner weitere Unterordner wie 'app', 'buildSource', 'list' und 'utilities'. Außerdem etwas git-Kram und eine Datei settings.gradle. Aber, und das verwirrt mich etwas, keine Datei build.gradle, diese ist dafür aber in den aufgeführten Unterordnern enthalten.

Woher weiß Gradle jetzt eigentlich z.B. in welcher Reihenfolge es was bauen soll? Mir sind die Aufgaben und Funktionen von build.gradle und settings.gradle noch nicht so recht klar. (Ich weiß, das steht bestimmt irgendwo in der Dokumentation, aber die ist leider auch voll von Dingen von denen ich zumindest glaube, sie erstmal nicht zu brauchen und daher erstmal beiseite lasse, sonst komm ich da gar nicht voran. Gradle ist schon ziemlich groß und übermächtig, wie ich finde.)


----------



## KonradN (26. Nov 2022)

Erst einmal muss ich klar sagen: Gradle habe ich bisher eher weniger benutzt. Meine Android Applikationen basierten auf gradle aber sonst habe ich immer auf Maven gesetzt.

Ich habe jetzt mal einfach ein neues gradle Projekt erstellt mit
Application, Java, multiple subprojects, groovy, no new apis

Was haben wir jetzt in dem Verzeichnis alles?
a) gradle wrapper -> .gradle, gradlew, gradlew.bat --> Das kannst Du für das Verständnis erst einmal ignorieren. Das ist halt nur ein Satz mit Scripts um halt kein lokales gradle zu benötigen.

b) paar git Dinge wie ein .gitignore und .gitattributes - das kann man sich auch separat ansehen. Für ein git Verständnis ist das egal.

c) settings.gradle -> Endlich etwas gradle spezifisches. Wenn man sich das anschaut, dann sieht man direkt, dass da nicht viel drin ist:
c1) rootProject.name Property wird gesetzt.
c2) Es wird angegeben, welche Verzeichnisse Gradle berücksichtigen soll. (app, list und utilities)
==> Keine build.gradle - in dem Verzeichnis wird Gradle also selbst nichts bauen!

d) app Verzeichnis: Ja, hier haben wir jetzt eine build.gradle - hier wird also aktiv etwas gebaut. Daher auch Sourcen, die gebaut werden sollen.
Bei list und utilities genau das Gleiche. Das sind also die Subprojekte

Dann kann man sich die build.gradle ansehen - da finden sich ja die Abhängigkeiten:
Bei apps/build.gradle findet sich:

```
dependencies {
    implementation 'org.apache.commons:commons-text'
    implementation project(':utilities')
}
```
==> Ahh, es wird utilities gebraucht! ==> *Das ist für die Reihenfolge verantwortlich! Da utilities von app benötigt wird, wird Gradle erst utilities bauen und dann app! Es ist also nicht die Reihenfolge in der settings.gradle im include dort!*

Aber es findet sich auch sowas:

```
plugins {
    id 'de.kneitzel.java-application-conventions'
}
```
(de.kneitzel war das package, das ich angegeben hatte)

Jetzt habe ich schon ein plugin? Gut, dass ich das jetzt sehe. Und ich mache mich klein von wegen: "Ich kenne Gradle eigentlich nicht" und dann zeige ich hier, dass ich gar eigene Plugins habe ...

Ok, Spaß beiseite. Das muss ja irgendwo zu finden sein und wird dann wohl etwas generiertes sein 

Und wenn man sich die Verzeichnis angeschaut hat, dann sieht man noch ein buildSrc - das in der settings.gradle nicht erwähnt wurde ... 




__





						Organizing Gradle Projects
					





					docs.gradle.org
				





> Complex build logic is usually a good candidate for being encapsulated either as custom task or binary plugin. Custom task and plugin implementations should not live in the build script. It is very convenient to use buildSrc for that purpose as long as the code does not need to be shared among multiple, independent projects.



Da kommen also Build Elemente rein. Und wenn man da schaut, dann findet sich da auch das plugin, das eingebunden wurde:
`src/main/groovy/de.kneitzel.java-application-conventions.gradle`

```
plugins {
    // Apply the common convention plugin for shared build configuration between library and application projects.
    id 'de.kneitzel.java-common-conventions'

    // Apply the application plugin to add support for building a CLI application in Java.
    id 'application'
}
```

Und da findet sich dann:

```
plugins {
    // Apply the java Plugin to add support for Java.
    id 'java'
}

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
}

dependencies {
    constraints {
        // Define dependency versions as constraints
        implementation 'org.apache.commons:commons-text:1.9'
    }

    // Use JUnit Jupiter for testing.
    testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
}

tasks.named('test') {
    // Use JUnit Platform for unit tests.
    useJUnitPlatform()
}
```

Da haben wir dann auch endlich die Abhängigkeiten - Wenn man da das JUnit 5 ausgewählt hatte, dann hat man sich ggf, schon gefragt, so denn da die Abhängig blieb. 


Daher einfach einmal kurz zusammen gefasst, ist die Struktur:

settings.gradle (mit dem project name und dem include der childs!)
buildSrc/ (Mit plugins und definitionen für andere Elemente)

build.gradle
settings.gradle
src
child1/

build.gradle
src
child2/

build.gradle
src
...


----------



## KonradN (26. Nov 2022)

Ach so - das ist jetzt so eine einfache Struktur, die möglich ist und die ein gradle init bei dieser Auswahl aufbaut. Das muss nicht so sein. Wenn Du eine Android App erstellst, dann wirst Du in der Regel auch im Top Level eine build.gradle finden ... Daher ist das nur eine Erläuterung gewesen, was man vorfindet - aber keine Aussage, dass es genau so sein muss!


----------



## White_Fox (26. Nov 2022)

Puh...das ist ja schonmal allerhand, danke. Dann werde ich jetzt mal als erstes damit weitermachen, meine Bibliotheken dort unterzubringen. Danke soweit, ich bin bestimmt gleich mit weiteren Fragen zurück...


----------



## White_Fox (26. Nov 2022)

...und schon bin ich wieder da. 

Folgendes: Ich habe ein paar (eigene) Bibliotheksprojekte die ich zwar benutze, aber sonst eigentlich nicht Teil des Projekts sind. Wenn ich das Gradleprojekt jetzt weggebe, und der arme Tropf will es bauen, sucht er diese Bibliotheksprojekte natürlich vergeblich.

Jetzt ist mein Plan, Gradle vor einem Build dazu zu veranlassen, diese Dateien in das Projekt zu kopieren. Ich will also:

Schauen, ob ein bestimmter lokaler Ordner existiert. Wenn ja: Lösche die vorhanden Quelldateien und ziehe eine neue Kopie vom lokalen Ordner. Wenn nicht: Laß die vorhandenen Quelldateien in Ruhe und mache einfach weiter.
Die Bibliothek bauen.
Wie man Gradle mit Dateien arbeiten läßt habe ich in der Doku schon gesehen, aber wie kann ich festlegen daß das vor jedem Build durchgespielt wird?

Irgendwo habe ich gelesen daß solche Kopiererei nicht besonders clever ist, ich wüßte aber nicht wie es anders gehen sollte. Ich will das Ganze ja weggeben können ohne daß dieser werauchimmer Zugriff auf meine lokale Platte braucht. Wenn jemand eine bessere Idee hat, immer her damit.


----------



## KonradN (26. Nov 2022)

Dazu werden Abhängigkeiten in einem Repository bereit gestellt. Du kannst Deine Bibliotheken also auch bei maven central deployen. Oder auf GitHub. Oder auf einem eigenen Repository, das Du erstellst. Oder ...

Die andere Möglichkeit ist, dass Du die Bibliotheken so weiter gibst. Dann muss die Bibliothek erst gebaut und im lokalen Repository deployed werden. Danach kann dann das eigentliche Projekt gebaut werden.

Das wäre der Weg, wie er bei Maven üblich ist. Gradle nutzt die Maven Repositories ebenfalls und kann dies auch nutzen.




__





						Declaring repositories
					





					docs.gradle.org
				




Das deployen findet Du hier in der Dokumentation:


			Maven Publish Plugin


----------



## White_Fox (26. Nov 2022)

KonradN hat gesagt.:


> Die andere Möglichkeit ist, dass Du die Bibliotheken so weiter gibst. Dann muss die Bibliothek erst gebaut und im lokalen Repository deployed werden. Danach kann dann das eigentliche Projekt gebaut werden.


Genau das will ich, ja.

Wenn ich das mittlerweile richtig sehe, will ich einen Copytask schreiben, der stets vor dem assemble-Task ausgeführt wird.


----------



## KonradN (26. Nov 2022)

Ich verstehe die Problematik weiterhin nicht. Was genau ist denn Dein Problem?

Wenn Du die Library separat veröffentlichst, dann wäre ein Ansatz, dass Kunden erst diese Library bauen und ins lokale Repository deployen müssen. Danach kannst Du darauf normal als Dependency zugreifen.

Oder wen Du alles als ein Paket bauen willst, dann ist die Library einfach ein Projekt und du hast ein depends auf dieses Projekt.

Etwas, das auch geht, wenn Du die ganzen Reposities nicht willst: Du kannst auch einfach jar Files im Projekt hinterlegen und dann eine Abhängigkeit eintragen wie:

```
dependencies {
    implementation files('libs/something_local.jar')
}
```
Diese Variante ist aber etwas, das ich mit meiner Maven Denkweise aber strikt ablehne. Maven dürfte da eine Warnung ausspucken, dass Du das Ergbenis nicht in ein Repository deployen solltest.


----------



## KonradN (26. Nov 2022)

Altgernativ kannst Du auch ein Verzeichnis als Repository definieren und dann da jar Dateien als Abhängigkeit angeben:

```
repositories {
   flatDir {
       dirs 'libs'
   }
}


dependencies {
   implementation name: 'somelib-1.2.3'
}
```


----------



## White_Fox (26. Nov 2022)

KonradN hat gesagt.:


> Ich verstehe die Problematik weiterhin nicht. Was genau ist denn Dein Problem?


Nun, ich will das so machen wie du sagtest: Die Bibliothek als Unterprojekt mitliefern.

Ich möchte aber nicht das gesamte Projekt da hineinverschieben, sondern aus meinem eigentlichen Originalprojekt die Quelldateien rauskopieren. Wenn ich in Gradle einen Build anstoße, soll Gradle erst schauen ob ein angegebenes Verzeichnis existiert und falls ja, soll es von dort die Quelldateien in das Gradle-Teilprojekt hineinkopieren.

Der assemble-Task, so verstehe ich Gradle bisher, ist der Task der das Projekt baut. Der build-Task läßt erst Tests laufen und ruft dann den assemble-Task auf. Also will ich einen Task 'grabfiles' schreiben, der immer vor assemble aufgerufen wird.


----------



## White_Fox (26. Nov 2022)

Ah...ich habe es, glaube ich:


```
tasks.register('hello') {
    doLast {
        println 'Hello world!'
    }
}

tasks.matching { it.name != 'hello' }.all { Task task ->
    task.dependsOn hello
}
```

Das in der Datei build.gradle sorgt dafür, daß, wenn ich z.B. den build-Befehl gebe, "Hello World" ausgegeben wird.









						Creating a task that runs before all other tasks in gradle
					

I need to create an initialize task that will run before all other task when I execute it.  task A {     println "Task A" }  task initializer {    println "initialized" } If I execute gradle -q A,...




					stackoverflow.com


----------



## White_Fox (26. Nov 2022)

Also...es gelingt mir, zu ermitteln ob das Verzeichnis mit meiner externen Bibliothek existiert oder nicht.

Jetzt würde ich gerne den Ordner ".../lib/src/main" löschen, aber dabei bekomme ich immer eine Exception.
`delete '$rootProject.projectDir/src/'`

Irgendwelche Vorschläge?


----------



## White_Fox (26. Nov 2022)

So, ich habe was ich wollte und am Ende war es einfacher als gedacht. Dieser Task hier:


```
//Grab project files from project authors library if the directory exists, to ensure to have the last version here.
tasks.register('grabLocalFiles') {
    doLast {
        println "Looking for refreshing source code for EngineeringUtils library..."
        println "Current project path: $projectDir"
        def locallibdirectory = new File( '$projectDir/../../../../../../Java Bibliotheken/Eigene Bibliotheken/EngineeringUtils' )
      
        if(locallibdirectory.exists()) {
            print "EngineeringUtils located. Try to replace this project source files with external source files..."
        
            delete "src/main/"
            delete "src/test/"
        
            copy {
                from '/../../../../../../Java Bibliotheken/Eigene Bibliotheken/EngineeringUtils/src'
                into 'src/main/'
            }
            copy {
                from '/../../../../../../Java Bibliotheken/Eigene Bibliotheken/EngineeringUtils/test'
                into 'src/test/'
            }
            println "done"
        }
        else{
            println 'EngineeringUtils not located. Continue with existing project source files.'
        }
    }
}

tasks.matching { it.name != 'grabLocalFiles' }.all { Task task ->
    task.dependsOn grabLocalFiles
}
```

...navigiert erst etwas zurück und schaut, ob an einer bestimmten Stelle ein Ordner namens "EngineeringUtils" zu finden ist. Ist der Ordner zu finden, wird der existierende Quellcode gelöscht und der Code aus dem externen Bibliotheksprojekt reinkopiert. Das passiert nur wenn ich das Buildskript auf meinem Rechner ausführe, bei anderen würde dieser Schritt übergangen werden.

So habe ich die aktuelle Version von meinem Buildskript meiner Bibliothek immer drin, andere nehmen das was bereits da ist. 


So langsam macht Gradle etwas Spaß.


----------



## thecain (26. Nov 2022)

Ich würde keinen Code von Ausserhalb dem Projekt referenzieren. Das verfehlt ein bisschen das Ziel von Gradle...


----------



## mihe7 (27. Nov 2022)

White_Fox hat gesagt.:


> So langsam macht Gradle etwas Spaß.


Sagt "Spaß" zu "Gradle": "Jeder Satz ist zu klein für uns beide."


----------



## KonradN (27. Nov 2022)

Ahh, jetzt habe ich auch den Sinn dahinter verstanden. Irgendwie hatte ich das bis eben nicht wirklich verstanden, was Du da versuchst.

Der Ansatz würde mir Bauchschmerzen bereiten. Ich bin es gewohnt, dass Libraries auch versioniert sind. Wenn Du nicht über Maven Repositories gehen willst, dann würde ich eher darüber nachdenken, die Libraries als jar einzufügen.

Evtl. ist es einfacher zu verstehen, wenn ich die Problematik erläutere:
Du hast zwei Produkte: prod1, prod2
und eine Library: lib
Du hast eine Variante von prod1 die natürlich lib nutzt. Alles toll! prod1 wird ausgeliefert.
Nun kommt prod2. Du entwickelst prod2 und dabei kommen Dinge, die in die Library gehören. lib wird also angepasst. Breaking Changes kommen. Da war etwas, dessen Konzept jetzt erweitert wurde und der damalige Ansatz ist damit massiv verändert. Aber alles super: Du hast prod2 fertig und lib ist in einer neuen Version.

Jetzt kommt plötzlich raus: Security Issue in prod1. Du musst es sofort anpassen und auch sofort releasen. Jetzt packst Du Dein Gradle Projekt an und schwupps: lib ist aktualisiert. Statt einem schnellen Securityfix darfst Du nun prod1 anpassen, damit es mit der neuen Version der Library arbeitet.

==> Es wird hoffentlich deutlich: Sowas will man nicht. Die Aktualisierung sollte immer ein aktiver Part eines Entwicklers sein.

Wir haben damals (noch C# Zeiten) auch ohne Repositories gearbeitet (Da wären es nicht maven repositories sondern nuget repositories). Da waren die Abhängigkeiten als DLLs (halt .Net Assemblies) eingebunden. Und wir hatten ein Set von Scripten, die unsere Abhängigkeiten aktualisiert haben. Im Rahmen der Entwicklung haben wir dann auch immer die Abhängigeiten auf einen aktuellen Stand gebracht - so dies im Zeitplan vorgesehen war. 

Daher ganz wichtig: Versionierungen! Das ist das A und O.


----------



## White_Fox (27. Nov 2022)

KonradN hat gesagt.:


> Ich bin es gewohnt, dass Libraries auch versioniert sind.


Ja....ich auch. Das war der Grund schlechthin für diese Idee. Ich habe mehrere Bibliotheksprojekte hier, in verschiedenen Repositories. Für das Projekt sind sie ok, aber ansonsten zu nutzlos um sie auf Maven hochzuladen.

Ich verstehe das Problem, auf das du hinauswillst...danke erstmal für den Hinweis. Da muß ich erstmal über eine Lösung nachdenken, wie ich das besser handhabe. Vielleicht fällt mir etwas besseres ein wenn ich mit Gradle besser umgehen kann, ich stehe ja noch ganz am Anfang.
Die Sache ist, das mir ein Kollege etwas bei meinem Projekt helfen will, daher habe ich jetzt etwas Not, Gradle anständig zum Laufen zu bringen. Diese externen Bibliotheken sind allerdings sehr klein, so daß man da noch nichteinmal von einem richtigen Konzept sprechen kann, und da kommt in nächster Zeit vorraussichtlich nichts dazu.

Anders würde es, wenn ich die Zeit und Muße hätte, alle Ideen die ich habe umzusetzen...aber für einen Hardwareentwickler ist das wahrscheinlich viel zu viel Software. Wenn ich daran denke wie zeitintensiv alleine dieses eine kleine Projekt schon geworden ist...mal sehen was ich mir einfallen lasse.


----------



## White_Fox (27. Nov 2022)

Nächstes Problem: So wie es aussieht, bekomme ich meine Bibliothek nicht eingebunden. Wenn ich den Build-Task vom Hauptprojekt anschubse, kommt mir Powershell mit dieser Meldung zurück:


> No matching configuration of project :EngineeringUtils was found. The consumer was configured to find a runtime of a library compatible with Java 16, packaged as a jar, preferably optimized for standard JVMs, and its dependencies declared externally but:
> - None of the consumable configurations have attributes.



So wie ich das verstehe sucht Gradle nach einer compilierten jar, und findet die nicht. Anscheinend ist das auch kein Wunder, ich liefere ja nur Quellcode. Allerdings wird die EngineeringUtils-Bibliothek einwandfrei gebaut, wenn ich deren Buildtask anschubse.
Wie bekomme ich Gradle denn beigebracht daß es die Bibliotheken erst kompiliert? Oder, besser, versucht die Bibliotheken zu kompilieren wenn es keine jar gefunden hat?

PS: Wenn ich die Bibliothek erst manuell baue (der durchläuft und eine lib.jar im buildordner hinterläßt, ist das so richtig?) und dann den Build für das Hauptprojekt, kommt der Fehler immer noch. Der sollte aber spätestens dann nach meinem Verständnis verschwinden. Was sehe ich da falsch?


----------



## KonradN (27. Nov 2022)

White_Fox hat gesagt.:


> Da muß ich erstmal über eine Lösung nachdenken, wie ich das besser handhabe.


Evtl. reicht es ja schon aus, dass dieses Kopieren ein Task ist, der nicht automatisch angestoßen wird. Also nur bei einem gradlew updateDependencies oder so wird dieses Kopieren gemacht. Das wäre dann etwas, das man machen könnte.



White_Fox hat gesagt.:


> So wie ich das verstehe sucht Gradle nach einer compilierten jar, und findet die nicht. Anscheinend ist das auch kein Wunder, ich liefere ja nur Quellcode. Allerdings wird die EngineeringUtils-Bibliothek einwandfrei gebaut, wenn ich deren Buildtask anschubse.
> Wie bekomme ich Gradle denn beigebracht daß es die Bibliotheken erst kompiliert? Oder, besser, versucht die Bibliotheken zu kompilieren wenn es keine jar gefunden hat?
> 
> PS: Wenn ich die Bibliothek erst manuell baue (der durchläuft und eine lib.jar im buildordner hinterläßt, ist das so richtig?) und dann den Build für das Hauptprojekt, kommt der Fehler immer noch. Der sollte aber spätestens dann nach meinem Verständnis verschwinden. Was sehe ich da falsch?


Hier ist die Frage, wie genau Du das eingebunden hast.
a) Wenn Du den Sourcecode lieferst, dann muss das natürlich ein Gradle "Projekt" (Ich bin hier nicht sicher, wie hier die Gradle Terminologie ist. In Maven wäre es ein Modul) sein, das gebaut wird. Also genau so, wie die Library auch in dem per gradle init gebauten Projekt: Einbindung, dass es gebaut wird per include in settings.gradle und dann Abhänggikeit per `implementation project(':mylib')` (So das im Ordner mylib wäre.)
Das sollte dann funktionieren, denn die Lib würde gebaut und das gebaute eingebunden. (So die mylib auch per gradle im Original genaut wird, dann muss natürlich das ganze bauen gleich sein also was Dein Projekt im buildSrc hat, muss mit dem der Library auch stimmen. Das muss kein Problem sein, wenn ihr das alles unter eurer Kontrolle habt. Aber das sind halt so unerwartete Abhängigkeiten, die ich vermeiden würde.)

b) Bei der Einbindung der jar Datei: Wie bindest Du die genau ein? Hast Du die Sourcen der Library wirklich richtig entfernt? Wenn Du da Details nennst, dann kann man da ja durchaus etwas schauen.

Ggf. kann es sinnvoll sein, auf Github mal ein minimales Beispiel zu erstellen. Du kannst da ja ein Repository erstellen, in dem Du dann nur Unterordner hast wie library und project. In Library dann die Library (die Du vermutlich auch eigenständig bauen könntest, also als eigenständiges Gradle Projekt) und dann in Project wäre das eigentliche Projekt mit der Einbinung der Library (egal wie - such Dir aus, wie Du es gerne haben möchtest und baue es einmal. Also gerne mit kopieren von ../../../library/src oder so ... Also übergreifender Zugriff.
Wenn man mehrere Möglichkeiten probieren will: Da kannst Du ja Branche erstellen.

Mit sowas hätte man die Möglichkeit, deine Versuche im Ganzen zu sehen und Ideen / Lösungsvorschläge konkreter zu bringen.


----------



## White_Fox (27. Nov 2022)

Ich hab hier mal hochgeladen was ich gerade habe.


			https://sourceforge.net/projects/jcls/files/jCLS.zip/download
		


Da fehlen aber noch einige Abhängigkeiten, aber die kommen dann wirklich aus irgendwelchen Onlinequellen.


----------



## mihe7 (27. Nov 2022)

White_Fox hat gesagt.:


> aber ansonsten zu nutzlos um sie auf Maven hochzuladen.


Würde es nicht reichen, das Zeug ins lokale Maven Repo zu legen?


----------



## White_Fox (27. Nov 2022)

Och nö, von Maven habe ich ja noch weniger Ahnung als von Gradle...


----------



## KonradN (27. Nov 2022)

White_Fox hat gesagt.:


> Och nö, von Maven habe ich ja noch weniger Ahnung als von Gradle...


Gradle nutzt auch Maven Repositories! 

Und ich habe Dir schon Links gegeben (#9), wo es darum ging, dass Gradle etwas ins lokale Maven Repository legt bzw. von dort Abhängigkeiten lädt. Denn das ist ja eigentlich der normale Weg.

Und ich frage mich: Wie "nützlich" muss etwas sein, das auf Maven Cebntral hochgeladen wird? Aber es muss ja nicht einmal Maven Cebntral sein. Man könnte ebenso Github nutzen (Github packages nennt es sich dort wohl).  Und spätestens bei Github ist die Frage nach den nützlich irrelevant. Da habe ich z.B. für Java Forum Threads ein Repository und die zwei Maven Repositories, in denen ich meine Maven Projektvorlagen habe. Ob das wirklich einen Nutzen hat? (Wobei ja hier im Forum schon Leute damit aufgeschlagen sind!)

Du willst etwas veröffentlichen und da bietet sich das an. Man kann aber auch gerne selbst hosten. Das ist ebenso in Ordnung und kann bei Firmen eine valide Idee sein.


----------



## White_Fox (27. Nov 2022)

KonradN hat gesagt.:


> Gradle nutzt auch Maven Repositories!


Ich weiß. Aber anlegen müßte ich ein Maven Repository trotzdem erstmal, eine POM-Datei schreiben, usw. , und ich möchte nicht zwei Buildsysteme parallel lernen...ich meine, fast jeder den ich kenne der irgendwas mit Software macht beschränkt sich vornehmlich auf eines von beiden. Und ich als ausgewiesener Nicht-Programmierer, der eigentlich mit nichts von alledem etwas zu tun haben will, zieht sich jetzt beide rein...

Außerdem steht mir dann noch demnächst etwas Einarbeitung in Git bevor. Da habe ich mich schonmal etwas eingelesen, vor zwei oder drei Jahren, aber das muß ich auch wieder auffrischen.

Nee, das muß ohne Maven gehen. Es ist ja nichtmal viel Quellcode, die Kompilierzeit nehme ich da in Kauf.


----------



## KonradN (27. Nov 2022)

White_Fox hat gesagt.:


> Och nö, von Maven habe ich ja noch weniger Ahnung als von Gradle...


Ach ja - da wäre auch noch anzumerken: Das was Gradle da an Projekten aufbaut ist aus meiner Sicht schon überkompliziert. Schau Dir die ganzen Ordner an und so. Das ist einfach nur Wahnsinn!

Maven ist da deutlich weniger komplex. Bei Maven ist die Kernidee immer: Convention over Configuration! Das ist bei Gradle nicht der Fall. Gradle ist da mehr ein ant - man macht seine eigenen Ziele und die werden irgendwie aufgebaut. Die Chance, dass Du da etwas kopieren kannst ist deutlich geringer. Und bei so Projekten zu unterstützen im Forum ist Hölle. Aus "Poste mal die pom.xml" wird dann ein:
Poste bitte: settings.gradle und build.gradle aus allen Verzeichnissen (also ., ./buildsrc, ./app, ...)

Aus einem "Füge in der POM (an der richtigen Stelle) mal ein: ....
wird ein: "Füge in der build.gradle in app (Aber nicht im root!) ein: ... 
(Kann natürlich auch unterschiedlich sein ...

Oder Diskussionen a.la. "Wieso hast Du dass den in der build.xml eingetragen und nicht jener?

Das sind so Gründe, wieso ich mich klar für Maven entschieden habe und nur darauf aufsetze.

Maven ist dumm. Maven kann (fast) nichts. Alles, was maven kennt, sind drei Lifecycle: clean, site und build. Und das war es. Maven kann nichts übersetzen oder so. Maven kann noch nicht einmal ein simples clean!
Die Funktionalität kommt durch Plugins. Man kann also nach und nach Plugins lernen. In einer "super pom" sind gewisse Plugins eingebunden und daher kann Maven dann auch ohne groß Konfioguration doch einiges - aber wichtig: Das ist nicht Maven - das sind die Plugins!

Das macht alles extrem einfacher!

Das ist ansonsten so wie: Die eingebauten Logging Klassen reichen mir nicht - man bindet ein super duper Loggingframework ein. Das kann dann so viel mehr! Man braucht es zwar nicht, aber heya: Dieses Logging Framework kann auch die Kaffeemaschine bedienen, meinen Tesla vorfahren, wenn ich den Build komplett zerhauen habe und ich schnell weg muss ehe meine Kollegen mich kriegen und und und ...

Also immer die klare Überlegung: Was brauche ich?


----------



## mihe7 (27. Nov 2022)

White_Fox hat gesagt.:


> Aber anlegen müßte ich ein Maven Repository trotzdem erstmal, eine POM-Datei schreiben, usw. ,


Nein, das muss Gradle automatisch können. Wenn ich es richtig sehe: maven-publish-Plugin hinzufügen, und den Task publishToMavenLocal ausführen.

Nachtrag: und in der die Lib nutzenden App wirst Du vermutlich noch ein Repository mavenLocal() einfügen müssen.


----------



## KonradN (27. Nov 2022)

White_Fox hat gesagt.:


> Ich weiß. Aber anlegen müßte ich ein Maven Repository trotzdem erstmal, eine POM-Datei schreiben, usw. , und ich möchte nicht zwei Buildsysteme parallel lernen...ich meine, fast jeder den ich kenne der irgendwas mit Software macht beschränkt sich vornehmlich auf eines von beiden. Und ich als ausgewiesener Nicht-Programmierer, der eigentlich mit nichts von alledem etwas zu tun haben will, zieht sich jetzt beide rein...


Du musst dich da in nichts einarbeiten. Gradle nutzt Maven Repositories. Das ist also auch fester Bestandteil von Gradle. Und wie das genau aufgebaut ist und so muss Dich nicht interessieren. Das kann man sich ansehen, aber heya - ich würde schätzen, dass 90% der Maven Nutzer keine Ahnung haben, wie das Repository aufgebaut ist und was es da so für Dateien gibt und was da in die pom gehört und was nicht ...


----------



## mihe7 (27. Nov 2022)

KonradN hat gesagt.:


> Das kann man sich ansehen, aber heya - ich würde schätzen, dass 90% der Maven Nutzer keine Ahnung haben, wie das Repository aufgebaut ist und was es da so für Dateien gibt und was da in die pom gehört und was nicht ...


Wenn ich mir anschaue, was da so rumrennt, dann biete ich 99 %. Dann zähle ich mich zu den 20 %, die zumindest den groben Aufbau kennen, aber so Dinge wie _remote_repositories interessieren mich nun echt nicht


----------



## White_Fox (27. Nov 2022)

Leute, ihr macht mich fertig.

Wobei, wenn ich so darüber nachdenke: Das einzige Projekt, was ich in Netbeans ohne Probleme bauen konnte, war ControlsFX das mit Gradle arbeitet. An allen, wirklich allen anderen Projekte und Bibliotheken, die ich je irgendwo runtergeladen habe, hatte das entsprechende Plugin irgendetwas auszusetzen und brach mit irgendeinem Fehler ab.


----------



## KonradN (27. Nov 2022)

White_Fox hat gesagt.:


> Leute, ihr macht mich fertig.


Jo, das ist unsere Absicht 😈

Generell ist es ja ok, dass Du gradle nimmst. Nur eben nutzt Gradle halt auch Maven Repositories. Die Arbeitsmittel sind also prinzipiell ähnlich. Und die Arbeitsweisen unterscheiden sich dann nicht wirklich.


----------



## White_Fox (3. Dez 2022)

So Leute, nach einigem Brüten über der Doku stecke ich nach wie vor fest. Hier steht anscheinend was ich wissen will, verstehe es allerdings nicht:




__





						Declaring Dependencies between Subprojects
					





					docs.gradle.org
				




Den Code verstehe ich komplett gar nicht, ich kann den Code den Beispielen weiter oben, wo es die Verzeichnisbäume gibt, einfach nicht einordnen.

Gradle beschwert sich, daß eine Abhängigkeit von "EngineeringUtils.jar" eingetragen wurde, also habe ich im Buildfile des Hauptprojekts doch alles richtig gemacht. Andererseits baut Gradle "EngineeringUtils.jar" doch ohne Anstand, legt den Buildoutputordner selber an, Gradle sollte doch wohl wissen wo es den Buildoutput reinwirft oder nicht?


----------



## KonradN (3. Dez 2022)

Hast du das erstellter jar direkt angegeben? Man hat eine Abhängigkeit zu dem Projekt….


----------



## White_Fox (3. Dez 2022)

Nö...ich habe das so gemacht wie das, was der gradle init-Befehl auswirft:


```
dependencies {
    implementation project('EngineeringUtils')
}
```


----------



## White_Fox (9. Dez 2022)

Ich habe es endlich hinbekommen, die Bibliothek einzubinden, Gradle meckert jetzt nicht mehr. Ich habe schlicht den gesamten Ordner von EngineeringUtils in die Abhängigkeitsdeklaration geworfen, irgendwo darin wird es jetzt schon die .jar finden. Meiner Meinung nach eine häßliche Lösung und ich würde lieber Gradle lieber direkt sagen daß ich das Buildartifact haben will, aber es war von allen Versuchen der einzige der funktioniert hat. 

Jetzt hängt Gradle dabei, einen Annotationsprozessor einzuhängen den ich ebenfalls als Unterprojekt führe. Hier funktioniert das aber nicht, was bei EngineeringUtils funktioniert hat. Mag sich das bitte mal jemand anschauen? Vielleicht hat jemand anders noch eine Idee...


----------

