我有遗留源使用new FtpClient()
,并发现FtpClient
是jre1.7中的抽象类。该代码适用于jre1.6或之前。
我正在使用maven来构建我的项目。我的JAVA_HOME
指向jdk1.7,导致编译我的源故障。但是当JAVA_HOME
指向jdk1.6时,它很好。但是,我公司的jdk versioin默认为1.7,并且不会降级到1.6版本。
问题:如何在不更改JAVA_HOME
的情况下编译我的来源?
在相关的构建日志下面:
[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 :(得分:1)
你可以尝试使用它:
<properties>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
</properties>
答案 1 :(得分:0)
您可以在pom.xml文件中添加maven编译器插件。
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>
在此处使用不同的源和目标值。你应该得到它。
答案 2 :(得分:0)
您在使用特殊情况时遇到了对Java交叉编译的常见误解:您希望使用sun.*
类,这些类无法保证在Java版本之间兼容。来自official Oracle note
不能保证直接调用
sun.*
包的Java程序可以在所有兼容Java的平台上运行。实际上,即使在同一平台上的未来版本中,也不能保证这样的程序能够正常工作。
在您的特定情况下,设置Maven编译器插件的source
/ target
是不够的。一般来说真的很危险。 Java编译器只知道字节码,而不是Java API(rt.jar
文件)。因此,使用Java 7编译器进行编译仍将使用Java 7的rt.jar
,在您的情况下,它将破坏Java 6的代码(特别是因为sun.*
用法)。
检查this SO answer以获得有关此事的更深入解释。如果您对其内容有疑问,请查看Oracle的Stuart Marks的评论。
在您的特定情况下,因此强制需要安装JDK 6,因为您需要指向Java 6 API的JDK 6 rt.jar
文件,否则您的代码永远不会编译正确。为此,您可以使用Maven编译器插件的executable
选项指向要使用的不同JDK安装,并结合fork
选项。
但是,对于任何需要此切换的插件,您也必须对测试执行执行相同的操作。因此,更可靠的方法是在每次构建之前预先设置JAVA_HOME
变量(指向JDK 6)或使用Maven toolchain并设置JDK以在一组Maven插件中使用。但是,同样,您需要在系统中安装JDK 6,否则它将无法工作。
您也可以考虑Maven profiles来隔离不同的JDK用法。在这样的配置文件中,我还建议添加Animal Sniffer Maven Plugin,如前面提到的SO答案中所述。
作为一般考虑,上述几点解释了为什么以及如何临时修复它,但您的应用程序和构建可能很容易遭受维护问题。更结构化的方法肯定是要修复sun.*
包的使用,即a really bad practice。但是,再一次,即使在那时也要注意交叉编译,这是一个经常被低估的棘手话题。