CLI: compile preloader against JDK 1.6

To be able to detect the Java runtime version at startup to report an
error if it's < 1.8
This commit is contained in:
Alexander Udalov
2017-06-01 00:43:40 +03:00
parent a236400785
commit ea9194e1fb
5 changed files with 30 additions and 28 deletions
+1 -1
View File
@@ -283,7 +283,7 @@
<target name="preloader"> <target name="preloader">
<cleandir dir="${output}/classes/preloader"/> <cleandir dir="${output}/classes/preloader"/>
<javac destdir="${output}/classes/preloader" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false" <javac destdir="${output}/classes/preloader" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false"
source="${java.target}" target="${java.target}"> source="1.6" target="1.6">
<src location="${basedir}/compiler/preloader/src"/> <src location="${basedir}/compiler/preloader/src"/>
</javac> </javac>
+2 -3
View File
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4"> <module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="true">
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="jdk" jdkName="1.6" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>
@@ -57,7 +57,7 @@ public class ClassPreloadingUtils {
} }
private static URLClassLoader createFallbackClassLoader(Collection<File> files) throws IOException { private static URLClassLoader createFallbackClassLoader(Collection<File> files) throws IOException {
List<URL> urls = new ArrayList<>(files.size()); List<URL> urls = new ArrayList<URL>(files.size());
for (File file : files) { for (File file : files) {
urls.add(file.toURI().toURL()); urls.add(file.toURI().toURL());
} }
@@ -76,7 +76,7 @@ public class ClassPreloadingUtils {
return extractManifestClasspath((ResourceData) manifest); return extractManifestClasspath((ResourceData) manifest);
} }
else if (manifest instanceof ArrayList) { else if (manifest instanceof ArrayList) {
List<File> result = new ArrayList<>(); List<File> result = new ArrayList<File>();
for (ResourceData data : (ArrayList<ResourceData>) manifest) { for (ResourceData data : (ArrayList<ResourceData>) manifest) {
result.addAll(extractManifestClasspath(data)); result.addAll(extractManifestClasspath(data));
} }
@@ -93,7 +93,7 @@ public class ClassPreloadingUtils {
String classpathSpaceSeparated = (String) manifest.getMainAttributes().get(Attributes.Name.CLASS_PATH); String classpathSpaceSeparated = (String) manifest.getMainAttributes().get(Attributes.Name.CLASS_PATH);
if (classpathSpaceSeparated == null) return Collections.emptyList(); if (classpathSpaceSeparated == null) return Collections.emptyList();
Collection<File> classpath = new ArrayList<>(1); Collection<File> classpath = new ArrayList<File>(1);
for (String jar : classpathSpaceSeparated.split(" ")) { for (String jar : classpathSpaceSeparated.split(" ")) {
if (".".equals(jar)) continue; if (".".equals(jar)) continue;
@@ -117,7 +117,7 @@ public class ClassPreloadingUtils {
ClassHandler handler ClassHandler handler
) throws IOException { ) throws IOException {
// 0.75 is HashMap.DEFAULT_LOAD_FACTOR // 0.75 is HashMap.DEFAULT_LOAD_FACTOR
Map<String, Object> resources = new HashMap<>((int) (classNumberEstimate / 0.75)); Map<String, Object> resources = new HashMap<String, Object>((int) (classNumberEstimate / 0.75));
for (File jarFile : jarFiles) { for (File jarFile : jarFiles) {
if (handler != null) { if (handler != null) {
@@ -154,7 +154,7 @@ public class ClassPreloadingUtils {
resources.put(name, resourceData); resources.put(name, resourceData);
} }
else if (previous instanceof ResourceData) { else if (previous instanceof ResourceData) {
List<ResourceData> list = new ArrayList<>(); List<ResourceData> list = new ArrayList<ResourceData>();
list.add((ResourceData) previous); list.add((ResourceData) previous);
list.add(resourceData); list.add(resourceData);
resources.put(name, list); resources.put(name, list);
@@ -20,7 +20,6 @@ import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.*; import java.util.*;
@SuppressWarnings("unchecked")
/** /**
* A class loader which loads classes and resources from the given map. * A class loader which loads classes and resources from the given map.
* *
@@ -29,6 +28,7 @@ import java.util.*;
* Therefore if you need to be able to find classes via findResource(), you should pass a fallback * Therefore if you need to be able to find classes via findResource(), you should pass a fallback
* class loader which is able to do that at any point of time. * class loader which is able to do that at any point of time.
*/ */
@SuppressWarnings("unchecked")
public class MemoryBasedClassLoader extends ClassLoader { public class MemoryBasedClassLoader extends ClassLoader {
private final ClassCondition classesToLoadByParent; private final ClassCondition classesToLoadByParent;
private final ClassLoader parent; private final ClassLoader parent;
@@ -140,7 +140,7 @@ public class MemoryBasedClassLoader extends ClassLoader {
Enumeration<URL> fromParent = parent.getResources(name); Enumeration<URL> fromParent = parent.getResources(name);
if (!own.hasMoreElements()) return fromParent; if (!own.hasMoreElements()) return fromParent;
List<URL> result = new ArrayList<>(); List<URL> result = new ArrayList<URL>();
while (own.hasMoreElements()) { while (own.hasMoreElements()) {
result.add(own.nextElement()); result.add(own.nextElement());
} }
@@ -163,7 +163,7 @@ public class MemoryBasedClassLoader extends ClassLoader {
else { else {
assert resources instanceof ArrayList : "Resource map should contain ResourceData or ArrayList<ResourceData>: " + name; assert resources instanceof ArrayList : "Resource map should contain ResourceData or ArrayList<ResourceData>: " + name;
List<ResourceData> resourceDatas = (ArrayList<ResourceData>) resources; List<ResourceData> resourceDatas = (ArrayList<ResourceData>) resources;
List<URL> urls = new ArrayList<>(resourceDatas.size()); List<URL> urls = new ArrayList<URL>(resourceDatas.size());
for (ResourceData data : resourceDatas) { for (ResourceData data : resourceDatas) {
urls.add(data.getURL()); urls.add(data.getURL());
} }
@@ -44,26 +44,29 @@ public class Preloader {
} }
private static void run(String[] args) throws Exception { private static void run(String[] args) throws Exception {
long startTime = System.nanoTime(); final long startTime = System.nanoTime();
Options options = parseOptions(args); final Options options = parseOptions(args);
ClassLoader classLoader = createClassLoader(options); ClassLoader classLoader = createClassLoader(options);
Handler handler = getHandler(options, classLoader); final Handler handler = getHandler(options, classLoader);
ClassLoader preloaded = ClassPreloadingUtils.preloadClasses(options.classpath, options.estimate, classLoader, null, handler); ClassLoader preloaded = ClassPreloadingUtils.preloadClasses(options.classpath, options.estimate, classLoader, null, handler);
Class<?> mainClass = preloaded.loadClass(options.mainClass); Class<?> mainClass = preloaded.loadClass(options.mainClass);
Method mainMethod = mainClass.getMethod("main", String[].class); Method mainMethod = mainClass.getMethod("main", String[].class);
Runtime.getRuntime().addShutdownHook( Runtime.getRuntime().addShutdownHook(
new Thread(() -> { new Thread(new Runnable() {
if (options.measure) { @Override
System.out.println(); public void run() {
System.out.println("=== Preloader's measurements: "); if (options.measure) {
System.out.format("Total time: %.3fs\n", (System.nanoTime() - startTime) / 1e9); System.out.println();
System.out.println("=== Preloader's measurements: ");
System.out.format("Total time: %.3fs\n", (System.nanoTime() - startTime) / 1e9);
}
handler.done();
} }
handler.done();
}) })
); );
@@ -120,10 +123,10 @@ public class Preloader {
private static Options parseOptions(String[] args) throws Exception { private static Options parseOptions(String[] args) throws Exception {
List<File> classpath = Collections.emptyList(); List<File> classpath = Collections.emptyList();
boolean measure = false; boolean measure = false;
List<File> instrumenters = new ArrayList<>(); List<File> instrumenters = new ArrayList<File>();
int estimate = DEFAULT_CLASS_NUMBER_ESTIMATE; int estimate = DEFAULT_CLASS_NUMBER_ESTIMATE;
String mainClass = null; String mainClass = null;
List<String> arguments = new ArrayList<>(); List<String> arguments = new ArrayList<String>();
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
String arg = args[i]; String arg = args[i];
@@ -162,7 +165,7 @@ public class Preloader {
private static List<File> parseClassPath(String classpath) { private static List<File> parseClassPath(String classpath) {
String[] paths = classpath.split(File.pathSeparator); String[] paths = classpath.split(File.pathSeparator);
List<File> files = new ArrayList<>(paths.length); List<File> files = new ArrayList<File>(paths.length);
for (String path : paths) { for (String path : paths) {
File file = new File(path); File file = new File(path);
if (!file.exists()) { if (!file.exists()) {
@@ -176,10 +179,10 @@ public class Preloader {
private static Handler getHandler(Options options, ClassLoader withInstrumenter) { private static Handler getHandler(Options options, ClassLoader withInstrumenter) {
if (!options.measure) return new Handler(); if (!options.measure) return new Handler();
Instrumenter instrumenter = options.instrumenters.isEmpty() ? Instrumenter.DO_NOTHING : loadInstrumenter(withInstrumenter); final Instrumenter instrumenter = options.instrumenters.isEmpty() ? Instrumenter.DO_NOTHING : loadInstrumenter(withInstrumenter);
int[] counter = new int[1]; final int[] counter = new int[1];
int[] size = new int[1]; final int[] size = new int[1];
return new Handler() { return new Handler() {
@Override @Override
public void beforeDefineClass(String name, int sizeInBytes) { public void beforeDefineClass(String name, int sizeInBytes) {