Community
Participate
Working Groups
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.
(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.
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.
(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.
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).
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
(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); } }
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.
(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 ?".
+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
(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?)
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.
(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?
> (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.
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.
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.
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.
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)
(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.
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.
(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.
Verified for 4.5 M4