Eclipse compiler & m2e

Récemment, j’ai appris que l’IDE eclipse n’utilisait pas le compilateur de la JDK (javac) pour transformer les fichiers Java en Class. C’est d’ailleurs pour cela qu’il est possible de développer et compiler du code sans avoir installer la JDK sur son ordinateur.
Par défaut, Maven utilise javac pour compiler les sources Java. Or, dans certains cas, le compilateur eclipse (JDT) accepte de compiler des classes là où javac sort en erreur. Par exemple, voici un code qui compile avec le JDT et pas avec javac :
package com.test; public class GenericMethod { private Object value; @SuppressWarnings("unchecked") public <X> X getValue() { return (X) value; // le cast n'est obligatoire que pour que javac compile // avec le compilateur eclipse, il n'est pas nécessaire } public void setValue(Object value) { this.value = value; } }
Voici la classe pour appeler la méthode :
package com.test; public class GenericMethodTest { public static void main(String[] args) { GenericMethod method = new GenericMethod(); method.setValue(3); int[] array = new int[] {1, 2}; array[0] = method.getValue(); System.out.println(array[0]); } }
Avec javac, la ligne 11 de la classe GenericMethodTest provoque l’erreur suivante :
type parameters of <X>X cannot be determined;no unique maximal instance exists for type variable X with upper bounds int,java.lang.Object
Il peut donc être essentiel d’utiliser dans le processus de build un autre compilateur que javac. Il est possible de configurer le plugin maven-compiler-plugin afin d’utiliser un compilateur alternatif. Par exemple, pour utiliser le compilateur eclipse c’est très simple :
<project> [...] <build> [...] <plugins> [...] <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <compilerId>eclipse</compilerId> </configuration> <dependencies> <dependency> <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-compiler-eclipse</artifactId> </dependency> </dependencies> </plugin> [...] </project>
Le build maven fonctionne parfaitement, en revanche l’utilisation du compilateur alternatif a des effets secondaires lorsqu’il est utilisé par le plugin eclipse m2e. La modification des fichiers .classpath et .project ne fonctionne plus correctement et cela provoque :
- La nature java du projet n’est pas détectée,
- Les dépendances ne sont plus récupérées,
- Les répertoires sources (src/main/java, src/main/resources, etc.) ne sont plus référencés
Le problème du nouveau plugin m2e c’est qu’il ne reconnaît les projets maven en tant que projets java que lorsque le compilateur utilisé est javac. Pour configurer un projet eclipse utilisant le compilateur eclipse, il est donc nécessaire d’indiquer à m2e qu’il s’agit bien d’un projet Java :
<pluginManagement> <plugins> <plugin> <groupId>org.eclipse.m2e</groupId> <artifactId>lifecycle-mapping</artifactId> <version>1.0.0</version> <configuration> <lifecycleMappingMetadata> <pluginExecutions> <pluginExecution> <pluginExecutionFilter> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <versionRange>[2.0,)</versionRange> <goals> <goal>compile</goal> <goal>testCompile</goal> </goals> <parameters> <compilerId>eclipse</compilerId> </parameters> </pluginExecutionFilter> <action> <configurator> <id>org.eclipse.m2e.jdt.javaConfigurator</id> </configurator> </action> </pluginExecution> </pluginExecutions> </lifecycleMappingMetadata> </configuration> </plugin> </plugins> </pluginManagement>
Dès que m2e reconnaît le projet en tant que projet java, la fonction Update project configuration, configurera les répertoires sources et mettra à jour le classpath du projet.