How do I install older version of JDK on Mac? - java

I need to install JDK 5 for testing Amazon mechanical turk APIs (which is not fully compatible with JDK 6). On Apple's website, I can only find the latest JDK. Is there a way to get older versions of JDKs for Mac?

This hint might help :
10.6: Re-enable Java 1.4.2 and Java 1.5 apps in Snow Leopard

Yes, this is the problem with macs.
If you do backups, then you can just copy old folders containing jdk 5 from backup disk back to your machine. Worked for me.

use
-target 1.5

You can compile against the 1.5 jdk with settings in javac.
In your case :
javac -source 1.5 -target 1.5
You can even set this in your IDE. Or you can do this with maven and the maven.compile.target and maven.compile.properties
-source release
Specifies the version of source code accepted. The following values for release are allowed:
[...]
1.5
The compiler accepts code containing generics and other language features introduced in JDK 5.
[...]
-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) and 1.6 (also 6).
The default for -target depends on the value of -source:
If -source is not specified, the value of -target is 1.6
If -source is 1.2, the value of -target is 1.4
If -source is 1.3, the value of -target is 1.4
For all other values of -source, the value of -target is the value of -source.
Resources :
Javac 6 documentation
Maven - Setting the -source and -target of the Java Compiler

Related

Version issue in custom jar

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.

Compile with java 6 from java 8 JDK installed

I am required to compile my source code with Java 6 for university. I currently have Java 8 JDK installed on my PC (Linux). How do I compile in Java 6?
p.s. I understand I wont be able to use any Java 7 or 8 features.
p.p.s. I realize java 6 source code will compile fine using the Java 8 JDK however I find that I am accidentally using post Java 6 features in my programs when compiling at home. When I try to compile the source code on the lab computers at uni I run into a bunch of errors. e.g. not being able to cast an object to a primitive.
The way to fix that problem is to compile using the later SDK and use the cross compilation options when compiling.
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 the -bootclasspath and -extdirs options when cross-compiling.
-target version
Generates class files that target a specified release of the virtual machine. Class files will run on the specified target and on later releases, but not on earlier releases of the JVM. Valid targets are 1.1, 1.2, 1.3, 1.4, 1.5 (also 5), 1.6 (also 6), 1.7 (also 7), and 1.8 (also 8).
The default for the -target option depends on the value of the -source option:
If the -source option is not specified, then the value of the -target option is 1.8
If the -source option is 1.2, then the value of the -target option is 1.4
If the -source option is 1.3, then the value of the -target option is 1.4
If the -source option is 1.5, then the value of the -target option is 1.8
If the -source option is 1.6, then the value of the -target is option 1.8
If the -source option is 1.7, then the value of the -target is option 1.8
For all other values of the -source option, the value of the -target option is the value of the -source option.
-bootclasspath bootclasspath
Cross-compiles 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.
To use the options completely correctly (i.e. using also the -bootclasspath option) requires the rt.jar of a JRE (not JDK) of the target version.
You can use the below for compilation
% javac -target 1.6 <whatever you want to compile>
I had a similar issue where a part of the project wanted to use Java 6 and rest of the project needed Java 8. You can change java version in just one terminal window for this purpose.
To change the java version in just one terminal window without changing the profile, use:
export JAVA_HOME=$(/usr/libexec/java_home -v 1.6)

what's the difference between -source and -target compatibility?

When using the Java compiler (javac), we can specify two kinds of compatibility. One is using -source and the other is using -target. What is the difference between these two?
For example, -source 1.5 and -target 1.6?
Also, is there any case where we use a different source and target compatibility level?
From the javac docs:
-source Specifies the version of source code accepted.
-target 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.
In your example:
-source 1.5 and -target 1.6
This would be used to make sure that the source code is compatible with JDK 1.5, but should generate class files for use on JDK 1.6 and later.
Quite why you would do this is another matter.
The -source indicates what level of compliance your source code has: are you using Annotations? Then you would need at least 1.5; are you using #override on interface implementations, you would need 1.6 etc
The -target specifies what Java version you want to be able to run your classes on. You could use a Java SE 7 compiler and compile to run on Java SE 1.5.
This is mostly useful to produce a jar file working with an older version of Java.
I believe that so far all JDKs are able to execute older version too, so there is no real reason to have target larger than source.
It does however make sense to set target to e.g. 1.6 when using a 1.7 JDK.
I'm not sure, but I believe it could work in some situations to compile a 1.7 java code using a 1.7 compiler to a 1.6 jar, for example expressions such as
ArrayList<Integer> foo = new ArrayList<>();
that are only valid in 1.7+ source version should compile to 1.6 compatible byte code. But I have not verified whether the compiler will actually do this. Unfortunately, this doesn't seem to be implemented in practise.

Applet jar generated with JDK 1.6 compiler on a system with JRE 1.5

Can a applet compiled with JDK 1.6(but not using any new features of 1.6) work on systems having JRE 1.5?
As others have mentions, you need -target 1.5 to generate 1.5 code. In order to use -target 1.5 you also need to set -source 1.5. Using any part of the 1.6 library that is not used in 1.5 will also cause a fail at run time, so use -bootclasspath to point to a 1.5 rt.jar. For completeness the "external directories" (libraries available to almost all code) should be set (probably to something empty) with, IIRC, -Dext.dirs.
No, the compiled code will require JRE 1.6 or later. JDK 1.6 will generate Java .class files with version 50.0 while 1.5 uses version 49.0.
Use javac -target 1.5 to generate .class files that JRE 1.5 can use. See http://docs.oracle.com/javase/6/docs/technotes/tools/windows/javac.html#options
If the code was compiled using compiler flag -target 1.6 (which is default for 1.6 JDK) - then it will not run on 1.5 JRE.
However, if the flag -target 1.5 was used - then it will work properly on 1.5 JRE.

Many versions of JDK: How do I specify which one is used?

I have installed many versions of the JDK: 1.4.2, 1.5 and 1.6.
How do I specify which version of the JDK is used when compiling using Ant?
Two solutions:
Specify the full path in your command:
for example /opt/java/jdk16/bin/javac ... on Linux
Use the -source and -target arguments of the javac command. This allows you specify the source code level and targeted JRE version
Also note:
Some Linux distributions can include tools to specify which JDK version to use by default.
Using -source and -target checkes that your language constructs are compliant with the targeted runtime, but does NOT check that core classes are compatible. This means that compiling with -source 1.4 on a JDK 1.6 will be just fine, even if you use String.isEmpty() which appeared in Java 6. This might lead to errors at runtime
javac -source 1.4 -target 1.4 YourFile.java
-source release
Specifies the version of source code accepted. The following
values for release are allowed:
1.3 the compiler does not support assertions, generics, or other
language features introduced after JDK 1.3.
1.4 the compiler accepts code containing assertions, which were
introduced in JDK 1.4.
1.5 the compiler accepts code containing generics and other
language features introduced in JDK 5. The compiler defaults to the
version 5 behavior if the -source flag is not used.
5 Synonym for 1.5
Here is the relevant documentation.
http://download.oracle.com/javase/1,5.0/docs/tooldocs/windows/javac.html
Use the Ant <javac> task<source> and/or <target> attributes. Valid values can be from 1.1 to 1.7, with 5, 6, and 7 valid aliases for 1.5, 1.6 and 1.7. Also, the <executable> attribute can be used to set which java javac compiler is used. For example:
<javac source="1.4" target="1.4" executable="c:\java1.6\bin\javac.exe"/>

Categories

Resources