Allow new language features on older version targets?
forax at univ-mlv.fr
Tue Oct 12 14:25:56 UTC 2021
Java 9 can be a hard pill to swallow, part of the issues is that all dependencies need to be updated before moving to 11, slowing down the adoption of Java 11.
I think your proposal does not help.
You have forgotten the fact that the bytecode is not only consumed by the VM but by a lot of languages, tools, frameworks and libraries.
Gradle, ErrorProne, FindBugs, Spring, Hibernate just to cite a few may/will choke if there are known new bytecode attributes but in older classfile versions.
So nestmates, records and sealed classes, all introduce new attributes thus can not be backported as is.
Records and switch on types both require special bootstrap methods, which did not exist in older JDK thus it can not be backported as is.
For switch expression, the structure of the generated bytecode is quite unusual, a value stay on stack before the goto at the end of each case, again, it can trouble some static analysis, so it can not be backported as is.
For me, the cost of having to test and maintain all combinations of the new feature with the old bytecodes for every existing software that consume bytecodes clearly outweigh what you think could be a nice feature to have.
PS: i'm currently playing with Scala 3 and i really hope that a lot of people will use it, there are some really great features in Scala 3, and i'm curious how people will use them.
> From: "Glavo" <zjx001202 at gmail.com>
> To: "compiler-dev" <compiler-dev at openjdk.java.net>, "jdk-dev"
> <jdk-dev at openjdk.java.net>
> Sent: Mardi 12 Octobre 2021 10:14:45
> Subject: Allow new language features on older version targets?
> Starting from Java 9, Java began to iterate rapidly and introduced
> many new features, which made Java more expressive and modern.
> However, upgrading Java is always difficult and painful. It needs to
> go through a series of cumbersome upgrade and migration processes.
> In these steps, the transplantation at the syntax level is often easy,
> because Java maintains good compatibility. However, due to subtle
> changes in the behavior of the JVM and the standard library, it is
> relatively difficult to upgrade the version of the java runtime.
> At the same time, for client applications, upgrading the development
> environment is much easier than upgrading the Java version of the
> deployment environment (e.g., only Java 8 is currently available on
> MIPS64el). For various reasons, a large number of users stay on the
> old java version. According to the statistical report of JetBrains,
> 71% of users still regularly use Java 8.0 in 2021.
> The most affected people are the developers of libraries. In order to
> make the library more widely used, most library authors always need to
> make their libraries use the lowest java version possible. This makes
> it difficult for them to enjoy the expression upgrade brought by Java
> This pain is not necessary. Although some language features of Java
> require the cooperation of JVM and standard library, e.g. Record, but
> this is not necessary for more features. At present, we can specify
> the source version and target version respectively, but we can't make
> the source version higher than the target version. I think this
> artificial additional restriction can be removed after careful
> consideration, so that more developers can enjoy the improvement of
> expression ability brought by Java's new language features.
> These features are pure language features that can be easily compiled
> into older versions of Java bytecode:
> * Milling Project Coin (JEP 213): Allow @SafeVargs on private instance
> methods; Allow effectively-final variables to be used as resources
> in the try-with-resources statement;Allow diamond with anonymous
> classes if the argument type of the inferred type is denotable.
> * Local-Variable Type Inference (JEP 286)
> * Local-Variable Syntax for Lambda Parameters (JEP 323)
> * Switch Expressions (JEP 361)
> * Text Blocks (JEP 378)
> * Pattern Matching for instanceof (JEP 394)
> * Pattern Matching for switch (JEP 406)
> * Record Patterns & Array Patterns (JEP 405)
> These characteristics cannot be directly desugared, but can be accepted
> by the old runtime:
> * module-info.java (JEP 261): At present, it is a popular practice to
> use Java 8 compilation library and add module info to it. However,
> this practice has not been well supported by the official. Even
> with a build tool like gradle, it needs to be implemented by
> special means. If javac can accept module info when the target
> version is less than 9 and compile it to Java 9, it is very helpful
> to simplify modular existing code.
> * Allow interface methods to be private (JDK-8071453): This seems to
> be allowed in jvmls 8, but it was not until Java 9 that it was
> introduced into the Java language.
> * Sealed Classes (JEP 409): Javac generates PermittedSubclasses_attribute
> for sealed classes. This attribute will be ignored on the old
> runtime and will not destroy the program. Even if it cannot be
> guaranteed by the runtime before JDK 15, it can enhance the
> expressiveness of the language and make the code more compatible
> with the higher version runtime.
> * Universal Generics (JDK-8261529): Universal generics seem to
> compile well into bytecode compatible with older Java version.
> I think it is particularly important to allow use of universal
> generic in older bytecodes. This allows the library to adapt it
> without compromising compatibility with older Java versions. This
> can erase many obstacles to Valhalla's promotion.
> Now we can use some hacks to do similar things, like
> [ https://github.com/bsideup/jabel | https://github.com/bsideup/jabel ]
> But this is just hack. It is unofficial and non-standard. At the same
> time, it also lacks tool support.
> We can also choose to switch to kotlin or Scala, both of them can emit
> Java 8 bytecode. In fact, because of the need for compatibility, the
> new language features of Java can't bring us more attraction because
> we can't use it most of the time. Over time, kotlin and Scala, which
> can have more language features on Java 8, have attracted us more and
> more. These problems are not just in the Java 8 era. The need to be
> compatible with old Java versions always exists, which makes it difficult
> for many people to put new features of the Java language into production
> for a long time. This will make Java less competitive with other JVM
More information about the jdk-dev