8306112: Implementation of JEP 445: Unnamed Classes and Instance Main Methods (Preview)

8308613: javax.lang.model updates for JEP 445 (preview)
8308913: Update core reflection for JEP 445 (preview)

Co-authored-by: Maurizio Cimadamore <mcimadamore@openjdk.org>
Co-authored-by: Joe Darcy <darcy@openjdk.org>
Co-authored-by: Jan Lahoda <jlahoda@openjdk.org>
Co-authored-by: Jim Laskey <jlaskey@openjdk.org>
Co-authored-by: Adam Sotona <asotona@openjdk.org>
Reviewed-by: mcimadamore, vromero, darcy
This commit is contained in:
Jim Laskey 2023-06-05 18:45:39 +00:00
parent e970ddbc60
commit 98b53c06cf
40 changed files with 1654 additions and 176 deletions

View file

@ -48,6 +48,7 @@ import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.lang.module.ResolvedModule;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
@ -78,6 +79,8 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.internal.util.OperatingSystem;
import jdk.internal.misc.MainMethodFinder;
import jdk.internal.misc.PreviewFeatures;
import jdk.internal.misc.VM;
import jdk.internal.module.ModuleBootstrap;
import jdk.internal.module.Modules;
@ -843,11 +846,32 @@ public final class LauncherHelper {
return false;
}
/*
* main type flags
*/
private static final int MAIN_WITHOUT_ARGS = 1;
private static final int MAIN_NONSTATIC = 2;
private static int mainType = 0;
/*
* Return type so that launcher invokes the correct main
*/
public static int getMainType() {
return mainType;
}
private static void setMainType(Method mainMethod) {
int mods = mainMethod.getModifiers();
boolean isStatic = Modifier.isStatic(mods);
boolean noArgs = mainMethod.getParameterCount() == 0;
mainType = (isStatic ? 0 : MAIN_NONSTATIC) | (noArgs ? MAIN_WITHOUT_ARGS : 0);
}
// Check the existence and signature of main and abort if incorrect
static void validateMainClass(Class<?> mainClass) {
Method mainMethod = null;
try {
mainMethod = mainClass.getMethod("main", String[].class);
mainMethod = MainMethodFinder.findMainMethod(mainClass);
} catch (NoSuchMethodException nsme) {
// invalid main or not FX application, abort with an error
abort(null, "java.launcher.cls.error4", mainClass.getName(),
@ -863,16 +887,42 @@ public final class LauncherHelper {
}
}
setMainType(mainMethod);
/*
* getMethod (above) will choose the correct method, based
* findMainMethod (above) will choose the correct method, based
* on its name and parameter type, however, we still have to
* ensure that the method is static and returns a void.
* ensure that the method is static (non-preview) and returns a void.
*/
int mod = mainMethod.getModifiers();
if (!Modifier.isStatic(mod)) {
abort(null, "java.launcher.cls.error2", "static",
mainMethod.getDeclaringClass().getName());
int mods = mainMethod.getModifiers();
boolean isStatic = Modifier.isStatic(mods);
boolean isPublic = Modifier.isPublic(mods);
boolean noArgs = mainMethod.getParameterCount() == 0;
if (!PreviewFeatures.isEnabled()) {
if (!isStatic || !isPublic || noArgs) {
abort(null, "java.launcher.cls.error2", "static",
mainMethod.getDeclaringClass().getName());
}
}
if (!isStatic) {
if (mainClass.isMemberClass() && !Modifier.isStatic(mainClass.getModifiers())) {
abort(null, "java.launcher.cls.error9",
mainMethod.getDeclaringClass().getName());
}
try {
Constructor<?> constructor = mainClass.getDeclaredConstructor();
if (Modifier.isPrivate(constructor.getModifiers())) {
abort(null, "java.launcher.cls.error8",
mainMethod.getDeclaringClass().getName());
}
} catch (Throwable ex) {
abort(null, "java.launcher.cls.error8",
mainMethod.getDeclaringClass().getName());
}
}
if (mainMethod.getReturnType() != java.lang.Void.TYPE) {
abort(null, "java.launcher.cls.error3",
mainMethod.getDeclaringClass().getName());

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -236,6 +236,13 @@ java.launcher.cls.error6=\
java.launcher.cls.error7=\
Error: Unable to initialize main class {0}\n\
Caused by: {1}: {2}
java.launcher.cls.error8=\
Error: no non-private zero argument constructor found in class {0}\n\
remove private from existing constructor or define as:\n\
\ public {0}()
java.launcher.cls.error9=\
Error: non-static inner class {0} constructor can not be invoked \n\
make inner class static or move inner class out to separate source file
java.launcher.jar.error1=\
Error: An unexpected error occurred while trying to open file {0}
java.launcher.jar.error2=manifest not found in {0}