In-depth understanding of Java version conflicts

Source: Internet
Author: User
Tags unsupported

I. Problems to be Solved

When we were an early adopter of jdk1.5, I believe many people have encountered the unsupported Major. Minor version 49.0 error, and they will be at a loss at that time. At the beginning, there were not many Chinese documents related to this issue on the Internet. Now, I am ready to find out how to solve this problem. Most of them will tell you to use JDK 1.4 for re-compilation. So why is that major. Minor? This is what we will talk about in this article to make the crowdsourced Security Testing come true.

I think I am lucky because I have studied the second edition of deep Java Virtual Machine before encountering that error. The original English book is "inside the Java Virtual Machine" (second edition ), major. where is minor hidden, but I have no personal experience. Wait for it to be connected to unsupported major. minor version 49.0 will actually interview, which is a fact I have verified.

First, we need to establish the direct feeling of unsupported Major. Minor version 49.0: The classes compiled by jdk1.5 cannot run under JVM 1.4, and must be compiled into the classes that can run under JVM 1.4. (Of course, if you are still using JVM 1.3 or JVM 1.2, You need to compile it into a class that can be recognized by the target JVM ). This also resolves the problem.

II. Where does major. Minor reside?

What is major. Minor and where is it? First, let's get to know and find Major. Minor.

Write a Java Hello world! Code, and then compiled into helloworld. Java using the JDK 1.5 Compiler

Java code
  1. Package com. unmi;
  2. Public class helloworld
  3. {
  4. Public static void main (string [] ARGs)
  5. {
  6. System. Out. println ("Hello, world! ");
  7. }
  8. }

The following code uses the byte code helloworld. Class compiled by javac-D. helloworld. Java of JDK 1.5 and ultraedit:



 

What is major. minor version, which is equivalent to the Primary and Secondary version of a software. It is only the primary and secondary version of a Java class identified here. At the same time, we can see that minor_version is 0x0000, major_version is 0x0031, and is converted to 0 and 49 in decimal number, that is, Major. minor is 49.0.

3. What is major. Minor and what is it

The 5th-8 bytes of the class file are minor_version and major_version. New features may be added to the Java class file format. Once the class file format changes, the version number also changes. For JVM, the version number determines the specific class file format. Generally, the JVM can read the class file only after the primary version number and a series of minor versions are given. If the version number of the class file exceeds the valid range that JVM can process, JVM will not process the class file.

In Sun's JDK 1.0.2 release, JVM supports the class file format from 45.0 to 45.3. JVM in all JDK 1.1 releases supports the class file format from 45.0 to 45.65535. In Sun SDK 1.2, JVM supports the class file format from version 45.0 to 46.0.

The compiler of version 1.0 or 1.2 can generate a class file with version 45.3. In Sun's 1.2 SDK, The javac compiler generates a class file whose version is 45.3 by default. If the-Target 1.2 flag is specified in the javac command line, the compiler of version 1.2 will generate a class file with version 46.0. The class file generated with the-target 1.0 flag cannot be run on JVM 1.1 or 1.2.

In the second version of JVM implementation, the main version number and minor version number of the class file are modified. For the second version, the main version number of the class file must be the same as that of the main release version of the Java platform (for example, the main version number rose from 45 to 46 on the Java 2 platform ), the minor version number is related to the versions released on a specific main platform. Therefore, although different class file formats can be expressed by different version numbers, different version numbers do not mean different class file formats. The reason for different version numbers may be that the class file is generated by the Java platform of different released versions, and the format of the class file may not change.

The above three paragraphs have been excerpted from "deep into Java virtual machines". A bunch of tricks have taken place. JDK 1.2 started the Java 2 era, but it was still far away from us in that era, many of us jumped directly on JDK 1.4, And I was similar, but the project requirement had to be wronged on JDK 1.3 for a while. However, the general information we can get is that each version of the JDK compiler has a version number in the class file compiled by each version. Different JVMs can accept a range of class version numbers, and errors occur if they exceed the range. However, they are generally backward compatible. Do you know Sun is working on Solaris? For previous versions of 100%
Binary compatibility, which protects customers' investments.

IV. Other methods for determining the Major. Minor version of the class

1) view in eclipse
The new feature added by ECLIPSE 3.3. When a class is not associated with the source code, opening it will display more detailed class information. Of course, it is not at the source code level. It can be seen that 2.0 spring is enabled. classpathxmlapplicationcontext in jar. information displayed by class



 


2) command javap-verbose
For compiled class files, use javap-verbose to display the Major. Minor version of the class. See:



 


3) manifest File
The jar package compiled by class will have file META-INF \ manifest, this file will usually have compiler information, the following list of several packages of META-INF \ manifest file content let's take a look
· Velocity-1.5.jar META-INFO \ manifest
Manifest-version: 1.0
Ant-version: Apache ant 1.7.0
Created-by: Apache ant
Package: org. Apache. Velocity
Build-JDK: 1.4.2 _ 08
Extension-Name: Velocity
We can see that it is packaged with ant, And the JDK used for building is 1.4.2 _ 08. Classes compiled with 1.4 can certainly run in 1.4 JVM. It would be boring to use JDK 1.5 and ant 1.4 for compiling.
· 2. 0 META-INFO \ manifest of spring. Jar
Manifest-version: 1.0
Ant-version: Apache ant 1.6.5
Created-by: 1.5.0 _ 08-b03 (Sun Microsystems Inc .)
Implementation-title: Spring framework
Note that JDK 1.5 is used for compiling. Is it compiled with-target 1.4 or-target 1.3? Indeed, you can view binary files of the class, which is the safest. The spring-2.0.jar can also load the execution in the 1.4 JVM.
· META-INFO \ manifest of jar packages using ant in one project
Manifest-version: 1.0
Ant-version: Apache ant 1.7.0
Created-by: 1.4.2-b28 (Sun Microsystems Inc .)
Build and package with JDK 1.4.

The first and second methods can clearly understand Major. minor version, and the third method should be no problem, but encountered abnormal build is hard to say, such as who put the META-INFO \ manifest package after changing it is unknown. The method of directly viewing binary files of the class is extremely reliable and accurate, that is, I have recognized the tool tampering.

V. compiler comparison and symptoms Section

The default minor. Major version of the class compiled from JDK 1.1 to JDK 1.7 is recommended. (Go to Sun's website again to make up the antiques I have never used)

JDK compiler version Target Parameter Hexadecimal minor. Major Minor. Major in decimal format
Jdk1.1.8 The target parameter cannot be included. 00 03 00 2D 45.3
Jdk1.2.2 No (default value:-target 1.1) 00 03 00 2D 45.3
Jdk1.2.2 -Target 1.2 00 00 00 2e 46.0
Jdk1.3.1 _ 19 No (default value:-target 1.1) 00 03 00 2D 45.3
Jdk1.3.1 _ 19 -Target 1.3 00 00 00 2f 47.0
J2sdk1.4.2 _ 10 No (default value:-Target 1.2) 00 00 00 2e 46.0
J2sdk1.4.2 _ 10 -Target 1.4 00 00 30 48.0
Jdk1.5.0 _ 11 No (default value:-target 1.5) 00 00 00 31 49.0
Jdk1.5.0 _ 11 -Target 1.4-source 1.4 00 00 30 48.0
Jdk1.6.0 _ 01 No (default value:-target 1.6) 00 00 00 32 50.0
Jdk1.6.0 _ 01 -Target 1.5 00 00 00 31 49.0
Jdk1.6.0 _ 01 -Target 1.4-source 1.4 00 00 30 48.0
Jdk1.7.0 No (default value:-target 1.6) 00 00 00 32 50.0
Jdk1.7.0 -Target 1.7 00 00 00 33 51.0
Jdk1.7.0 -Target 1.4-source 1.4 00 00 30 48.0
Apache harmony 5.0m3 No (default value:-Target 1.2) 00 00 00 2e 46.0
Apache harmony 5.0m3 -Target 1.4 00 00 30 48.0


The above comparison shows the JDK compiler in windows. Here we can summarize:

1)-target 1.1 has a version number. Target is 1.2 and later only uses the primary version number. The minor version number is 0.
2) The language differences from 1.1 to 1.4 are relatively small, so the default target versions from 1.2 to 1.4 are not their corresponding versions.
3) the syntax of 1.5 is greatly changed, so the default target is 1.5 by default. Because JDK 1.5 is used to generate code with the target of 1.4,-target 1.4 is not enough, and-source 1.4 must be included at the same time to specify the source code compatibility, this is also true for the code 1.6/1.7 JDK generation target 1.4.
4) The 1.6 compiler seems radical, and the default parameter is-target 1.6. Because there is no difference between the syntax of 1.6 and 1.5, you do not need to follow-source 1.5 when using-target 1.5.
5) Note that the default target for 1.7 compilation is 1.6.
6) the version number of the class file generated by other third-party JDK is the same as that of the Sun version JDK.
7) Most importantly, the JVM of a certain version can accept that the maximum major version number of the class file cannot exceed the version number of the class file compiled by the corresponding JDK with the corresponding target parameter.

The above sentence is a little long. reading it in one breath is not very easy to understand. For example: the master version number of the maximum class file that the JVM of 1.4 can accept cannot exceed the master version number of the class file compiled with the 1.4 JDK-target 1.4 parameter, that is, 48.

Because the default target is 1.5 During JDK 1.5 compilation, and the bytecode Major. Minor version is 49.0, the 1.4 JVM is unacceptable and only throws an error.

So why is there no unsupported major for JDK upgrades from 1.1 to 1.2, from 1.2 to 1.3, or from 1.3 to 1.4. minor version is incorrect because 1.2, 1.3, 1.4, and both maintain good binary compatibility, check that the default target of 1.2/1.3/1.4 is 1.1/1.1/1.2, which means that the class files compiled by 1.4 JDK can be loaded and executed under JVM 1.2 by default, what's more
What about JVM 1.3? (Of course, the new version of the extended API must be removed)

6. Find the solution to the problem

Now, if you encounter this problem, you should know how to solve it. As I have seen some brothers, I will find JDK 1.4 to download and install, then use it to re-compile all the code? In fact, you don't have to worry about it. We certainly remember that javac still has a-target parameter. Right, you can continue to use JDK 1.5. during compilation, the parameter-target 1.4-source 1.4 will be okay, however, you must be familiar with the APIs that JDK 1.5 has added. You cannot obtain method not found from your class file under JVM 1.4. Target JVM is 1.3
-Target 1.3-source 1.3 is used for the compilation options.

If ant is used, its javac task can also select target and Source

<Javac target = "1.4" Source = "1.4 "............................ />

If it is under development, it is certain that currently Java ide has compilation options for projects to set the target code. For example, Java compiler settings in Eclipse project properties,



 

If you set the compilation option, you will see that different compiler compliance levels are selected. The generated class files compatibility and source compatibility are also changing. You can also manually adjust the two items, after manual settings, you don't need to care about the version of the compiler that you use. You just need to ask the compiler to generate the bytecode we want. Then, even if the source code is written in VB, as long as the bytecode that can be compiled into the JVM can be executed, it is not tight. You can also find the corresponding Setting Dialog Box in other ides.

In other cases, you must know the current JVM version and the acceptable major bytecode version number (which can be compared with the previous table ). There are two ways to obtain information about the current JVM version:

First, if you directly use Java commands to execute programs on the console, you can use Java-version to view the current JVM version, and then determine the acceptable class file version.

Second, if it is executed in the container, but it is not clear which JVM will be used, you can add the code system to the Program executed in the container. getproperty ("Java. runtime. version "); or system. getproperty ("Java. class. version ") to obtain the JVM version and the acceptable class version.

Last trick: if you do not want to recompile all the code with the target parameter for the JVM of a lower version; if you still want to use new APIs in the Code; what's more, you have also used new features of JDK 1.5, such as generics, Automatic Disassembly boxes, and enumeration. Then you can use-target 1.4-source 1.4 to compile the code, you have to refresh the code. The last trick is that you don't need to start with the source code, directly convert the byte code that you compiled normally, and continue to enjoy those new features. The new API is: please refer to the previous log article: mongotranslator allows you to run the code written with the jdk1.5 feature in jvm1.4. This is what I use, so there will be no problem in doing a good test.

7. discuss another problem

This is an unsupported Major. Minor version 49.0 error caused by copying tomcat. Scenario: JDK 1.5 is installed locally, and an EXE tomcat installation file is found online to be installed and available. Later, my colleague asked for a tomcat and didn't want to download or install it. So I copied the entire Tomcat directory to him based on my previous experience, the result is that unsupported major appears when the JSP file is browsed. minor version 49.0 is incorrect. It can be confirmed that he installed JDK 1.4, but I still have some questions. I am dumb with confidence in this issue. Inertial thinking is compiled
If an exception occurs when the class file gets a lower version of JVM, it does not need to be executed for Classes compiled by JDK 1.5.

Later, I carefully read the exception information and finally found % atat_home % \ common \ Lib \ tools. jar, because the JSP file needs to be compiled based on it, and this tool is called. A class file in jar, 49.0, soon I realized that this file was copied from the % jdk1.5 % \ lib directory to the Tomcat lib directory when Tomcat was installed on my machine, as a result, 1.4 of JVM is used for compiling JSP on a colleague's machine with 49.0 tools. jar, so no error occurs.
If JDK tools. jar is replaced with tomcat, it will be OK.

8. Summary

In fact, the understanding of major. Minor is as much as we can imagine. It is also a Microsoft program, and a 32-bit application cannot be executed in a 16-bit system.

If we know the target JVM version before release, how can we see major from the Java class file. if the minor version is used, you don't have to wait until the server reports an exception to solve the problem, so you can predict the possible problem.

In other cases, we should solve this problem. The root cause of the problem is that the lower version JVM cannot load the higher version class file. Just find the higher version class file and process it.

Reprinted from: http://sheng.iteye.com/blog/690035

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.