Skip to content

Commit

Permalink
Add minimal JRE version check to Main.runMain
Browse files Browse the repository at this point in the history
Use new constant Main.MINIMAL_JRE_VERSION (currently = 17) and
SourceVersion.latest().ordinal() to check, if the minimal JRE version
requirement for AJC is met. If not, then exit with code -1 and error
message "The AspectJ compiler needs at least Java runtime 17".

Relates to #269.

Signed-off-by: Alexander Kriegisch <[email protected]>
  • Loading branch information
kriegaex committed Dec 15, 2023
1 parent 9b77839 commit 0ba9f25
Showing 1 changed file with 35 additions and 21 deletions.
56 changes: 35 additions & 21 deletions org.aspectj.ajdt.core/src/main/java/org/aspectj/tools/ajc/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import org.aspectj.util.LangUtil;
import org.aspectj.weaver.Dump;

import javax.lang.model.SourceVersion;

/**
* Programmatic and command-line interface to AspectJ compiler. The compiler is an ICommand obtained by reflection. Not thread-safe.
* By default, messages are printed as they are emitted; info messages go to the output stream, and warnings and errors go to the
Expand Down Expand Up @@ -79,6 +81,12 @@ public class Main {

private static final String MESSAGE_HOLDER_OPTION = "-messageHolder";

// Minimal Java runtime version necessary to run AJC
// TODO: Update value, if Eclipse JDT Core raises compilation target level.
private static final int MINIMAL_JRE_VERSION = 17;
private static final String MINIMAL_JRE_VERSION_ERROR =
"The AspectJ compiler needs at least Java runtime " + MINIMAL_JRE_VERSION;

/** @param args the String[] of command-line arguments */
public static void main(String[] args) throws IOException {
new Main().runMain(args, true);
Expand Down Expand Up @@ -218,14 +226,31 @@ public void setCommand(ICommand command) {
}

/**
* Run without throwing exceptions but optionally using System.exit(..). This sets up a message handler which emits messages
* immediately, so report(boolean, IMessageHandler) only reports total number of errors or warnings.
* Run without throwing exceptions, but optionally using {@link System#exit(int)}. This sets up a message handler
* which emits messages immediately, so {@link #report(boolean, IMessageHolder)} only reports the total number of
* errors or warnings.
*
* @param args the String[] command line for the compiler
* @param useSystemExit if true, use System.exit(int) to complete unless one of the args is -noExit. and signal result (0 no
* exceptions/error, &lt;0 exceptions, &gt;0 compiler errors).
* @param args the compiler command line
* @param useSystemExit if true, use {@link System#exit(int)} to complete unless one of the args is {@code -noExit},
* and signal result (0 = no exceptions/error, &lt;0 = exceptions, &gt;0 = compiler errors).
* Note: While some shells like Windows <i>cmd.exe</i> can correctly print negative exit codes
* via {@code echo %errorlevel%"}, UNIX shells like Bash interpret them as positive byte values
* modulo 256. E.g., exit code -1 will be printed as 127 using {@code echo $?}.
*/
public void runMain(String[] args, boolean useSystemExit) {
final boolean doExit = useSystemExit && !flagInArgs("-noExit", args);

// This needs to be checked, before any classes using JDT Core classes are used for the first time. Otherwise, users
// will see ugly UnsupportedClassVersionError stack traces, which they might or might not interpret correctly.
// Therefore, interrupt AJC usage right here, even if it means that not even a usage page can be printed. It is
// better to save users from subsequent problems later.
if (SourceVersion.latest().ordinal() < MINIMAL_JRE_VERSION) {
System.err.println(MINIMAL_JRE_VERSION_ERROR);
if (doExit)
System.exit(-1);
return;
}

// Urk - default no check for AJDT, enabled here for Ant, command-line
AjBuildManager.enableRuntimeVersionCheck(this);
final boolean verbose = flagInArgs("-verbose", args);
Expand Down Expand Up @@ -267,18 +292,8 @@ public void runMain(String[] args, boolean useSystemExit) {
Dump.reset();
}

boolean skipExit = false;
if (useSystemExit && !LangUtil.isEmpty(args)) { // sigh - pluck -noExit
for (String arg : args) {
if ("-noExit".equals(arg)) {
skipExit = true;
break;
}
}
}
if (useSystemExit && !skipExit) {
systemExit(holder);
}
if (doExit)
systemExit();
}

// put calls around run() call above to allowing connecting jconsole
Expand Down Expand Up @@ -453,14 +468,13 @@ public void setCompletionRunner(Runnable runner) {
/**
* Call System.exit(int) with values derived from the number of failures/aborts or errors in messages.
*
* @param messages the IMessageHolder to interrogate.
*/
protected void systemExit(IMessageHolder messages) {
int num = lastFails; // messages.numMessages(IMessage.FAIL, true);
protected void systemExit() {
int num = lastFails;
if (0 < num) {
System.exit(-num);
}
num = lastErrors; // messages.numMessages(IMessage.ERROR, false);
num = lastErrors;
if (0 < num) {
System.exit(num);
}
Expand Down

0 comments on commit 0ba9f25

Please sign in to comment.