I want to recompile an old jar file (which was compiled in java 1.2). So that there are no errors i need to compile it in Java 1.2 aswell. But havent found a jdk 1.2 which i can install on windows 7 (and 64bit).
Any suggestions?
thanks in advance!
Yes, you can set the version of compiler at compile time. And compile your java code into old versions of java.
From Oracle article : http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/javac.html
Cross-Compilation Example
Here we use javac to compile code that will run on a 1.4 VM.
% javac -target 1.2 -bootclasspath jdk1.2/lib/classes.zip \
-extdirs "" OldCode.java
There are two scenarios, just compiling old code and actually developing for an old JRE.
For just compiling you don't need an old JDK, you can adjust the target language level javac compiles with the -target option (see: https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html) - Although there may be edge cases that may break the compiled code if the compiler decides to select a different overload for a method that does not exist in the old JRE.
For developing old JRE compatible code, you could use above method but you run the risk accidentially using an API that isn't present in the real old JRE. To avoid that problem you need the actual 1.2 API, meaning you need the rt.jar file from a real 1.2 JRE/JDK. This can be added into your project in your IDE (and the current e.g. 1.8 JDK removed). The detailed procedure how to set this up depends on the IDE. Likewise the 1.2 rt.jar can be provided to javac, also using command line switches. Again you need no runnable 1.2 JRE to compile/develop.
Related
I am posting this question as I have limited resources to test or confirm by my own.
Problem statement : I have an old custom Jar working with java 1.6. We don't have source code as well.
To fix one of the issue we updated 2 .class file of this jar using 7-zip.The code change was just to update the existing loggers with more meaningful messages.
These 2 .class file compiled with java 1.7.
Now the questions is whether this jar will work correctly with java 1.6 or will generate java version issue as 2 of the .class files are compiled with java 1.7.
Note - I know it's easy to test this rather then asking here but my test environment is only supporting java 1.8 and it's working perfectly but whether it will run with java 1.6 or not I can't test.
If you compile using: javac Foo.java where that javac is from a JDK1.7 installation, and you then attempt to run the class file that results on a JDK1.6, it will not work.
However, all you need to do is this:
javac -source 1.6 -target 1.6 Foo.java, and then it will, unless you used features from 1.7. If you use language features (I can't think of any, so I doubt it), it won't compile, and thus you know. If you use API, it will compile and you won't know. There is no easy solution to this other than compiling with JDK1.6 (or compiling with javac7 against a bootcp of JDK1.6, but you need to download and install a JDK1.6 to get that; might as well just use javac6 then).
Binary Compatibility
The class file version for Java SE 7 is 51, as per the JVM Specification, because of the invokedynamic byte code introduced by JSR 292. Version 51 class files produced by the Java SE 7 compiler cannot be used in Java SE 6.
Java SE 7 is binary-compatible with Java SE 6 except for the incompatibilities . Except for the noted incompatibilities, class files built with the Java SE 6 compiler will run correctly in Java SE 7.
Friends Words ...
The compiler is not backwards compatible because bytecode generated with Java7 JDK won't run in Java 1.6 jvm (unless compiled with the -target 1.6 flag). But the JVM is backwards compatible, as it can run older bytecodes.
So they chose to consider the compatibility from the point of view of javac (as it is the part specific to the JDK), meaning that the bytecode generated can be run in future releases of the jvm (that is more related to the JRE, but also bundled in the JDK).
In brief, we can say:
JDK's are (usually) forward compatible.
JRE's are (usually) backward compatible.
Java Says
Cross-Compilation Options
By default, classes are compiled against the bootstrap and extension classes of the platform that javac shipped with. But javac also supports cross-compiling, where classes are compiled against a bootstrap and extension classes of a different Java platform implementation. It is important to use -bootclasspath and -extdirs when cross-compiling; see Cross-Compilation Example below.
-target version
Generate class files that target a specified version of the VM. Class files will run on the specified target and on later versions, but not on earlier versions of the VM. Valid targets are 1.1, 1.2, 1.3, 1.4, 1.5 (also 5), 1.6 (also 6), and 1.7 (also 7).
The default for -target depends on the value of -source:
If -source is not specified, the value of -target is 1.7
If -source is 1.2, the value of -target is 1.4
If -source is 1.3, the value of -target is 1.4
If -source is 1.5, the value of -target is 1.7
If -source is 1.6, the value of -target is 1.7
For all other values of -source, the value of -target is the value of -source.
-bootclasspath bootclasspath
Cross-compile against the specified set of boot classes. As with the user class path, boot class path entries are separated by colons (:) and can be directories, JAR archives, or ZIP archives.
For More about Cross-Compilation look at
http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html#crosscomp-options
Better than me at
http://www.oracle.com/technetwork/java/javase/compatibility-417013.html
The code base for Java 7 and versions of Java 6 is very similar and even shares many of the same bugs. e.g. the was a well known bug in Java 7 when it was released to do with loop optimisation and people suggested waiting for it to be fixed before migrating. The interesting thing was the bug was also in Java 6, the only difference was that the optimisation was on by default in Java 7 and off by default in Java 6.
Most of the performance improvements in Java 7 were back ported into Java 6.
I have two jars: CLI.jar and Some.jar; CLI.jar depends on Some.jar.
The major version of CLI.jar classes is 51 (Java 7)
The major version of Some.jar classes is 52(Java 8)
I run java -jar CLI.jar with JRE 1.7 on a host, it gave "Unsupported major.minor version 52.0" error.
I initially thought it was a JRE version issue, but when I switched to another host which also had JRE 1.7, I did not see this error and everything worked fine.
What did I miss here? I am a professional software developer and I know the basics and double checked the JRE version I am using.
JRE 1.7 is not able to run 1.8 class files (and, by extension, JARs that require 1.8 class files). The error you have encountered points that out quite well.
If another computer can run the same JAR file, its Java version is not 1.8. Note that multiple JREs can be installed on one machine.
TL;DR - No, Java byte code is not forward compatible, but it is backwards compatible.
A bit more details:
Generally, files compiled with later Java version can't be run on the earlier Java machines (e.g. classes compiled with Jdk 1.8 can't be run with Jdk 1.7).
However, this statement is false in the way around context. Any version of Jdk is inherently, and by design, backwards compatible1, which means, that Jdk 1.8 can run programs compiled with compiler from Jdk 1.7.
1There is a little catch here. It's rare, but sometimes, later Java versions deprecate and then finally remove some APIs, Frameworks, Libraries or etc. from the build. For example, JavaFX has been removed since Java 11. So, if this kind of situation arises, and you upgrade your Java, you'll just need to manually add missing (in this case - JavaFX) dependency.
I can find java, javac and javadoc but there is no javah.exe in my jdk\\bin folder.
I tried to reinstall the JDK but it is still missing. How can I get it, why is it missing?
I found a similar question where the operating system was Linux but I can not find answers for Windows users.
My OS is Windows 10. The Java version is 10.0.1.
The tool javah.exe was removed in Java 10. The reason is simple, it is obsolete. From JEP 313: Remove the Native-header Generation Tool (javah):
Motivation
The tool has been superseded by superior functionality in javac, added in JDK 8 (JDK-7150368). This functionality provides the ability to write native header files at the time that Java source code is compiled, thereby eliminating the need for a separate tool.
Focusing on the support provided by javac eliminates the need to upgrade javah to support recent new paradigms, such as API access via the Compiler API in javax.tools.*, or the new java.util.spi.ToolProvider SPI added in JDK 9.
So you can just use javac.exe if you are on Java 8 or newer.
javah has been superseded by the -h option added to javac in JDK 8.
It is deprecated since Java 9.
See here for details.
I'm trying to consume a third-party API, where I get support for the third party API upto JDK 1.6.
I have other few projects which are built using JDK 1.7 and as part of the product I'm also packaging JRE 1.7.
if compiler compliance level is set to JDK 1.6, compile & run using JDK 1.7 libraries produce same result as of compile & run using JDK 1.6?
Would it be safe to claim support from third-party vendor when compiler compliance level is set to JDK 1.6.
Update:
I presumed that setting compiler level in eclipse is same as setting -source & -target options of javac.
I'm not sure if compiling using JDK 1.7 setting source & target to 6/1.6 is same as compiling in jdk1.6.
The problem is in changes of Java API between versions. There are some classes and methods that are available in Java 7 but not in Java 6 and other way round. The code compiles with Java 7 but it will not run with Java 6 because of missing classes or methods.
Unless you compile with Java 6 JDK, you cannot be 100% sure.
Yes, if you compile with compliance level set to 1.6, it will be able to run on java 6 - compiler will guarantee that. It should be able to run on java 7 as well, since JRE is backward-compatible.
You can actually specify the .class files version compatibility in the "Preferences->Java->Compiler" (project specific), so at worst you are benefitting from a more recent compiler building probably exactly the same bytecode as using JDK 1.6.
"Compliance 1.6" however does not ensure that you get exactly the same result as using JDK1.6, but java standard ensures applications built with 1.6 will run the same on a >= 1.6 JRE.
So if you are really afraid of incompatibilities, build the project (on your CI server I suppose) with a project specific setting 1.6 on a machine with both JRE 1.6 for this one, and 1.7 for other projects, and bundle a 1.7 in your distribution, it is guaranteed to run ok by Sun/oracle/java.
i.e. if the code is built with JDK 1.6, and used by other JDK >= 1.7 code you are fine with respect to versioning. Probably this is the case of many jars you use everyday.
However, building the code that is stamped 1.6, with a real JDK 1.6 is the only sensible thing to do if you are afraid of real world problems (money involved).
So I think then you are safe to "claim support", build in 1.6 and use the jar in 1.7.
In my experience with Eclipse, Compliance level set to Java 5 is not the same as compiling with JDK5. It has allowed Java 6 methods to pass compilation locally when the Installed Java was set to Java 6 and the compliance was set to 5 and then our build failed when the files were checked in.
I am currently working in jdk 1.5 version. I want to compile and execute code in jdk 1.6 version.
How can i do this?
It's a bit unclear what you're asking.
If you're asking whether you can compile code with JDK 1.5 and run it with JDK 1.6, yes, that's fine. 1.6 can run code compiled with 1.5 without trouble. You won't be able to make use of any of the Java 6 (1.6) compile-time or API enhancements, of course. To do that, you'd have to compile with the 1.6 (or higher) JDK.
If you're asking how to start using 1.6, just install it and start using it. (That's a very general and somewhat vague answer, but then, it's a very general and vague question.)
Use the -target and -source flags to tell the compiler what source version you are using or what target version you plan to run it on
javac -target 1.6 -source 1.5 [classes to compile etc]
http://docs.oracle.com/javase/6/docs/technotes/tools/solaris/javac.html#options
Install JDK 1.6 and re-set your JAVA_HOME variable. Normally, the code from the older platform versions will work on newer ones.
if you are using an IDE, there must be an option with the location of java compiler, change to the directory of your installation of your new jdk.
else, change the value of your environement variable JAVA_HOME to the directory of your installation of your new jdk.
you don't have any change to do in your code
jdk 1.6 supports all features present in jdk 1.5.So u can compile and run your program on jdk1.6 without any problem.
Java is backwards compatible, so you can compile and run your application on 1.6 without any problems but maybe with some warning messages on compile.
You can use also the arguments -target and -source. More info here
Have a look at the java documentation about compatibility issues.
Find here