2016-03-24 1 views
4

J'ai source héritée qui utilise new FtpClient(), et a constaté que FtpClient est une classe abstraite dans jre1.7. Le code est bien pour jre1.6 ou avant. J'utilise maven pour construire mon projet maintenant. Mes JAVA_HOME points à jdk1.7, ce qui provoque la compilation de mon échec de la source. Mais c'est bien quand mon JAVA_HOME point à jdk1.6. Cependant, le jdk versioin dans ma société est 1.7 par défaut, et ne reviendrait pas à la version 1.6.Maven construire comment utiliser rt.jar qui dans la version java 1.6 ou avant

Question: comment le faire fonctionner pour compiler ma source sans changer le JAVA_HOME?

Ci-dessous le journal de construction concernée:

[INFO] Compiling 601 source files to C:\MyData\Project\A-Trunk\CCA\Online\branches\CCA_TabletAccess_Maven\Common_Source\target\classes 
[INFO] ------------------------------------------------------------------------ 
[ERROR] BUILD FAILURE 
[INFO] ------------------------------------------------------------------------ 
[INFO] Compilation failure 

C:\MyData\Project\A-Trunk\CCA\Online\branches\CCA_TabletAccess_Maven\Common_Source\src\com\hhbb\cca\services\ens\util\FTPCommon.java:[44,9] error: FtpClient is abstract; cannot be instantiated 

C:\MyData\Project\A-Trunk\CCA\Online\branches\CCA_TabletAccess_Maven\Common_Source\src\com\hhbb\cca\services\ens\util\FTPCommon.java:[45,6] error: cannot find symbol 

could not parse error message: symbol: method openServer(String) 
    location: variable aftp of type FtpClient 
C:\MyData\Project\A-Trunk\CCA\Online\branches\CCA_TabletAccess_Maven\Common_Source\src\com\hhbb\cca\services\ens\util\FTPCommon.java:46: error: no suitable method found for login(String,String) 
       aftp.login(user,psw); 
        ^

could not parse error message:  method FtpClient.login(String,char[],String) is not applicable 
     (actual and formal argument lists differ in length) 
    method FtpClient.login(String,char[]) is not applicable 
     (actual argument String cannot be converted to char[] by method invocation conversion) 
C:\MyData\Project\A-Trunk\CCA\Online\branches\CCA_TabletAccess_Maven\Common_Source\src\com\hhbb\cca\services\ens\util\FTPCommon.java:47: error: cannot find symbol 
       aftp.ascii(); 
        ^

could not parse error message: symbol: method ascii() 
    location: variable aftp of type FtpClient 
C:\MyData\Project\A-Trunk\CCA\Online\branches\CCA_TabletAccess_Maven\Common_Source\src\com\hhbb\cca\services\ens\util\FTPCommon.java:53: error: FtpClient is abstract; cannot be instantiated 
       aftp = new FtpClient(); 
        ^

C:\MyData\Project\A-Trunk\CCA\Online\branches\CCA_TabletAccess_Maven\Common_Source\src\com\hhbb\cca\services\ens\util\FTPCommon.java:[54,6] error: cannot find symbol 

could not parse error message: symbol: method openServer(String,int) 
    location: variable aftp of type FtpClient 
C:\MyData\Project\A-Trunk\CCA\Online\branches\CCA_TabletAccess_Maven\Common_Source\src\com\hhbb\cca\services\ens\util\FTPCommon.java:55: error: no suitable method found for login(String,String) 
       aftp.login(user,psw); 
        ^

could not parse error message:  method FtpClient.login(String,char[],String) is not applicable 
     (actual and formal argument lists differ in length) 
    method FtpClient.login(String,char[]) is not applicable 
     (actual argument String cannot be converted to char[] by method invocation conversion) 
C:\MyData\Project\A-Trunk\CCA\Online\branches\CCA_TabletAccess_Maven\Common_Source\src\com\hhbb\cca\services\ens\util\FTPCommon.java:56: error: cannot find symbol 
       aftp.binary(); 
        ^

could not parse error message: symbol: method binary() 
    location: variable aftp of type FtpClient 
C:\MyData\Project\A-Trunk\CCA\Online\branches\CCA_TabletAccess_Maven\Common_Source\src\com\hhbb\cca\services\ens\util\FTPCommon.java:62: error: cannot find symbol 
        aftp.closeServer(); 
        ^

could not parse error message: symbol: method closeServer() 
    location: variable aftp of type FtpClient 
C:\MyData\Project\A-Trunk\CCA\Online\branches\CCA_TabletAccess_Maven\Common_Source\src\com\hhbb\cca\services\ens\util\FTPCommon.java:127: error: cannot find symbol 
         aftp.cd(RWFileDir); 
          ^

could not parse error message: symbol: method cd(String) 
    location: variable aftp of type FtpClient 
C:\MyData\Project\A-Trunk\CCA\Online\branches\CCA_TabletAccess_Maven\Common_Source\src\com\hhbb\cca\services\ens\util\FTPCommon.java:128: error: cannot find symbol 
         TelnetOutputStream outs = aftp.put(filename); 
                ^


[INFO] ------------------------------------------------------------------------ 
[INFO] For more information, run Maven with the -e switch 
[INFO] ------------------------------------------------------------------------ 
[INFO] Total time: 8 seconds 
[INFO] Finished at: Thu Mar 24 14:12:52 CST 2016 
+0

'' 'erreur: FtpClient est abstrait; ne peut pas être instancié''' erreur avec ce code, ce n'est pas la configuration maven ou le problème de version de langage Java –

+3

Fixer le code ou utiliser Java 1.6. N'aurait jamais dû utiliser une classe 'sun. *' En premier lieu. – EJP

+0

@Evgeny Lebedev, Mais il n'y a pas d'erreur quand je compile avec jdk1.6. – Will

Répondre

0

Vous rencontrez un malentendu commun à propos de la compilation croisée Java avec un cas particulier: vous voulez utiliser les classes sun.*, qui n'ont aucune garantie d'être compatibles avec les versions Java. De official Oracle note

A Java program that directly calls into sun.* packages is not guaranteed to work on all Java-compatible platforms. In fact, such a program is not guaranteed to work even in future versions on the same platform.

Dans votre cas, la mise en source/target du plugin Maven Compiler ne serait pas suffisant. Et en général, c'est vraiment dangereux. Le compilateur Java ne connaît que le bytecode, pas l'API Java (le fichier rt.jar). Donc, la compilation en utilisant le compilateur Java 7 utiliserait toujours le rt.jar de Java 7, ce qui dans votre cas va casser le code pour Java 6 (surtout à cause de l'utilisation de sun.*).

Vérifiez this SO answer pour une explication plus approfondie à ce sujet. Vérifiez également les commentaires de Stuart Marks d'Oracle, si jamais vous avez des doutes sur son contenu.


Dans votre cas, vous donc obligatoire ont besoin d'un JDK 6 installé, parce que vous devez pointer vers le JDK 6 fichier rt.jar pour API Java 6, sinon votre code ne serait jamais compiler correctement. Pour cela, vous pouvez utiliser l'option executable du plugin Maven Compiler, pour pointer vers une autre installation de JDK à utiliser, en conjonction avec l'option fork.

Cependant, vous devrez également faire la même chose pour l'exécution du test et en général pour tout plugin nécessitant ce commutateur. Par conséquent, une approche plus fiable consisterait à définir la variable JAVA_HOME à l'avance avant chaque build (pour pointer sur JDK 6) ou à utiliser Maven toolchain et à définir un JDK à utiliser dans un ensemble de plugins Maven. Mais, encore une fois, vous avez besoin de JDK 6 installé dans votre système, sinon cela ne fonctionnerait pas.

Vous pouvez également considérer Maven profiles pour isoler les différentes utilisations de JDK.Dans un tel profil, je suggère également d'ajouter le Animal Sniffer Maven Plugin comme décrit dans la réponse SO susmentionnée.


En contrepartie générale, les points ci-dessus expliquent pourquoi et comment vous pouvez le fixer temporairement, mais votre application et de construire peuvent facilement souffrir des maux de tête d'entretien. Une approche plus structurée est certainement de fixer l'utilisation du paquet sun.*, qui est a really bad practice. Mais, encore une fois, même alors être au courant de la compilation croisée, c'est un sujet délicat qui est souvent sous-estimé.

1

vous pouvez essayer de jouer avec que:

<properties> 
    <maven.compiler.source>1.6</maven.compiler.source> 
    <maven.compiler.target>1.6</maven.compiler.target> 
</properties> 
+0

J'ai essayé, pas travaillé. – Will

+0

fournissez le journal avec votre erreur (s) –

+0

@Avez-vous jdk 1.6 dans votre système? – Bhavesh

0

Vous pouvez ajouter le plugin compilateur Maven dans le fichier pom.xml.

https://maven.apache.org/plugins/maven-compiler-plugin/

<project> 
    [...] 
    <build> 
    [...] 
    <plugins> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-compiler-plugin</artifactId> 
     <version>3.5.1</version> 
     <configuration> 
      <source>1.7</source> 
      <target>1.6</target> 
     </configuration> 
     </plugin> 
    </plugins> 
    [...] 
    </build> 
    [...] 
</project> 

Jouer avec des valeurs différentes de source et cible ici. Tu devrais l'avoir.

+0

ne fonctionne pas ... javac: la version source 1.7 requiert la version cible 1.7 – Will