web-dev-qa-db-fra.com

Maven: javac: la version source 1.6 nécessite la version cible 1.6

REMARQUE: cela semble être une limite dans le programme "javac".

J'ai Java 6 code qui doit être construit pour une JVM Java 5. Mon travail précédent avec la cible javac ant (avec le compilateur JDK et avec ecj) m'a amené à croire qu'il s'agirait simplement de définir la source et la cible de javac. D'où ce fragment pom.xml:

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <source>1.6</source>
        <target>1.5</target>
    </configuration>
</plugin>

qui fonctionne comme prévu depuis Eclipse 3.7 avec le support Maven. Malheureusement, exécuter Maven directement à partir de la ligne de commande me donne

javac: source release 1.6 requires target release 1.6

qui est le même que celui généré par javac -source 1.6 -target 1.5. Pour clarifier, il s'agit de l'OpenJDK 6 officiel pour Ubuntu

x@JENKINS:~$ javac -version
javac 1.6.0_20
x@JENKINS:~$ javac -source 1.6 -target 1.5
javac: source release 1.6 requires target release 1.6
x@JENKINS:~$

L'Oracle officiel Java 7 JDK pour Windows affiche le même comportement.

Remarque: je ne veux pas construire avec Java 5 bibliothèques ou quoi que ce soit. Juste que le javac actif génère Java 5 compatible bytecode) .

Comment obtenir ce que je veux tout en étant compatible avec le plugin Eclipse Maven?

(EDIT: en plus de @Override, je veux également compiler avec les bibliothèques JAX-WS dans Java 6 lorsqu'il est utilisé, mais toujours généré Java 5 octets) code - Je peux ensuite ajouter délibérément les bibliothèques JAX-WS dans le conteneur Web lors du déploiement dans une installation Java 5)


EDIT: Il s'avère que maven-compiler-plugin peut être invité à utiliser un autre compilateur, et le compilateur Eclipse peut le faire:

        <plugin>
            <!-- Using the Eclipse compiler allows for different source and target, 
                which is a good thing (outweighing that this is a rarely used combination, 
                and most people use javac) This should also allow us to run maven builds 
                on a JRE and not a JDK. -->

            <!-- Note that initial experiments with an earlier version of maven-compiler-plugin 
                showed that the Eclipse compiler bundled with that gave incorrect lines in 
                the debug information. By using a newer version of the plexus-compiler-Eclipse 
                plugin this is hopefully less of an issue. If not we must also bundle a newer 
                version of the Eclipse compiler itself. -->

            <groupId>org.Apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.0</version>
            <configuration>
                <source>1.6</source>
                <target>1.5</target>
                <debug>true</debug>
                <optimize>false</optimize>
                <fork>true</fork>
                <compilerId>Eclipse</compilerId>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.codehaus.plexus</groupId>
                    <artifactId>plexus-compiler-Eclipse</artifactId>
                    <version>2.1</version>
                </dependency>
            </dependencies>
        </plugin>

qui compile la classe en Java 1,5 bytecode sans plaintes. Ceci est également pris en charge "prêt à l'emploi" pour m2e pour Eclipse Java EE 4.2.2.

EDIT: J'ai trouvé que de toutes choses, l'outil javadoc n'aime pas la sortie du compilateur Eclipse.

EDIT 2015-06-28: J'ai fait un test rapide récemment et le dernier ecj (correspondant à Eclipse 4.4) a bien fonctionné avec javadoc.

26

La limitation est en javac. La solution consiste à dire à maven d'utiliser un autre compilateur. Voir la question pour plus de détails.

13

Il semble que si vous voulez faire une compilation croisée, vous devez fournir quelques arguments supplémentaires - bootclasspath et - extdirs , même si je pense que vous n'avez besoin que du premier. Pour utiliser Javac et un exemple, vous pouvez trouver ici avec une explication des options supplémentaires ici (section Options de compilation croisée).

Vous devrez ensuite configurer ces options pour votre plug-in-compilateur maven. D'après ce que je comprends, vous devez définir le plugin sur fork pour qu'il utilise les arguments du compilateur plutôt que le compilateur intégré. Vous pouvez trouver une liste de toutes les options ici

 <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.5</target>
                    <fork>true</fork>
                    <compilerArguments>
                        <bootclasspath>${1.5.0jdk}\lib\rt.jar</bootclasspath>
                   </compilerArguments>
               </configuration>
           </plugin>
        ....
       </plugins>
   </build>
8
Kingamajick

Je pense que vous devez définir -bootclasspath ainsi que javac se compile avec JDK 1.5 bootstrap classes.

Essayer:

javac -source 1.6 -target 1.5 -bootclasspath /path/to/jdk1.5/lib/rt.jar -extdirs "" Foo.Java

MISE À JOUR:

Essayez de supprimer le -source option, mais conservez le -target option.

Je viens de le tester:

# no source, only target => COMPILES to 1.5
$ javac -target 1.5 Foo.Java
$ javap -v  Foo | grep version
  minor version: 0
  major version: 49

# no source, no target => COMPILES to 1.6
$ javac Foo.Java
$ javap -v  Foo | grep version
  minor version: 0
  major version: 50

# both source and target => ERROR
$ javac -source 1.6 -target 1.5 Foo.Java
javac: source release 1.6 requires target release 1.6

$ javac -version
javac 1.6.0_21
2
dogbane

J'ai eu la même erreur lorsque j'ai mis à jour mon IDE IntelliJ, il a été corrigé avec le remplacement de 1.5 par 1.6 comme ci-dessous.

       <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>
1
Krishna Sapkota

Quelles fonctionnalités du langage Java 6 utilisez-vous qui ne sont pas présentes dans Java 5? Pour autant que je sache, la seule "fonctionnalité" qui a été ajoutée à la langue est l'utilisation du @Override annotation dans interfaces. Sinon, Java 6 et Java 5 sont compatibles avec la source. Que se passe-t-il lorsque vous utilisez:

<source>1.5</source>
<target>1.5</target>

dans votre fichier de construction Maven?

1
Jonathan