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.
--- 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);
+ }
}
/**