Bug 107783 - should allow 1.4 class generation with java 5 source/compiler compatibility
Summary: should allow 1.4 class generation with java 5 source/compiler compatibility
Status: VERIFIED WONTFIX
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 enhancement with 2 votes (vote)
Target Milestone: 4.5 M4   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-08-23 16:08 EDT by Randy Hudson CLA
Modified: 2014-12-09 23:25 EST (History)
10 users (show)

See Also:


Attachments
Autoboxing support for target < 1.5 (11.13 KB, patch)
2005-10-18 10:18 EDT, Oliver Masutti CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Randy Hudson CLA 2005-08-23 16:08:14 EDT
Some of the new features in java 5 could be used in source code, but would still
result in .class files which would work with 1.4 VMs. The user should be allowed
to select "generated .class file compatibility" preference of 1.4 in conjunction
with 5.0 source and compiler compatibility. A subset of java 5 features would
still compile normally. For example:

@SuppressWarnings({"deprecation"})

would be a great benefit to filtering out bogus or unremovable deprecation
warnings so that I could see real warnings that I could address and fix. AFAIK,
using this 1.5 feature would create .class files that still execute on 1.4 VMS.

Other features, like @Override might work as well.

Then of course things like enums and generics would not work with 1.4 VMs, and
should cause compiler errors.
Comment 1 Markus Milleder CLA 2005-10-12 12:58:12 EDT
(In reply to comment #0)
> Some of the new features in java 5 could be used in source code, but would still
> result in .class files which would work with 1.4 VMs. The user should be allowed
> to select "generated .class file compatibility" preference of 1.4 in conjunction
> with 5.0 source and compiler compatibility. A subset of java 5 features would
> still compile normally. For example:

Depending on the amount of effort, all Java 5 features could be usable on a Java
2 VM. The following is my understanding how several of the features work, and I
apologize in advance if I have a too simple view of the world.

* Autoboxing
emit new Integer(int) instead of Integer.valueOf(int) . This loses the caching
of small valued Integers that Integer.valueOf(int) does. Adding that would
require some other class than Integer to hold the cache array.

* Static import
This should just work.

* Annotations
As afar as I understand, this only adds some extra data to the type info, so
either don't put that in (and rreact to the annotations that are actually
compiler directives) or let the Java 2 VM ignore the unknown data (which I
believe it will).

* Generics
Again add some extra data to the type info and otherwise emit the same code as
using the plain classes and doing manual casting, so it sounds doable, too.

* Enhanced for loop
This would need to emit the Java 2 idiom of the loop without using the Iterable
interface. Additionally code checking for the existence of an iterator() method
and a diagnostic message would be necessary.

* Enums
These would need a new base class.

Retroweaver has a list of things it does in the documentation, and a quick look
over that seems to confirm my thinking. Additionally, the Eclipse Java compiler
is in a position to be the optimal solution mentioned there - a compiler that
understands Java 5 source and can target Java 2 VMs.
Comment 2 Philipe Mulet CLA 2005-10-13 03:35:54 EDT
1. It would be illegal for a compiler to do so. See
http://forum.java.sun.com/thread.jspa?forumID=316&threadID=503547

2. Language features are quite easy to map back, since the VM spec did not get
affected by 1.5 constructs for the most part. Yes enums are a bit of a problem,
but either disallow them or emulate them. Now the hard part is libraries. How
can you tell that some feature you are using did exist in 1.4 ? This is a new
concept our compiler implementation doesn't support (double lookup) or you would
need to validate binaries after the fact.

This being said, there is some work to do there, but until (1) has been
resolved, we will not invest into it. If others are interested in delivering a
tool doing it (just be careful not to claim being a true compiler), we can help
how to make adjustments. Our compiler is indeed able to work in 1.3, 1.4 and 1.5
compliant mode, so there are numbers of switches in place allowing to generate
1.4 constructs if configured properly. 

Autoboxing is known to be not configurable, and Olivier is looking at making it
so (should be a trivial task), but we are not going to officially allow the
-source 1.5 -target 1.4 mode be allowed in the IDE. Now, you can bypass the
official front end, and make the settings the way you want, as some already
figured out.
Comment 3 Markus Milleder CLA 2005-10-13 05:14:40 EDT
(In reply to comment #2)
> 1. It would be illegal for a compiler to do so. See
> http://forum.java.sun.com/thread.jspa?forumID=316&threadID=503547

Thanks for that link.

So there is a political problem: The output of such a compilation could not be
called Java and would hava a similar status as e.g. Jython class files.
Comment 4 Oliver Masutti CLA 2005-10-18 10:18:36 EDT
Created attachment 28389 [details]
Autoboxing support for target < 1.5

Enable the eclipse compiler to generate different Autoboxing code when target
is < Java 1.5. i.e. instead of Integer.valueOf(int) [Static method only
available only on >=1.5JRE] produces new Integer(int).
Comment 5 Oliver Masutti CLA 2005-10-26 05:56:34 EDT
I wrote a small website which collects all information concerning this topic.
find it <a href="http://www.masutti.ch/eel">here</a>. I (also) apologize in
advance if I'm completely wrong with my ideas. It is a "works for me" page.

First of all, you have to figure out how to bypass the gui to make the eclipse
compiler produce target=1.4 (or 1.3) code from 5.0 source. have a look <a
href="http://www.masutti.ch/eel/howto/howto.html">here</a>. For the "batch-mode"
compiler (org.eclipse.jdt.core.JDTCompilerAdapter), there is also a hack to make
it accept source=1.5 target=1.4. 

> * Autoboxing
> emit new Integer(int) instead of Integer.valueOf(int) . This loses the caching
> of small valued Integers that Integer.valueOf(int) does. Adding that would
> require some other class than Integer to hold the cache array.

with the attached patch, this should work. from what I understand, this patch
may make it into some future eclipse version (in this form or another - still
has to be verified).

> * Static import
> This should just work.

agree.

> * Annotations
> As afar as I understand, this only adds some extra data to the type info, so
> either don't put that in (and rreact to the annotations that are actually
> compiler directives) or let the Java 2 VM ignore the unknown data (which I
> believe it will).

put a jar with the standard jdk1.5 annotations somewhere on the build path and
they will work fine. especially useful is @SuppressWarnings when working with
Generics.

> * Generics
> Again add some extra data to the type info and otherwise emit the same code as
> using the plain classes and doing manual casting, so it sounds doable, too.

As, to me, the java.util.Collection classes seemed most useful in a parametrized
way, I looked for a workaround. You "just" have to hide the original JDK1.4
Collection classes by adding you own parametrized versions of the classes at the
top of your buildpath. This requires some work you have to do - as has been
pointed out, there is no efficient way to make the compiler look at two
different class libraries and decide whether a class/method is downwards
compatible. So I "ported" some of the most useful 1.4 collection classes to a
parametrized version. also see the above mentioned page for a download.

> * Enhanced for loop
> This would need to emit the Java 2 idiom of the loop without using the Iterable
> interface. Additionally code checking for the existence of an iterator() method
> and a diagnostic message would be necessary.

Classes that derive from java.util.Collection are in a lucky position: they
already implement iterator(). Soooo, if you take the "ported" collection
classes, they should work fine with foreach. As long as you don't refer to
java.lang.Iterable directly, I have to add.

> * Enums
> These would need a new base class.

I'm stuck there, too. But I can live without them for now...

Ciao!
Ollie
Comment 6 Olivier Thomann CLA 2005-11-16 10:40:24 EST
(In reply to comment #5)
> with the attached patch, this should work. from what I understand, this patch
> may make it into some future eclipse version (in this form or another - still
> has to be verified).
The patch has been reviewed and committed with minor changes.
Now the following code works fine on a 1.4 VM once the compiler has been hacked
to accept -source 1.5 -target 1.4.

public class X {
	public static void main(String[] args) {
		Integer i = 0;
		Boolean b = true;
		Byte b1 = 1;
		Character c = 't';
		Double d = -0.0;
		Float f = 1.0f;
		Long l = 10000000L;
		Short s = 128;
		System.out.println(i);
		System.out.println(b);
		System.out.println(b1);
		System.out.println(c);
		System.out.println(d);
		System.out.println(f);
		System.out.println(l);
		System.out.println(s);
	}
}
Comment 7 Missing name Mising name CLA 2006-05-18 19:58:50 EDT
To get around the issue of creating something 'not quite Java' would it be possibe to use pre-Java 5 as an intermediate language?  That is, Java 5 source is translated into >=Java 1.4 source (possibly a separate project) which is then compiled to 1.4 bytecode with 1.4 libraries.  Library version errors could be flagged up during the second stage.  This approach would allow emulation classes to be created, though it could result in discrepencies between the 5 source and the API in the pre-5 bytecode, e.g. enumerations could be emulated but they wouldn't be interchangable with true Java 5 enums.
Comment 8 Jörg von Frantzius CLA 2006-05-19 09:57:52 EDT
(In reply to comment #6)
So now what is the exact state of this enhancement? Can I e.g. somehow compile Java 1.5 sources into 1.4 bytecode with a vanilla Eclipse 3.2RC4? 

Our usecase is that we have a common huge framework being reused in several projects, with one of them unfortunately being stuck with JDK 1.4. We became so used to 1.5 syntax + generics that its really a PITA not being able to use it in the framework.

I'd be very happy if I could chose 1.5 compiler (and JRE, if necessary), with 1.4 bytecode being produced, with a warning coming up that I can get all sorts of XXNotFoundErrors when running against a JRE 1.4.

Just for the records, there is a corresponding thread in eclipse.tools.jdt with subject "Source 5.0, Target < 5.0 ?".
Comment 9 Channing Walton CLA 2006-05-22 07:16:27 EDT
+1 for this. There is a 'special' feature of the java 5 compiler which allows you to compile Java 5 code to 1.4 which is called jsr14. You just specify a source of 1.5 and target of "jsr14"

Channing
Comment 10 Jörg von Frantzius CLA 2006-05-22 08:34:41 EDT
(In reply to comment #9)
> +1 for this. There is a 'special' feature of the java 5 compiler which allows
> you to compile Java 5 code to 1.4 which is called jsr14. You just specify a
> source of 1.5 and target of "jsr14"

Unfortunately that seems to be an undocumented feature not officially supported. From the thread on Sun's forumns linked by the excellent page http://www.masutti.ch/eel I find this the most interesting statement (written by "gafter", probably from Sun?): 

"The problem is not and engineering problem of how to implement it - as you can see from the jsr14 prototype, we've worked out the technical issues - nor of why we should do so. We even know how to make enums work (thanks, Lubo!). The problem is a legal one in that it violates the Java platform specifications. That is not something we would allow our licensees to do, and we should not therefore do it ourselves. If we allow the hybrid language then we will need a language specification, a conformance suite, and licensing terms for the hybrid language."

I can imagine this being a problem for Sun, but is it for Eclipse or IBM? I'd think supporting this officially would be an outstandingly interesting feature. I'm afraid IBM as a licensee could get on legally shaky ground here as well, though (unless they disable UI acces to the feature in WSAD maybe?)
Comment 11 Philipe Mulet CLA 2006-05-22 10:16:39 EDT
Since you noticed the "jsr14" undocumented target, here is more info.
We did introduce this secret target recently. It internally does for the batch compiler what -source 1.5 -target 1.4 did for a while. We wanted to remove it entirely, but noticed that javac 1.6 still supported the "jsr14" target.

This is why we added it, as an experimental option. It may be useful for some usage, though over time, this ability will be less and less useful.
Note that it doesn't handle all 1.5 constructs on 1.4 runtime, and that in 3.3, we may invest a bit more to handle/emulate more of them.
Comment 12 Jörg von Frantzius CLA 2006-05-23 09:47:42 EDT
(In reply to comment #11)
> Note that it doesn't handle all 1.5 constructs on 1.4 runtime, and that in 3.3,
> we may invest a bit more to handle/emulate more of them.

Does there per chance exist some documentation on what 1.5 features exactly are supported on 1.4 runtime? Is e.g. generics supported when providing "backported" collection interfaces as described in http://www.masutti.ch/eel/ ?

How about making the switch accessible in the UI?
Comment 13 Oliver Masutti CLA 2006-08-10 08:44:19 EDT
> (In reply to comment #6)
> So now what is the exact state of this enhancement? Can I e.g. somehow compile
> Java 1.5 sources into 1.4 bytecode with a vanilla Eclipse 3.2RC4? 

fyi I updated my website (www.masutti.ch/eel) => eclipse 3.2 seems to support most features out of the box now, without hacking the batch compiler/code generation, thanks to target "jsr14" and the autoboxing enhancement. You will "only" still need to work around the UI switch.
Comment 14 David Witherspoon CLA 2006-09-28 11:39:27 EDT
It certainly looks to me like Sun's 1.5 javac compiler allows compiling code that allows 1.5 features, but generating code that will run under 1.4.  See http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/javac.html, and check out the section on cross-compiling.
Comment 15 Olivier Thomann CLA 2006-09-28 20:05:48 EDT
This is not what I got from this section.
It is using the bootclasspath to set the classes to be the 1.4 classes. Nothing is mentionned about compiling 1.5 source code to 1.4 target level.
See comment 11 for existing support.
Comment 16 Olivier Thomann CLA 2007-06-21 12:28:41 EDT
We have done what we could at the core level.
No further action planned for JDT/Core.

Moving to JDT/UI to investigate if the target jsr14 should be exposed. Feel free to close it if no action is planned in the UI.
Comment 17 Martin Aeschlimann CLA 2007-06-22 06:48:44 EDT
I think it's better to close this bug in jdt.core land, with the appropriate milestone. Please file a bug against JDT to add the new class file target (I guess we need a new constant in JavaCore)
Comment 18 Oliver Masutti CLA 2007-06-27 10:24:07 EDT
(In reply to comment #16)
> We have done what we could at the core level.
> No further action planned for JDT/Core.

did you invest some more into this? (Philippe mulet wrote in comment #11:"and that in 3.3, we may invest a bit more to handle/emulate more of them") I think what you've done is already sufficient, for the enum part there is a more sophisticated solution needed, out of the scope of jdt, imho. Otherwise, this is as much as you can get from a generic solution. Thanks!

> Moving to JDT/UI to investigate if the target jsr14 should be exposed. Feel
> free to close it if no action is planned in the UI.

wouldn't exposing the jsr14 target in the UI move you into legal troubles? From what I understand, the language you supported must not be called a Java anymore.
Comment 19 Randy Hudson CLA 2014-10-01 14:27:52 EDT
Targetting 1.4 JREs is no longer important.  This can be closed, unless you want to recycle it for java 7/8 features in java 6/7.  I don't know that there are as many language features that are n-1 binary compatible as there were in java 6.
Comment 20 Jay Arthanareeswaran CLA 2014-11-10 04:12:41 EST
(In reply to Randy Hudson from comment #19)
> I don't know that
> there are as many language features that are n-1 binary compatible as there
> were in java 6.

I am not sure, but we can create a new bug should we need it.

I agree it's time to close this. Not sure what's left, but we have no intention of revisiting this one.
Comment 21 Jay Arthanareeswaran CLA 2014-12-09 23:25:16 EST
Verified for 4.5 M4