A question asked at Devoxx was: should Java 7/8 be backwards compatible?
A really good question in my opinion. I would say yes but only one version. So Java 7 should be compatible with 6 but not with the versions before that. What do you guys think?
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." --- Martin Fowler
Please correct my English.
I wouldn't mind if Java 7 source code wasn't backwards compatible, but I'm not sure I like the idea of the compiled code not being backwards compatible. Our production environment uses a dozen or two open-source products and having to come up with Java-7-compatible versions of all of them could be a challenge.
I'm not sure about Java 7 but if I remember correctly, Java versions 5 and 6 not only added new features but also improved runtime performance. Garbage collection was improved, memory management etc. Therefore if JVM improvements / enhancements are also planned for Java 7 and 8 I'm sure that old Java code would benefit from backward compatability.
Yes. I would expect Java 7/8 to be backward compatible at the .class level. At the source level, I would expect it to be mostly backward compatible. Like Java 1.4 added assert and Java 5 added enum. Not a big effort to change But if there are too many changes, it makes things difficult.
There was a big majority that liked the idea of Java 8 or 9 being backwards incompatible. I voted +1 too, it would be good to get rid of at least the deprecated cruft. Maybe there should be a separate, optional compatibility package to make it possible to run old code on the new JVM.
I'm not sure if the Java 8 changes should be compatible with unchanged Java 6 code, which is the only question of interest to me.
Clearly anything called Java has to compile byte code that runs on the JVM, and the JVM can improve and be extended, but old byte code won't use the new features.
At the source code level, I've got mixed feelings. The addition of generics was very ugly, IMHO. Most of the time, they are fairly clean, but some of the syntax is idiotic. One can argue that folks stuck in Java 6 can just use a Java 6 compiler. But this makes adoption of Java 8 stuff hard, since you have to convert everything. This is why some backwards compatibility is usually included as languages evolve. But Fortran-77 broke old code, as did Algol-68. For good reasons.
So if the plan is to layer closures and other new features on as crudely as they did generics, then I'd rather it not be backwards compatible. Just design a new language and be done. While in there, kill off the c-style native variables types that are not Objects.
But I'm not sure that the resulting language would still be Java. I'd be really happy if they froze Java and made Java 8 be a clean reinvention, called Java++ or something else to indicate its not the Java from last century.
No matter the level of changes. I still think backwards compatibility is still very important as for Very big projects, restructuring the whole project might be very challenging. Also consider some cases where third party libraries are used, and vendors have not upgraded.
Also cost wise consider the cost implication...
I will stand my ground that for JDK7/8 should be backwards compatible till JDK5 at least........
Paul Okeke wrote:No matter the level of changes. I still think backwards compatibility is still very important as for Very big projects, restructuring the whole project might be very challenging.
I agree that the level of effort to port old code bases (legacy Java anyone?) is huge. But that implies that folks with huge installed bases will be writing new Java 7 or Java 8 code. If the runtime is compatible, you could use a Java 5 compiler on the old code, and use a Java 7 compiler on the new cool stuff.
Scala is an example of a complete language that does not look like Java, yet used the Java JVM and interoperates well with legacy Java code. Scala also has cleanly designed features that are being tacked onto Java 7/8.
We do not need another backwards compatibility black hole like the type erasure that we got stuck with for Java 5's generics. That was purely caused by the insistence on backwards compatibility.
Java has never been 100% backward compatible and personally I don't mind. We're in a technology rush and we need to move fast; in terms of the JDK, backwards compatibility is expensive and slows us down.
That's what Jigsaw is, no? Come Java 8, due to the modular nature of the JRE, there will be no more requirement for backwards compatibility. At least that's what I got from Mark Reinhold's explanation at Devoxx.
Dieter Quickfend wrote:That's what Jigsaw is, no? Come Java 8, due to the modular nature of the JRE, there will be no more requirement for backwards compatibility. At least that's what I got from Mark Reinhold's explanation at Devoxx.
Not quite correct :-). Whilst Jigsaw will make it easier from a technical standpoint to break backwards compatibility, it's not necessarily in the social/political/ecosystem interests to do so. Oracle will continue to focus on maintaining backwards compatibility as long as they keep getting that message from their customers.
What I actually don't get is why they chose for type erasure instead of keeping that information in the byte code. Class files are never backwards compatible (code compiled with a 1.6 compiler will not run on a 1.5 JVM etc), so that wouldn't be a problem. Existing libraries could still have worked if the generic type would be in the byte code optionally; if it isn't present (starting with some magic number to identify it it's there or not) you simply use a raw type, which could be considered as using Object for the generic type. It's not like the byte code specification doesn't change with new language features (at least, I think it does).
I still would like for this to happen in the future, so you can use the generic type to create arrays (new T) or even instances. I've even thought up a syntax for the latter to require a specific constructor:
- <T> means that there are no constraints on the constructor, meaning you still cannot create instances. This can be used in case you don't need to create instances, and to keep existing code working.
- <T()> means the class is required to have a constructor without parameters, allowing you to call new T().
- <T(int,String)> means the class is required to have a constructor with the given parameter types, allowing you to call new T(13, "Rob").
Any extends information would come after the parentheses, e.g. <T(long) extends Number> would allow you to use Long and BigDecimal T but not Integer, Double or Date.
Mr. Manager I would like to restart the "20 Million lines of code project" because a new version of Java has come out. Oh and I'll ask the same next year when Java 8 will come out.
Seriously, restarting can be a solution but most of the time it is a very very costly one. Regarding your remarks that the beauty of the initial designer's vision is lost can be caused by numerous things. Mostly it is because the architecture hasn't been followed and updated as the project evolved over time and because there isn't some one which checks if the code actually follows the architecture. Restarting isn't really a solution for this, more a fix of the symptoms. Code evolves over time and so should an architecture.
Wouter Oet wrote:Mr. Manager I would like to restart the "20 Million lines of code project" because a new version of Java has come out. Oh and I'll ask the same next year when Java 8 will come out.
I didn't suggest anything of the kind.
But take a million line section of that crock legacy project, and don't just convert it to Java 9, rewrite it. Call it a refactoring, call it maintenance, call it cleanup because its been patched and re-patched 30 times over the past 14 years. Call it what you want. But throw out the old implementation. Write a new one that meets the current functional requirements using modern tools.
If you do a good job, the old million line crock becomes 50,000 lines of beautiful, clear and easy to maintain software.
If the manager is too dumb to agree, I'd find a new job. I've done it.
I believe Java versions should be backwards compatible 2 versions. 2 versions is enough time for 2 versions ago to be well out of date, but still recent enough for the old code to still work.
“Don’t worry if it doesn’t work right. If everything did, you’d be out of a job.” (Mosher's Law of Software Engineering)
“If debugging is the process of removing bugs, then programming must be the process of putting them in.” (Edsger Dijkstra)
But is two enough? Suppose there is this awesome library that someone wrote way back when Java 1.4 was the current version. This library is just great, and a lot of people are using it. However, it hasn't been updated since because, well, it simply works.
Now comes Java 7. The two versions rule applies, so anything written in Java 1.4 doesn't work anymore. That means that the awesome library stops working all of a sudden. The original developer is unable to recompile / rework the library (maybe because he died...), and the library isn't open source. That means that nobody has access to the source. What now? Decompile it?
I'm not saying that backwards compatibility should go on forever (I for instance hate type erasure), but there are very valid reasons for not discarding code written on an older version so easily.