JDK-8151366 : Using JDK8 to compile code for JDK7 (-source 1.7 -target 1.7) does not work if ConcurrentHashMap is used
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8u74
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2016-03-03
  • Updated: 2016-07-13
  • Resolved: 2016-03-07
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

EXTRA RELEVANT SYSTEM CONFIGURATION :
javac 1.8.0_74

A DESCRIPTION OF THE PROBLEM :
Compiling Java 7 that uses java.util.concurrent.ConcurrentHashMap with JDK8 produces code that is not executable on JDK7. That is attempt to run such code fails with the exception:

Exception in thread "main" java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySet()Ljava/util/concurrent/ConcurrentHashMap$KeySetView;
        at CHMCompilationTest.main(CHMCompilationTest.java:8)


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Use JDK8 to compile attached CHMCompilationTest file using the following command:
javac -source 1.7 -target 1.7 CHMCompilationTest.java
NB: This will actually produce a warning:
warning: [options] bootstrap class path not set in conjunction with -source 1.7
1 warning
2. Run compiled class using JDK7. I've used the following version:
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Program runs without error and prints:
[]
ACTUAL -
Exception in thread "main" java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySet()Ljava/util/concurrent/ConcurrentHashMap$KeySetView;
        at CHMCompilationTest.main(CHMCompilationTest.java:8)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class CHMCompilationTest {

  public static void main(String[] args) {
    ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
    Set<Integer> keys = map.keySet();
    System.out.println(keys);
  }

}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Use JDK7 to compile Java 7 code.


Comments
jsr166 maintainers are very sorry for the trouble that ConcurrentHashMap$KeySetView has caused. Here's the workaround: import java.util.concurrent.ConcurrentHashMap; import java.util.Map; public class CHM_keySet { public static void main(String[] args) throws Throwable { ConcurrentHashMap<Long,Long> m = new ConcurrentHashMap<>(); // Workaround ... System.out.println(((Map) m).keySet()); // ... for NoSuchMethodError from: System.out.println(m.keySet()); } }
13-07-2016

FYI, this is precisely the use case of for the -release flag added to javac in JDK 9 under JEP 247: Compile for Older Platform Versions (JDK-8058150).
07-03-2016

This is not an issue. The problem is caused by a difference in the ConcurrentHashMap API between JDK 7 and JDK 8: JDK 7: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html#keySet%28%29 JDK 8: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html#keySet-- As you can see, the JDK 7 signature returns a Set, while JDK 8 signature returns a KeySetView, which is a new class in JDK 8. So, this problem is unavoidable if a source program is compiled using -source 7/target 7 AND JDK 8 classes are on the bootclasspath. The solution is to use JDK 7 runtime in the bootclasspath: /opt/JDK/8/re/b40/bin/javac -source 7 -target 7 -Xlint CHMCompilationTest.java warning: [options] bootstrap class path not set in conjunction with -source 1.7 <-------------------------------------------------- 1 warning /usr/lib/jvm/java-1.7.0-openjdk-amd64/bin/java CHMCompilationTest Exception in thread "main" java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySet()Ljava/util/concurrent/ConcurrentHashMap$KeySetView; at CHMCompilationTest.main(CHMCompilationTest.java:8) To address this: /opt/JDK/8/re/b40/bin/javac -Xbootclasspath/p:/usr/lib/jvm/java-1.7.0-openjdk-amd64/jre/lib/rt.jar -Xlint -source 7 -target 7 CHMCompilationTest.java [no warnings!] maurizio@mc:~/Desktop$ /usr/lib/jvm/java-1.7.0-openjdk-amd64/bin/java CHMCompilationTest []
07-03-2016

Test Result: ########## OS: Windows 7 64-bit JDK: javac 7uXX java 7uXX : Pass javac 7uXX java 8uXX : Pass javac 7uXX java 9ea : Pass javac 8uXX java 7uXX : Fail javac 9ea java 7uXX : Fail javac 9ea java 8uXX : Pass ################################################################################################################################ javac 7uXX and java 7uXX ###################### c:\ji\tools>javac -version javac 1.7.0_51 c:\ji\tools>java CHMCompilationTest Exception in thread "main" java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySe at CHMCompilationTest.main(CHMCompilationTest.java:8) c:\ji\tools>javac -source 1.7 -target 1.7 CHMCompilationTest.java c:\ji\tools>javac -version javac 1.7.0_51 c:\ji\tools>java CHMCompilationTest [] ################################################################################################################################ javac 7uXX java 8uXX ################### c:\ji\tools>javac -version javac 1.7.0_51 c:\ji\tools>javac -source 1.7 -target 1.7 CHMCompilationTest.java c:\ji\tools>javac -version javac 1.8.0_74 c:\ji\tools>java CHMCompilationTest [] ################################################################################################################################ javac 9ea and java 8uXX #################### c:\ji\tools>javac -version javac 9-ea c:\ji\tools>javac -source 1.8 -target 1.8 CHMCompilationTest.java warning: [options] bootstrap class path not set in conjunction with -source 1.8 1 warning c:\ji\tools>javac -version javac 1.8.0_74 c:\ji\tools>java CHMCompilationTest [] ################################################################################################################################ javac 9ea and java 7uXX ##################### c:\ji\tools>javac -version javac 9-ea c:\ji\tools>javac -source 1.7 -target 1.7 CHMCompilationTest.java warning: [options] bootstrap class path not set in conjunction with -source 1.7 1 warning c:\ji\tools>javac -version javac 1.7.0_51 c:\ji\tools>java CHMCompilationTest Exception in thread "main" java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySet()Ljava/util/concurrent/ConcurrentHashMap$KeySetVi at CHMCompilationTest.main(CHMCompilationTest.java:8) c:\ji\tools> ################################################################################################################################
07-03-2016