Workaround compilation of Java code using JDK 9 and newer
authorJan Vrany <jan.vrany@fit.cvut.cz>
Thu, 27 Sep 2018 23:16:42 +0100
changeset 3855 bcaceb2ade06
parent 3854 193b04caef42
child 3860 e87f2f1439e9
Workaround compilation of Java code using JDK 9 and newer JDK 9 and newer removed class `sun.misc.Launcher` which is used by `ReflectiveClassLoader` to extract boot class path. In order to make the code at least compilable using `javac` from JRK 9 (and newer), use reflection rather than referencing the class directly. Naturally, this does not mean `stx:libjava` would run using JDK 9 (or newer), merely that it does compile. This makes building Smalltalk/X easier as there's no need to juggle with default `javac` versions or even to install (old) JRK 7 just to *compile* Smalltalk/X. For *running* Java inside Smalltalk/X, you'd still need JDK 7.
tools/java/src/stx/libjava/tools/environment/internal/ReflectiveClassLoader.java
--- a/tools/java/src/stx/libjava/tools/environment/internal/ReflectiveClassLoader.java	Thu Sep 27 23:09:30 2018 +0100
+++ b/tools/java/src/stx/libjava/tools/environment/internal/ReflectiveClassLoader.java	Thu Sep 27 23:16:42 2018 +0100
@@ -17,6 +17,9 @@
 
 import java.io.File;
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
 import java.util.ConcurrentModificationException;
 import java.util.Iterator;
 import java.util.Vector;
@@ -45,7 +48,7 @@
      * safely cached.  
      * 
      */
-    protected static ReflectiveClassLoader PRIMORDIAL = new ReflectiveURLClassLoader(null, sun.misc.Launcher.getBootstrapClassPath().getURLs());
+    protected static ReflectiveClassLoader PRIMORDIAL;
 
     /**
      * Cached {@link Field} to access normally inaccessible field {@link java.lang.ClassLoader#classes}. 
@@ -79,6 +82,29 @@
         } catch (SecurityException e) {
             FIELD_ClassLoader_Classes = null;
         }
+        
+        if (Double.parseDouble(System.getProperty("java.specification.version")) >= 9.0) {
+        	throw new RuntimeException("Java 9 and newer is not yet supported");
+        }
+         
+        try {
+        	Class<?> launcher = Class.forName("sun.misc.Launcher");
+        	Method getBootstrapClassPath = launcher.getMethod("getBootstrapClassPath");
+        	Object classpath = getBootstrapClassPath.invoke(null);
+        	Method getURLs = classpath.getClass().getMethod("getURLs");
+        	URL[] urls = (URL[])getURLs.invoke(classpath);
+        	PRIMORDIAL = new ReflectiveURLClassLoader(null, urls);
+        } catch (ClassNotFoundException e) {
+        	throw new RuntimeException("Cannot determine bootstrap class path", e);
+        } catch (NoSuchMethodException e) {
+        	throw new RuntimeException("Cannot determine bootstrap class path", e);
+		} catch (SecurityException e) {
+			throw new RuntimeException("Cannot determine bootstrap class path", e);
+		} catch (IllegalAccessException e) {
+			throw new RuntimeException("Cannot determine bootstrap class path", e);
+		} catch (InvocationTargetException e) {
+			throw new RuntimeException("Cannot determine bootstrap class path", e);
+		}
     }
         
     /**