4

I have legacy source which uses new FtpClient(), and found that FtpClient is a abstract class in jre1.7. The code is fine for jre1.6 or before.

I am using maven to build my project now. My JAVA_HOME points to jdk1.7, which cause the compilation of my source failure. But it is fine when my JAVA_HOME point to jdk1.6. However, the jdk versioin in my company is 1.7 default, and would not downgrade to version 1.6.

Question: how to make it work to compile my source without change the JAVA_HOME?

Below the concerned build log:

[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
A_Di-Matteo
  • 26,902
  • 7
  • 94
  • 128
Will
  • 239
  • 2
  • 11

3 Answers3

1

you can try to play with that:

<properties>
    <maven.compiler.source>1.6</maven.compiler.source>
    <maven.compiler.target>1.6</maven.compiler.target>
</properties>
Eugene Lebedev
  • 1,400
  • 1
  • 18
  • 30
0

You can add the maven compiler plugin in the pom.xml file.

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 with different values of source and target here. You should get it.

vijayinani
  • 2,548
  • 2
  • 26
  • 48
0

You are hitting a common misunderstanding of Java cross-compilation with a special case: you want to use sun.* classes, which have no guarantee to be compatible across Java versions. From 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.

In your specific case, setting source/target of the Maven Compiler Plugin would not be enough. And in general is really dangerous. The Java compiler only knows about bytecode, not about Java API (the rt.jar file). So compiling using Java 7 compiler would still use the rt.jar of Java 7, which in your case is going to break code for Java 6 (especially because of the sun.* usage).

Check this SO answer for a more in deep explanation on the matter. Check also comments from Stuart Marks from Oracle, if ever you have doubts about its content.


In your specific case, you hence mandatory need a JDK 6 installed, because you need to point to the JDK 6 rt.jar file for Java 6 API, otherwise your code would never compile correctly. For such, you could use the executable option of the Maven Compiler Plugin, to point at a different installation of JDK to use, in conjunction with the fork option.

However, you would have to do the same for test execution as well and in general for any plugin requiring this switch. Hence, a more reliable approach would be to set the JAVA_HOME variable upfront before every build (to point to JDK 6) or to use Maven toolchain and set a JDK to use across a set of Maven plugins. But, again, you need JDK 6 installed in your system, otherwise it would not work.

You may also consider Maven profiles to isolate the different JDK usage. In such a profile, I would also suggest to add the Animal Sniffer Maven Plugin as described in the aforementioned SO answer.


As general consideration, the points above explain the why and how you could fix it temporarily, but your application and build may easily suffer maintenance headaches. A more structured approach is definitely to fix the usage of sun.* package, which is a really bad practice. But, yet again, even then be aware about cross-compilation, it's a tricky topic which is often underestimated.

Community
  • 1
  • 1
A_Di-Matteo
  • 26,902
  • 7
  • 94
  • 128