2016-03-24 6 views
4

У меня есть исходный источник, который использует new FtpClient(), и нашел, что FtpClient является абстрактным классом в jre1.7. Код подходит для jre1.6 или ранее.Maven построить, как использовать rt.jar, который в версии java версии 1.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

Ошибка '' ': FtpClient является абстрактным; не может быть вызвана '' 'ошибкой с этим кодом, это не проблема конфигурации maven или проблемы с языковой версией –

+3

Исправить код или использовать Java 1.6. Никогда не следовало использовать класс «sun. *». – EJP

+0

@Evgeny Lebedev, но при компиляции с jdk1.6 ошибки не возникает. – Will

ответ

0

Вы сталкиваетесь с распространенным непониманием кросс-компиляции Java со специальным случаем: вы хотите использовать классы sun.*, которые не имеют гарантии совместимости в Java-версиях. От 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.

В вашем конкретном случае, если для параметра source/target в Maven компилятора плагин не будет достаточно. И вообще действительно опасно. Компилятор Java знает только о байт-коде, а не о Java API (файл rt.jar). Поэтому компиляция с использованием компилятора Java 7 по-прежнему будет использовать rt.jar Java 7, который в вашем случае собирается сломать код для Java 6 (особенно из-за использования sun.*).

Проверить this SO answer для более глубокого объяснения по этому вопросу. Также проверяйте комментарии Stuart Marks от Oracle, если у вас есть сомнения относительно его содержимого.


В вашем конкретном случае, вы, следовательно обязательным нужен JDK 6 установлен, потому что вам нужно, чтобы указать на rt.jar файл JDK 6 для Java 6 API, в противном случае ваш код никогда не будет компилировать правильно. Для этого вы можете использовать опцию executable плагина Maven Compiler, чтобы указать на другую установку 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. Но, опять же, даже тогда осознавать кросс-компиляцию, это сложная тема, которая часто недооценивается.

1

вы можете попробовать играть с этим:

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

Я пробовал, не работал. – Will

+0

предоставить журнал с ошибкой (-ами) –

+0

@ У вас есть jdk 1.6 в вашей системе? – Bhavesh

0

Вы можете добавить плагин Maven компилятора в файле 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> 

Play с различными значениями исходного и целевого здесь. Вы должны это получить.

+0

не работает ... javac: исходный релиз 1.7 требует целевого релиза 1.7 – Will