Compatibility issues with Java class

Source: Internet
Author: User

Not long ago in the work, encountered several compile class caused by the nosuchmethoderror, after analysis and test verification, but also to figure out the middle of the ins and outs, now some of the concluding things (with some process analysis) to share.

When using the Javac-source 1.6-target 1.6来 to compile the lower version (1.6) class, remember to use the-bootclasspath parameter to specify the 1.6 version of the class library (typically Rt.jar), without specifying, a warning is generated:
Warning: [options] does not set the bootstrap classpath with-source 1.6

Warning: [options] does not set the bootstrap classpath with-source 1.6

or English version

class path not set in conjunction With-source 1.6

If I ignore this warning (when I search the above Chinese warning online, there is no information about the need to pay attention, and how to resolve), the compiled class may not be able to run in the lower version of the JRE, if the source calls some special methods, The Nosuchmethoderror will be thrown at execution time. For example, Concurrenthashmap's Keyset method, in jdk1.6, the method returns a set, in jdk1.8, the method returns the Keysetview, which is a new class in jdk1.8, is a set implementation. When the compiled class is put into jre1.6 to run, the Nosuchmethoderror is thrown because the keyset method that returns the type Keysetview is not found, although the compiled class version is 1.6.

    Based on the above cognition, to discuss the following scenario
    There are now Apia_1.0.jar and Apib_1.0.jar,apib_1.0.jar dependent Apia_1.0.jar, The former is compiled based on the latter, which means there is no compatibility problem between the two versions.
    Then if Apia has been modified to upgrade to Apia_1.1.jar, where the return value of a method of a class is changed from object to string (from the source, this is compatible because string is an object, This should be the Richter replacement, at this time Apib_1.0.jar is incompatible with Apia_1.1.jar, If you upgrade the Apia to 1.1,APIB in a way that returns a value of object in Apia, the Nosuchmethoderror will be thrown because the method is not found (if you disagree with this, look at the following article) because now in Apia, there is only one method that returns a string, and Also, you can't keep the method that returns a value of object, which is conflicting with each other.
    Of course, you can also republish a Apib_1.1.jar, based on the Apia_1.1.jar compiled version. However, this means that APIB relies on a specific version of Apia, which is very detrimental to dependency maintenance, is prone to problems during use, and is only found when the problematic method is called at run time. There is no error during the compilation of the application (Apia and APIB are already compiled jars).

Perhaps you have noticed at this point that the JDK is not forward compatible? Why do I use jdk1.6 compiled by the program can jre1.8 in the normal call Concurrenthashmap.keyset? Does it not also exist in the above mentioned problem? Why doesn't it throw an exception because it can't find the keyset method with the return value set?
Here we need to introduce the bridge method in class, it does not error, because there is indeed a return value of 1.8 in the keyset method, but does not exist in the source file, but exists in the class file, through Javap-v Java.util.concurrent.ConcurrentHashMap decompile 1.8 Concurrenthashmap, you can see a keyset method that returns a value of Java.util.Set:

 Public java.util.Set keySet ();d escriptor: () Ljava/util/set;flags:acc_public, Acc_bridge, Acc_syntheticcode: Stack=1, Locals=1, args_size=10: aload_0//  Method keySet: () ljava/util/concurrent/ Concurrenthashmap$keysetview; 4267:0

The Acc_bridge in the Ps:flag parameter indicates that this is a bridging method

Although the Java syntax layer does not allow two methods with a different return value, there is no such restriction in the class file, and the keyset method that returns a value of Keysetview is called in this bridging method. Another Java.lang.reflect.Method.isBridge () refers to this.

Then why does Concurrenthashmap.keyset have a bridging method? In fact, it is not the JDK to do their own specialization, because KeySet is a rewrite method (interface method also has this effect), overriding the parent class Abstractmap public set<k> KeySet () method, which is roughly understood as, The parent class or interface has declared the method (that is, the return set), that is, if the fruit class or the implementation itself returned to other subtypes, then the compiler will have to do this compatibility work, that is, to create a bridging method. If you change the top-level method directly, the compiler will not be able to do this thing, how does it know who to be compatible with? Similarly, static methods can be problematic.

Finally, summarize:

    • If you want to remain compatible with previous versions, in addition to the interface method or overriding the parent method, do not change the return value type at other times, otherwise it is incompatible. (I think this is especially important when participating in open source projects)
    • When you use a high version of Javac to configure the source, target parameter to compile a lower version of class or to hit a jar package, you must specify the corresponding lower version of the class library with Bootclasspath, or it may produce incompatibilities. This also means: Don't just install a jdk8 and expect to compile a program that will work properly on jre1.6, and you'll need a 1.6 version of the Java class Library to complete the compilation.
    • If there is a habit of replacing individual class files to patch, then you also need to be particularly careful with compatibility issues, the principle is the same.

The incompatibility problem mentioned above will be delayed until the problem method is actually called, so it deserves attention.

RELATED links:

Javac Official Document: http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html

Compatibility issues with Java class

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.