Cours 1 : Outillage
Java
Pour développer en Java, nous avons besoin d'installer un JDK (Java Development Kit). La dernière version LTS (Long Term Support) est la version 21.
Installation d'OpenJDK 21
Télécharger le setup.
Exécuter le fichier MSI et suivre les instructions
Télécharger l'installeur PKG
Exécuter l'installeur PKG :
Installer les packages nécessaires :
Installer le dépôt APT de AdoptOpenJDK :
Installer OpenJDK 21 :
Pour vérifier la bonne installation du JDK :
Le résultat devrait ressembler à :
IntelliJ IDEA
IntelliJ IDEA est un environment de développement intégré (IDE) pour le développement avec les différents langages ciblant la JVM. Il est très puissant et est largement utilisé dans l'industrie. C'est celui qui sera utilisé pour le cours.
Installation d'IntelliJ
Git
Qu'est-ce que Git ?
Git est un système de gestion de version (version control system ou VCS en anglais). Il en existe d'autre (Mercurial, SVN), mais git est de loin le plus utilisé de nos jours.
L'objectif du système de gestion de version est de versionner efficacement notre code, suivre précisément les changements qu'on y apporte, et naviguer facilement à travers les différentes versions. Cela est très important, car cela permet de ne jamais perdre de changement, ou de pouvoir revenir en arrière en cas soucis par exemple.
Git facilite également la coopération à plusieurs sur un projet. Il permet de travailler en parallèle et de réconcilier les versions qui ont divergé.
Concept importants
Commit
Un commit est une sauvegarde de l'intégralité d'une version du projet à un instant T. Il représente une étape dans l'historique
Branche
Permet de faire diverger en parallèle plusieurs versions du projet pour pouvoir les réconcilier facilement plus tard.
Installer git
Configuration du compte local :
Créer un dépot local
Workflow Git "de base"
Créer un commit
git add .
: ajouter tous les changements au tracking gitgit commit -m "Message de commit"
: créer un commit avec les changements
Créer une branche
git branch nomDeLaBranche
: créer la branchegit checkout nomDeLaBranche
: se positionner sur la branche
Fusion
Pour rapport les changements d'une branche sur une autre, on fusionne :
Pour fusionner (merge) la branche b2 dans la branche b1
Il peut y avoir des conflits à résoudre si les mêmes lignes ont été changées dans les historiques divergents.
Conflits de fusion
Lorsque les deux branches que vous voulez fusionner contiennent des modifications différentes des mêmes lignes, un conflit de fusion apparaît, il faut donc le régler.
Après avoir fait votre commande de fusion qui avait des conflits, git se met en mode résolution de conflit, et va faire apparaitre dans les fichiers contenant des conflits les deux versions des lignes qui sont en conflits sous le format suivant :
Il faut donc soit garder une des deux versions et supprimer totalement l'autre, ou alors faire un nouveau changement à partir des deux versions, ce qui a du sens dans le contexte du code sur cette ligne. Les marqueurs de conflits (<<<<<<<
, =======
, >>>>>>>
) doivent être supprimés pour que git considère le conflit résolu.
Une fois tous les conflits résolus, on peut commiter les changements (git add .
et git commit -m "conflict resolved"
) afin de marquer la résolution du conflit.
Serveurs
On utilise un dépot distant pour se synchroniser avec les gens avec qui on coopère. Il y a principalement :
Github
Gitlab
Ajouter un dépot distant
Intéractions avec un dépot distant
Pousser des changements :
Tirer des changements :
Mettre à jour les infos sur le dépot distant :
Récapitulatif des espaces git et de leurs intéractions
Récapitulatif du workflow de base pour implémenter une fonctionnalité
Se positionner sur la branche principale :
git checkout master
Mettre à jour la branche principale :
git pull origin master
(origin étant le nom standard pour un dépôt distant, mais ce nom est personnalisable)Créer une nouvelle branche à partir de la branche principale :
git branch maFeature
Se positionner sur la nouvelle branche :
git checkout maFeature
Faire des changements dans le code
Ajouter les changements à git :
git add .
Créer un nouveau commit avec les changements :
git commit -a -m "message de commit"
Pousser les changements :
git push origin maFeature
Retourner sur master :
git checkout master
Fusionner la branche de feature :
git merge maFeature
Avec ce workflow, on peut travail à plusieurs, tant que chacun a sa branche, sans avoir peur d'écraser les changements des autres.
Outils recommandés
Outil du cours : Intégration Git de IntelliJ IDEA.
Autres outils intéressants :
GitLab
GitLab est une des nombreuses options qui existent en tant que serveur git. Un serveur git est un serveur qui va permettre à toutes les personnes travaillant sur un projet de synchroniser leur travail, car GitLab héberge un dépôt distant. GitLab fournit également des outils de coopération, notamment la revue de code.
La revue de code permet de vérifier le code de ses collègues pour vérifier s'il ne contient pas de problème, mais aussi pour suggérer des améliorations de qualité.
Nous utiliserons GitLab.com pour ce module. Vous aurez donc besoin de créer un compte dessus.
Gradle
Qu'est-ce que Gradle ?
Gradle est un outil de build (build tool), il permet de structurer notre projet, de définir comment un projet doit être compilé, packagé, exécuté, et testé.
Gradle est, avec Maven, l'un des outils de build de l'écosystème Java les plus utilisés, il a l'avantage d'être plus moderne que Maven. Il est très (parfois trop) puissant, mais il permet de gagner beaucoup de temps.
Installer gradle
Télécharger la dernière distribution Gradle
Extraire l'archive à l'endroit où vous souhaitez l'installer (ex : C:/tools/gradle)
Configurer l'environment : ajoutez une variable d'environment système
GRADLE_HOME
à votrePATH
, avec comme valeur le chemin du répertoire où vous avez extrait l'archive
Télécharger la dernière distribution Gradle
Extraire l'archive à l'endroit où vous souhaitez l'installer (ex : /opt/gradle)
Configurer l'environment : ajoutez une variable
GRADLE_HOME
à votrePATH
, avec comme valeur le chemin du répertoire où vous avez extrait l'archive
Pour vérifier que Gradle fonctionne correctement :
Le résultat devrait être :
Création d'un projet Java avec Gradle
Commencer par créer un dossier pour le projet, puis se positionner dans ce dossier :
Ensuite, initialiser le projet avec :
Suivre le script d'installation avec les options suivantes :
Type de projet :
application
Langage :
Java
Sous-projets :
no
Langage de script de build :
Groovy
Framework de tests :
JUnit Jupiter
Nom du projet : au choix
Nom du paquet :
fr.<votre prenom suivi de votre non de famille, en miniscule, sans accent, tout collé>
Version de Java cible : 21
Nouvelles APIs :
no
Structure du projet Gradle
Le dossier
gradle
, les scriptsgradlew
etgradlew.bat
constituent le "wrapper" gradle. Il s'agit d'une version portable de votre application qui vit dans votre répertoire projet. Ainsi, vous contrôlez précisément la version de gradle utilisée, et les personnes qui vont télécharger votre projet n'auront pas besoin d'installer Gradle pour le construire.Le fichier
settings.gradle
est le fichier de méta-données du projet pour Gradle.Le dossier
app
est le module qui correspond à l'application. Un projet peut éventuellement contenir plusieurs modules.Le fichier
app/build.gradle
, est le script de build de votre module. Il contient les instructions Gradle pour le compiler, exécuter et packager.Le fichier
src
contient le code source de votre module ; le code de production et les tests.
Décortiquons un peu le contenu des fichiers spécifiques à Gradle.
settings.gradle
Le fichier de méta-données du projet contient un ajout de plugin qui permet d'installer automatiquement un JDK en cas d'absence. Ce n'est pas requis dans notre cas (et dans la plupart des cas). C'est un élément rajouté par le template du script d'initialisation, et peut être supprimé sans soucis.
Les deux autres déclarations sont :
rootProject.name = 'mon-projet'
: déclaration du nom du projetinclude('app')
: le projet contient un module, dans le dossierapp
. Gradle s'attend à trouver dans ce dossier un script de build pour le module nommébuild.gradle
app/build.gradle
plugins
: l'ajout du projetapplication
permet de configurer le module comme une application console, c'est-à-dire un programme qui a un point d'entrée (une méthode main), exécutable en ligne de commande, par opposition par exemple à un module de typelibrary
, qui n'aurait pas de point d'entrée, et qui aurait vocation à être importée par un autre module qui en utiliserait les classes.repositories
: avecmavenCentral()
on désigne le dépôt depuis lequel les dépendances déclarées seront téléchargées comme MavenCentral. Ce dernier est le dépôt de paquets Java standard (un peu comme NPM / nuget / cargo, etc).dependencies
: ici, on déclare les dépendances du projet. Plus de détail là-dessus dans la partie suivante.java
: permet de déclarer la version de Java utilisée par le module.application
: permet de déclarer la classe principale de l'application console, qui sert de point d'entrée pour l'exécution. C'est la classe qui contient la méthodemain
tasks.named('test')
: permet de déclarer l'utilisation de JUnit pour les tests.
Commandes de base
Le script wrapper gradlew.bat
est à utiliser sous Windows, le script wrapper gradlew
, est à utiliser sous MacOS et Linux.
Commandes :
Pour exécuter l'application :
./gradlew run
Pour exécuter les tests :
./gradlew test
Gérer les dépendances avec Gradle
La plupart des projets Java ont besoin de dépendances, pour éviter de toujours réinventer la roue. Les dépendances sont gérées dans un script de build Gradle via :
La déclaration du dépôt de paquet. C'est toujours MavenCentral pour les librairies publiques. Mais des entreprises peuvent avoir des dépôts privés pour leurs propres paquets.
La déclaration des dépendances :
La déclaration de dépendance vers un paquet se divise en deux parties.
Scope (portée) de la dépendance
La portée de la dépendance définit à quel moment du build la dépendance intervient :
compileOnly
: pour les dépendances qui sont utilisées seulement pour compiler le code de production, mais n'ont pas besoin d'être présent au moment de l'exécutionimplementation
: pour les dépendances utilisées à la compilation et à l'exécutionruntimeOnly
: pour les dépendances utilisées uniquement à l'exécutiontestCompileOnly
: équivalent decompileOnly
pour les teststestImplementation
: équivalent deruntimeOnly
pour les tests
Identifiant du paquet
L'identifiant du paquet (ex : org.junit.jupiter:junit-jupiter:5.9.2
) désigne le paquet sur dépôt. Il se divise en trois parties, séparées par des :
:
L'identifiant du groupe, en gros la personne/entité autrice du paquet :
org.junit.platform
L'identifiant du paquet :
junit-jupiter
Le numéro de version :
5.9.2
Intégration entre IntelliJ et Gradle
Gradle étant un outil très important pour développer en Java, IntelliJ propose une intégration de l'outil.
Intégration des scripts de build
Les scripts de build sont parsés et utilisés par IntelliJ pour rendre votre projet Gradle directement utilisable lorsque vous l'ouvrez dans l'IDE, notamment en téléchargeant et indexant les dépendances, et en adaptant sa configuration avec ce qui est déclaré dans les scripts.
Ainsi, à chaque fois que vous modifiez un script de build, l'IDE vous propose comme action contextuelle de re-parser votre script :
Appuyez sur ce bouton à chaque fois que vous avez terminé vos changements de script de build afin qu'ils soient pris en compte par l'IDE.
Intégration des commandes
Il est également possible d'exécuter des commandes Gradle directement depuis l'interface graphique de l'IDE, via l'outil Gradle qui est général en haut à droite :
Vous avez dans cette interface la liste des commandes disponibles dans chaque module, il suffit de double cliquer sur une commande pour l'exécuter dans l'interface graphique de l'IDE et avoir une mise en forme du résultat, notamment par exemple pour les tests :