Package com.isomorphic.scripting

# Class JSEngineManager

java.lang.Object
com.isomorphic.scripting.JSEngineManager

public class JSEngineManager extends Object
Manages JavaScript engine detection and selection for server-side scripting.

This class provides a centralized mechanism for detecting and selecting JavaScript engines with comprehensive logging that appears once per JVM execution. The selection priority is:

1. GraalJS Polyglot mode (preferred - best Java interop and performance)
2. GraalJS via JSR-223 ScriptEngine (fallback if Polyglot Context unavailable)
3. GraalJS with Nashorn compatibility mode
4. V8 via J2V8 (if available)
5. OpenJDK Nashorn (standalone JAR for Java 15+)
6. Oracle Nashorn (built-in, Java 8-14 only)

The detection and selection process is logged once per JVM to avoid duplicate log messages.

Usage Example:

     // Detect available engines (logs once per JVM)
     EngineInfo info = JSEngineManager.detectEngines(getClass().getClassLoader());
     System.out.println("Selected engine: " + info.name + " " + info.version);
     System.out.println("Mode: " + info.mode);  // "polyglot", "jsr223", "v8", or "nashorn"

     // Create an engine using the best available option
     ScriptEngine engine = JSEngineManager.createEngine(getClass().getClassLoader());

See Also:
  - SmartClient Server JavaDoc

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static class`
  `JSEngineManager.EngineInfo`
  Information about an available JavaScript engine.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static ScriptEngine`
  `createEngine(ClassLoader classLoader)`
  Creates a ScriptEngine for the preferred JavaScript engine.
  `static JSEngineManager.EngineInfo`
  `detectEngines(ClassLoader classLoader)`
  Detects available JavaScript engines and logs the results.
  `static JSEngineManager.EngineInfo`
  `getCachedInfo()`
  Gets the cached engine info without triggering detection.
  `static void`
  `resetDetection()`
  Forces re-detection of engines.

- ## Method Details

  - ### detectEngines

    public static JSEngineManager.EngineInfo detectEngines(ClassLoader classLoader)
    Detects available JavaScript engines and logs the results.

    This method is safe to call multiple times; detection and logging only happen once per JVM execution. Subsequent calls return cached results without additional logging.

    Detection checks for engines in the following priority order:

    1. GraalJS Polyglot API (org.graalvm.polyglot.Context)
    2. GraalJS JSR-223 (com.oracle.truffle.js.scriptengine.GraalJSEngineFactory)
    3. V8 via J2V8 (com.eclipsesource.v8.V8)
    4. Nashorn (via ScriptEngineManager)
    Parameters:
      `classLoader` - ClassLoader to use for engine discovery
    Returns:
      EngineInfo describing the selected engine, never null

  - ### createEngine

    public static ScriptEngine createEngine(ClassLoader classLoader)
    Creates a ScriptEngine for the preferred JavaScript engine.

    The engine selection priority is:

    1. GraalJS via Polyglot API (wrapped as ScriptEngine)
    2. GraalJS via JSR-223
    3. Nashorn via JSR-223
    4. Any available "javascript" engine

    The returned ScriptEngine can be used with the standard JSR-223 API:

         ScriptEngine engine = JSEngineManager.createEngine(getClass().getClassLoader());
         engine.eval("var x = 1 + 2;");
         Object result = engine.eval("x");  // returns 3

    Parameters:
      `classLoader` - ClassLoader to use for engine creation
    Returns:
      A ScriptEngine for JavaScript, or null if no engine is available

  - ### resetDetection

    public static void resetDetection()
    Forces re-detection of engines.

    This clears the cached engine info and allows the next call to `detectEngines(ClassLoader)` to perform fresh detection with logging. Useful for testing when JARs are added/removed from the classpath.

  - ### getCachedInfo

    public static JSEngineManager.EngineInfo getCachedInfo()
    Gets the cached engine info without triggering detection.

    Returns the EngineInfo from a previous call to `detectEngines(ClassLoader)`, or null if detection has not yet been performed.

    Returns:
      Cached EngineInfo or null if not yet detected