[PATCH]: javac[8,9] with jdk7

Liam Miller-Cushon cushon at google.com
Thu Apr 3 17:40:40 UTC 2014


On Wed, Mar 26, 2014 at 1:34 AM, Joel Borggrén-Franck <
joel.franck at oracle.com> wrote:

> having javac run with JRE n-1 in a degraded state would be a nice
> contribution if the patches aren't too intrusive.


It sounded like that was the general consensus, so I put together a patch
to allow javac 9 to run on jre 7 in a degraded state. That means:

- warnings aren't generated for annotation processors that support
RELEASE_7 when the source level is 8 or 9 (because the RELEASE_8 and
RELEASE_9 constants aren't available)

- the native headers feature is disabled (because
StandardLocations.NATIVE_HEADER_OUTPUT isn't available)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20140403/835bedce/attachment-0001.html>
-------------- next part --------------
# HG changeset patch
# User Liam Miller-Cushon <cushon at google.com>
# Date 1396544631 25200
#      Thu Apr 03 10:03:51 2014 -0700
# Node ID ca676423ae58b3f4a87fb89c380d39d8d087a149
# Parent  e25d44c21b29e155734f8d832f2edac3d0debe35
Allow javac 9 to run on jre 7 in a degraded state.

diff -r e25d44c21b29 -r ca676423ae58 src/share/classes/com/sun/tools/javac/code/Source.java
--- a/src/share/classes/com/sun/tools/javac/code/Source.java	Thu Mar 27 11:38:37 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Source.java	Thu Apr 03 10:03:51 2014 -0700
@@ -246,11 +246,32 @@
         case JDK1_7:
             return RELEASE_7;
         case JDK1_8:
-            return RELEASE_8;
+            return release8;
         case JDK1_9:
-            return RELEASE_9;
+            return release9;
         default:
             return null;
         }
     }
+
+    /** {@link SourceVersion.RELEASE_8}, or the latest release if it doesn't exist. */
+    private static final SourceVersion release8 = getLatestSupportedSourceVersion("RELEASE_8");
+
+    /** {@link SourceVersion.RELEASE_9}, or the latest release if it doesn't exist. */
+    private static final SourceVersion release9 = getLatestSupportedSourceVersion("RELEASE_9");
+
+    /**
+     * Allow javac to compile with -source N and -target N while running on JRE N-1.
+     *
+     * If SourceVersion.RELEASE_N does not exist, fall back to using the latest available release.
+     * This will prevent warnings from being issued about annotation processors that do not support
+     * source version N, but will otherwise allow javac to run normally and generate version N
+     * bytecode.
+     */
+    private static SourceVersion getLatestSupportedSourceVersion(String name) {
+        try {
+            return SourceVersion.valueOf(name);
+        } catch (IllegalArgumentException useLatestInstead) {}
+        return SourceVersion.latest();
+    }
 }
diff -r e25d44c21b29 -r ca676423ae58 src/share/classes/com/sun/tools/javac/file/Locations.java
--- a/src/share/classes/com/sun/tools/javac/file/Locations.java	Thu Mar 27 11:38:37 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/file/Locations.java	Thu Apr 03 10:03:51 2014 -0700
@@ -48,6 +48,7 @@
 
 import com.sun.tools.javac.code.Lint;
 import com.sun.tools.javac.main.Option;
+import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Options;
@@ -651,15 +652,18 @@
         handlersForLocation = new HashMap<>();
         handlersForOption = new EnumMap<>(Option.class);
 
-        LocationHandler[] handlers = {
+        List<LocationHandler> handlers = List.of(
             new BootClassPathLocationHandler(),
             new ClassPathLocationHandler(),
             new SimpleLocationHandler(StandardLocation.SOURCE_PATH, Option.SOURCEPATH),
             new SimpleLocationHandler(StandardLocation.ANNOTATION_PROCESSOR_PATH, Option.PROCESSORPATH),
             new OutputLocationHandler((StandardLocation.CLASS_OUTPUT), Option.D),
-            new OutputLocationHandler((StandardLocation.SOURCE_OUTPUT), Option.S),
-            new OutputLocationHandler((StandardLocation.NATIVE_HEADER_OUTPUT), Option.H)
-        };
+            new OutputLocationHandler((StandardLocation.SOURCE_OUTPUT), Option.S));
+        
+        if (hasNativeHeaderOutput()) {
+            handlers = handlers.append(
+                    new OutputLocationHandler(nativeHeaderOutput(), Option.H));   
+        }
 
         for (LocationHandler h: handlers) {
             handlersForLocation.put(h.location, h);
@@ -668,6 +672,42 @@
         }
     }
 
+    private static final JavacFileManager.Location nativeHeaderOutput;
+    static {
+        JavacFileManager.Location result = null;
+        for (StandardLocation location : StandardLocation.values()) {
+            if (location.getName().equals("NATIVE_HEADER_OUTPUT")) {
+                result = location;
+                break;
+            }
+        }
+        nativeHeaderOutput = result;
+    }
+
+    /**
+     * Test whether StandardLocation.NATIVE_HEADER_OUTPUT is available (i.e. the current JRE is
+     * version 8 or greater).
+     *
+     * @return true if StandardLocation.NATIVE_HEADER_OUTPUT exists
+     */
+    public static boolean hasNativeHeaderOutput() {
+        return nativeHeaderOutput != null;
+    }
+
+    /**
+     * Provide StandardLocation.NATIVE_HEADER_OUTPUT if it is available. This is needed for runtime
+     * compatibility with JRE 7.
+     *
+     * @return StandardLocation.NATIVE_HEADER_OUTPUT
+     * @throws NullPointerException if StandardLocation.NATIVE_HEADER_OUTPUT does not exist
+     */
+    public static JavacFileManager.Location nativeHeaderOutput() {
+        if (nativeHeaderOutput == null) {
+            throw new NullPointerException();
+        }
+        return nativeHeaderOutput;
+    }
+
     boolean handleOption(Option option, String value) {
         LocationHandler h = handlersForOption.get(option);
         return (h == null ? false : h.handleOption(option, value));
diff -r e25d44c21b29 -r ca676423ae58 src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java
--- a/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java	Thu Mar 27 11:38:37 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java	Thu Apr 03 10:03:51 2014 -0700
@@ -42,6 +42,7 @@
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.VarSymbol;
 import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.file.Locations;
 import com.sun.tools.javac.code.Type;
 import com.sun.tools.javac.code.Types;
 import com.sun.tools.javac.model.JavacElements;
@@ -171,7 +172,7 @@
     public FileObject write(ClassSymbol c) throws IOException {
         String className = c.flatName().toString();
         FileObject outFile
-            = fileManager.getFileForOutput(StandardLocation.NATIVE_HEADER_OUTPUT,
+            = fileManager.getFileForOutput(Locations.nativeHeaderOutput(),
                 "", className.replaceAll("[.$]", "_") + ".h", null);
         PrintWriter out = new PrintWriter(outFile.openWriter());
         try {
diff -r e25d44c21b29 -r ca676423ae58 src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
--- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu Mar 27 11:38:37 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu Apr 03 10:03:51 2014 -0700
@@ -56,6 +56,7 @@
 import com.sun.tools.javac.comp.*;
 import com.sun.tools.javac.comp.CompileStates.CompileState;
 import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.file.Locations;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.parser.*;
 import com.sun.tools.javac.processing.*;
@@ -1564,7 +1565,8 @@
                 if (usePrintSource)
                     file = printSource(env, cdef);
                 else {
-                    if (fileManager.hasLocation(StandardLocation.NATIVE_HEADER_OUTPUT)
+                    if (Locations.hasNativeHeaderOutput()
+                            && fileManager.hasLocation(Locations.nativeHeaderOutput())
                             && jniWriter.needsHeader(cdef.sym)) {
                         jniWriter.write(cdef.sym);
                     }
diff -r e25d44c21b29 -r ca676423ae58 src/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java
--- a/src/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java	Thu Mar 27 11:38:37 2014 -0700
+++ b/src/share/classes/com/sun/tools/sjavac/comp/SmartFileManager.java	Thu Apr 03 10:03:51 2014 -0700
@@ -25,6 +25,7 @@
 
 package com.sun.tools.sjavac.comp;
 
+import com.sun.tools.javac.file.Locations;
 import com.sun.tools.javac.util.ListBuffer;
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -175,7 +176,8 @@
     {
         FileObject file = super.getFileForOutput(location, packageName, relativeName, sibling);
         if (file == null) return file;
-        if (location.equals(StandardLocation.NATIVE_HEADER_OUTPUT) &&
+        if (Locations.hasNativeHeaderOutput() &&
+                location.equals(Locations.nativeHeaderOutput()) &&
                 file instanceof JavaFileObject) {
            file = new SmartFileObject((JavaFileObject)file, stdout);
            packageName = ":" + packageNameFromFileName(relativeName);


More information about the compiler-dev mailing list