Skip to content

Commit

Permalink
Add additional check to ensure Recaf runs with a JDK and not a JRE
Browse files Browse the repository at this point in the history
For now we'll just exit with a special exit code, since we crash anyways.

Longer term we will want to just disable features that rely on the JDK specific code rather than exit. This includes things like:

- Attaching to remote processes (jdk.attach module does not exist in JREs)
- Recompiling (JavacCompiler interface has no implementations)
  • Loading branch information
Col-E committed Oct 24, 2024
1 parent de2138c commit bdcb624
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ public class ExitCodes {
public static final int ERR_FX_UNKNOWN_VERSION = 106;
public static final int INTELLIJ_TERMINATION = 130;
public static final int ERR_CDI_INIT_FAILURE = 150;
public static final int ERR_NOT_A_JDK = 160;

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
import software.coley.recaf.workspace.model.Workspace;
import software.coley.recaf.workspace.model.resource.WorkspaceResource;

import javax.tools.*;
import javax.tools.Diagnostic;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
Expand Down Expand Up @@ -59,8 +63,8 @@ public JavacCompiler(JavacCompilerConfig config) {
*/
@Nonnull
public CompilerResult compile(@Nonnull JavacArguments arguments,
@Nullable Workspace workspace,
@Nullable JavacListener listener) {
@Nullable Workspace workspace,
@Nullable JavacListener listener) {
return compile(arguments, workspace, null, listener);
}

Expand All @@ -79,9 +83,9 @@ public CompilerResult compile(@Nonnull JavacArguments arguments,
*/
@Nonnull
public CompilerResult compile(@Nonnull JavacArguments arguments,
@Nullable Workspace workspace,
@Nullable List<WorkspaceResource> supplementaryResources,
@Nullable JavacListener listener) {
@Nullable Workspace workspace,
@Nullable List<WorkspaceResource> supplementaryResources,
@Nullable JavacListener listener) {
if (compiler == null)
return new CompilerResult(new IllegalStateException("Cannot load 'javac' compiler."));

Expand Down Expand Up @@ -168,7 +172,7 @@ public static int getMinTargetVersion() {
* @return Listener to encompass recording behavior and the user defined listener.
*/
private JavacListener createRecordingListener(@Nullable JavacListener listener,
@Nonnull List<CompilerDiagnostic> diagnostics) {
@Nonnull List<CompilerDiagnostic> diagnostics) {
return new ForwardingListener(listener) {
@Override
public void report(@Nonnull Diagnostic<? extends JavaFileObject> diagnostic) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package software.coley.recaf.util;

import org.slf4j.Logger;
import software.coley.recaf.ExitCodes;
import software.coley.recaf.ExitDebugLoggingHook;
import software.coley.recaf.analytics.logging.Logging;

/**
* JDK vs JRE validation utils.
*
* @author Matt Coley
*/
public class JdkValidation {
private static final Logger logger = Logging.get(JdkValidation.class);

/**
* Applies a few assorted checks to ensure we are running on a JDK and not a JRE.
*/
public static void validateJdk() {
try {
Class.forName("com.sun.tools.attach.VirtualMachine");
} catch (ClassNotFoundException ex) {
logger.error("Recaf must be run with a JDK, but was run with a JRE: " + System.getProperty("java.home"));
ExitDebugLoggingHook.exit(ExitCodes.ERR_NOT_A_JDK);
}
}
}
4 changes: 4 additions & 0 deletions recaf-ui/src/main/java/software/coley/recaf/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import software.coley.recaf.services.workspace.io.ResourceImporter;
import software.coley.recaf.ui.config.WindowScaleConfig;
import software.coley.recaf.util.JFXValidation;
import software.coley.recaf.util.JdkValidation;
import software.coley.recaf.util.Lang;
import software.coley.recaf.workspace.model.BasicWorkspace;

Expand Down Expand Up @@ -80,6 +81,9 @@ public static void main(String[] args) {
}
}

// Validate we're on a JDK and not a JRE
JdkValidation.validateJdk();

// Invoke the bootstrapper, initializing the UI once the container is built.
recaf = Bootstrap.get();
launchArgs = recaf.get(LaunchArguments.class);
Expand Down

0 comments on commit bdcb624

Please sign in to comment.