L'entreprise Gradle est incroyable ! Elle fourni une extension Maven (payante) permettant à ce dernier de bénéficier du cache de Gradle.
Imaginez que vous soyez tellement performant par rapport à votre concurrent direct que vous vous permettiez de l'améliorer et d'en faire un produit d'appel !
Merci @Philou pour l'info.
Correspondances des goals Maven en Gradle :
Maven | Gradle |
---|---|
mvn clean | gradle clean |
mvn compile | gradle compile |
mvn test | gradle test |
mvn package | gradle assemble |
mvn verify | gradle check |
mvn install | task publishToMavenLocal |
mvn deploy | gradle publish |
Transformer automatiquement un pom.xml
en build.gradle
via la commande gradle init.
La page de configuration du plugin que je ne retrouve jamais.
Les liens vers les fichiers de base de données de vulnérabilités (CVE) du consortium OWASP.
Afin de renforcer vos build Maven et garantir que vos 'pom.xml' ne tirent pas de dépendances inutiles vous pouvez configurer votre maven-dependency-plugin
avec l'exécution suivante :
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>analyze</id>
<goals>
<goal>analyze-only</goal>
</goals>
<configuration>
<failOnWarning>true</failOnWarning>
<outputXML>true</outputXML>
</configuration>
</execution>
</executions>
</plugin>
Builder des modules en parallèle sous Maven, je me le note pour reminder (car je l'oublie tout le temps) :
mvn -T 4 clean install # Builds with 4 threads
mvn -T 1C clean install # 1 thread per cpu core
mvn -T 1.5C clean install # 1.5 thread per cpu core
Je me note la dépendance :
<dependency>
<groupId>com.oracle.substratevm</groupId>
<artifactId>svm</artifactId>
<version>1.0.0-rc8</version>
<scope>provided</scope>
</dependency>
Il faudra que je fasse un poc à ce sujet.
Concept :
- J'importe un JAR avec Maven.
- Je développe pendant 6 mois.
- Je veux savoir si mes classes utilisent encore au moins une classe de ce JAR (où s'il faut virer cette dépendance).
J'utiliserai :
mvn dependency:analyze
@Animal : tu ne devrais pas modifier le fichier settings.xml pour y intégrer Sonar mais ajouter cela dans un pom.xml.
Dit autrement :
- Le settings.xml de l'install de Maven est un pom.xml.
- Tout projet Maven buildé par cette install de Maven va hériter de ce settings.xml (y compris les autres users de l'OS).
- Mieux vaut privilégier son settings.xml dans $HOME/.m2/settings.xml.
- Mieux vaut encore l'intégrer au pom.xml du projet qui est concerné par Sonar (dans le sens où rien ne fonctionnerait avec un Maven Wrapper).
Le diagramme dont je me sers le plus pour expliquer les phases principales du cycle de vie de Maven.
Rappel
Maven Wrapper est un petit script à positionner à la racine de votre projet et qui vous permettra :
- De définir la bonne version de Maven avec laquelle vous pouvez builder votre projet.
- De récupérer automatiquement cette version
Problème
Pour exécuter vos commandes de build, il ne faut plus taper
mvn clean install
mais
./mvnw clean install
Inconvénients :
- Le "./" a ajouter devant la commande est fastidieux.
- Si vous êtes dans un sous-module, vous devrez faire un "../mvnw clean install" et cela fait perdre du temps.
Solution
Elle est en trois phases :
-
Installer une version de Maven dans votre poste
- Sans l'ajouter à votre PATH
- Mais en créant la variable MAVEN_HOME
-
Ajouter le script suivant dans votre .bashrc
_build_mvnw_dir() {
echo "$1/mvnw"
}
_find_mvnw() {
currentDir=`pwd`
while [ "$currentDir" != "" ]; do
isMvnwDir=`_is_mvnw_dir "$currentDir"`
if [ "$isMvnwDir" == "true" ]; then
break
else
currentDir=`_get_parent_dir "$currentDir"`
fi
done
if [ "$currentDir" == "" ]; then
echo ""
else
_build_mvnw_dir "$currentDir"
fi
}
_get_parent_dir() {
echo "$currentDir" | sed "s|^\(.*\)/[^/.]*$|\1|"
}
_is_mvnw_dir() {
if [ -f "$1/mvnw" ]; then
echo "true"
else
echo "false"
fi
}
_mvn() {
mvnwPath=`_find_mvnw`
if [ "$mvnwPath" == "" ]; then
$MAVEN_HOME/bin/mvn $*
else
eval "$mvnwPath $*"
fi
}
- Ajouter l'alias suivant à votre .bash_aliases
alias mvn='_mvn'
Fonctionnement
Utiliser Maven comme vous en avez l'habitude, le script va simplement utilise Maven Wrapper s'il est définit dans votre projet, sinon il utiliser l'installation "par défaut" que vous avez faite de Maven dans le répertoire $MAVEN_HOME.
Après investigation, ton problème est dû à la cross-compilation entre deux versions du JDK.
Explications
Tu essaies de compiler des sources Java en syntaxe 8 pour qu'elles soient compilées dans un bytecode dont le format sera à destination d'une JRE 8.
Or, tu opères cette compilation depuis un JDK 10. Que se passe-t-il alors ?
Simplement que le compilateur t'avertie que la JRE 8 a une certaine API et que ton JDK 10 contient l'API 8 + toutes les classes qui ont été ajoutées dans Java 9 et 10. Ce faisant, si tu venais à utiliser une classe n'existant que dans Java 10, alors même si le bytecode que le compilateur produit à partir de tes sources est à destination de Java 8, tu ne pourras pas lancer ton programme et tu auras une ClassNotFoundException.
Le JDK 10 ne pouvant pas savoir quelles classes ne se trouvent que dans Java 10, il te demande un bootstrap classpath, c'est-à-dire un chemin vers le fichier rt.jar d'un JDK 8, afin de ne te permettre de n'utiliser que des classes de l'API de Java 8 dans ton code.
Ainsi, le JDK 10 n'utilisera plus son rt.jar à lui qui est trop récent, mais l'ancien.
Solution
Ajouter dans la configuration du maven-compiler-plugin l'option
Il faut aussi que la variable $JRE8_HOME soit définie dans ton OS.
Et voilà.
N.B : en ce qui concerne les modules de Java 9, c'était une fausse piste, mea maxima culpa !
Voici les étapes à suivre :
- Sélectionnez le module Maven dans l'encradé Project.
- Puis dans le menu principale aller dans Run > Edit Configurations...
- Dans la colonne de gauche, choisissez votre framework (dans mon cas c'est Default > TestNG).
- Dans l'encadré à droite, en bas, intitulé : "Before launch, Maven goal, Activate tool window" ajoutez le goal suivant en dessous du build :
org.javalite:activejdbc-instrumentation:2.0:instrument
- Appliquer et voilà.
En quoi Gradle souffre du problème de l'arrêt des machines de Turing mais pas Maven.
Il suffit d'ajouter le paramètre -Dmaven.repo.local à la ligne de commande :
mvn -Dmaven.repo.local=/path/to/repository
Introduction
Comme vous le savez sûrement, il existe une légende sur internet congrue à l'arrivée de Maven 3 : il est possible d'écrire des pom en Yaml. Eh bien sachez que la chose n'est en rien une légende.
En effet, les versions Maven 3.x et supérieures recherchent - avant de lire le pom.xml - un fichier spécifique dans ./mvn/extensions.xml. Ce fichier va charger des extensions à Maven lui permettant de faire plus de choses.
L'idée est donc de demander à Maven de charger l'extension polyglot-yaml qui va ajouter à Maven la capacité d'interpréter du Yaml.
Mise en oeuvre
- À la racine de votre projet créez le répertoire ./mvn/
- Créez dans ce répertoire le fichier extensions.xml dont le contenu est le suivant :
<?xml version="1.0" encoding="UTF-8"?> <extensions> <extension> <groupId>io.takari.polyglot</groupId> <artifactId>polyglot-yaml</artifactId> <version>0.2.1</version> </extension> </extensions>
- Créez un fichier pom.yml à la racine de votre projet
- A titre d'exemple, voici un modèle de pom parent en Yaml :
modelEncoding: 'UTF-8'
modelVersion: '4.0.0'
groupId: 'com.enterprise.fivestars.fs'
artifactId: 'fs-project'
version: '1.0.0-SNAPSHOT'
packaging: 'pom'
name: '. ${project.artifactId} [${project.version}]'
properties:
## Project encoding
project.encoding: 'UTF-8'
project.build.sourceEncoding: '${project.encoding}'
project.reporting.outputEncoding: '${project.encoding}'
## Maven compiler
maven.compiler.source: '1.8'
maven.compiler.target: '${maven.compiler.source}'
## Kotlin compiler
kotlin.compiler.jvmTarget: '${maven.compiler.source}'
kotlin.source.directory: '${project.basedir}/src/main/kt'
kotlin.test.directory: '${project.basedir}/src/test/kt'
kotlin.version: '1.1.51'
## Loggers
logback.version: '1.1.7'
slf4j.version: '1.7.22'
modules:
- fs-domain
- fs-main
- fs-persistence
dependencyManagement:
dependencies:
## Project dependencies
- { groupId: '${project.groupId}' , artifactId: 'fs-project' , version: '${project.version}' }
- { groupId: '${project.groupId}' , artifactId: 'fs-domain' , version: '${project.version}' }
- { groupId: '${project.groupId}' , artifactId: 'fs-persistence' , version: '${project.version}' }
## Database - Driver & embedded DB
- { groupId: 'com.h2database' , artifactId: 'h2' , version: '1.4.195' }
## Database - Database migration
- { groupId: 'org.flywaydb' , artifactId: 'flyway-core' , version: '4.2.0' }
## Database - Connection Pool
- { groupId: 'com.zaxxer' , artifactId: 'HikariCP' , version: '2.7.2' }
## Database - Persistence framework
- { groupId: 'org.javalite' , artifactId: 'activejdbc' , version: '1.4.13.j7' }
## Dependencies Injection
- { groupId: 'org.codejargon.feather' , artifactId: 'feather' , version: '1.0' }
## Kotlin - JVM & Collection compliance
- { groupId: 'org.jetbrains.kotlin' , artifactId: 'kotlin-stdlib' , version: '${kotlin.version}' }
- { groupId: 'org.jetbrains.kotlin' , artifactId: 'kotlin-stdlib-jre8' , version: '${kotlin.version}' }
## Logger - Logging framework facad
- { groupId: 'org.slf4j' , artifactId: 'slf4j-api' , version: '${slf4j.version}' }
## Logger - Logging framework
- { groupId: 'ch.qos.logback' , artifactId: 'logback-classic' , version: '${logback.version}' }
## Testing dependencies
- { groupId: 'org.assertj' , artifactId: 'assertj-core' , version: '3.8.0' }
- { groupId: 'org.jetbrains.kotlin' , artifactId: 'kotlin-test' , version: '${kotlin.version}' }
- { groupId: 'org.junit.platform' , artifactId: 'junit-platform-runner' , version: '1.0.1' }
- { groupId: 'org.mockito' , artifactId: 'mockito-core' , version: '2.12.0' }
build:
pluginManagement:
plugins:
## Compiler - Java (Prevent its execution because of Kotlin)
- artifactId: 'maven-compiler-plugin'
groupId: 'org.apache.maven.plugins'
version: '3.6.2'
configuration:
compilerArgs: {arg: '-Werror'}
encoding: '${project.build.sourceEncoding}'
fork: true
debug: false
optimize: true
showDeprecation: true
showWarnings: true
source: '${maven.compiler.source}'
target: '${maven.compiler.target}'
executions:
- goals:
id: 'default-compile'
phase: 'none'
- goals:
id: 'default-testCompile'
phase: 'none'
- goals: ['compile']
id: 'java-compile'
phase: 'compile'
- goals: ['testCompile']
id: 'java-test-compile'
phase: 'compile'
## Compiler - Kotlin
- artifactId: 'kotlin-maven-plugin'
groupId: 'org.jetbrains.kotlin'
version: '${kotlin.version}'
configuration:
nowarn: false
jvmTarget: '${kotlin.compiler.jvmTarget}'
executions:
- goals: ['compile']
id: 'compile'
phase: 'compile'
configuration:
sourceDirs: [
'${kotlin.source.directory}'
]
- goals: ['test-compile']
id: 'test-compile'
phase: 'test-compile'
configuration:
sourceDirs: [
'${kotlin.test.directory}'
]
## ActiveJDBC - Enrich entities bytecode
- artifactId: 'activejdbc-instrumentation'
groupId: 'org.javalite'
version: '1.4.13.j7'
executions:
- goals: ['instrument']
id: 'enrich-entities'
phase: 'process-classes'
## Quality - JaCoCo (Code coverage)
- artifactId: 'jacoco-maven-plugin'
groupId: 'org.jacoco'
version: '0.7.9'
executions:
- goals:
id: 'prepare-agent'
inherited: true
- goals:
id: 'report'
inherited: true
phase: 'prepare-package'
Et la même chose avec un pom enfant :
modelEncoding: 'UTF-8'
modelVersion: '4.0.0'
parent:
groupId: 'com.enterprise.fivestars.fs'
artifactId: 'fs-project'
version: '1.0.0-SNAPSHOT'
relativePath: '../pom.yml'
artifactId: 'fs-persistence'
packaging: 'jar'
name: '${project.artifactId}'
dependencies:
## Kotlin - JVM & Collection compliance
- { groupId: 'org.jetbrains.kotlin' , artifactId: 'kotlin-stdlib' , scope: 'compile' }
- { groupId: 'org.jetbrains.kotlin' , artifactId: 'kotlin-stdlib-jre8' , scope: 'compile' }
## Database - Database migration
- { groupId: 'org.flywaydb' , artifactId: 'flyway-core' , scope: 'compile' }
## Database - Driver & embedded DB
- { groupId: 'com.h2database' , artifactId: 'h2' , scope: 'compile' }
## Database - Connection Pool
- { groupId: 'com.zaxxer' , artifactId: 'HikariCP' , scope: 'compile' }
## Logger - Logging framework facade
- { groupId: 'org.slf4j' , artifactId: 'slf4j-api' , scope: 'compile' }
## Logger - Logging framework
- { groupId: 'ch.qos.logback' , artifactId: 'logback-classic' , scope: 'compile' }
## Testing dependencies
- { groupId: 'org.assertj' , artifactId: 'assertj-core' , scope: 'test' }
- { groupId: 'org.jetbrains.kotlin' , artifactId: 'kotlin-test' , scope: 'test' }
- { groupId: 'org.junit.platform' , artifactId: 'junit-platform-runner' , scope: 'test' }
- { groupId: 'org.mockito' , artifactId: 'mockito-core' , scope: 'test' }
build:
plugins:
- { groupId: 'org.jetbrains.kotlin' , artifactId: 'kotlin-maven-plugin' }
- { groupId: 'org.apache.maven.plugins' , artifactId: 'maven-compiler-plugin' }
- { groupId: 'org.jacoco' , artifactId: 'jacoco-maven-plugin' }
Et en prime, vous savez à présent compiler du Kotlin avec Maven.
L'acte II explique comment passer les problèmes de path dans les chemins hard-codé dans les jar.
Notifier votre plateforme d'intégration continue des changements effectués dans votre application.