src/jdk.jshell/share/classes/jdk/jshell/spi/ExecutionControl.java

Print this page

        

*** 20,154 **** * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ - package jdk.jshell.spi; ! import java.util.Collection; ! import jdk.jshell.JShellException; /** ! * This interface specifies the functionality that must provided to implement ! * a pluggable JShell execution engine. * <p> ! * The audience for this Service Provider Interface is engineers ! * wishing to implement their own version of the execution engine in support ! * of the JShell API. This is NOT a part of the JShell API. * <p> * A Snippet is compiled into code wrapped in a 'wrapper class'. The execution ! * engine is used by the core JShell implementation to load and, for ! * executable Snippets, execute the Snippet. * <p> * Methods defined in this interface should only be called by the core JShell * implementation. * <p> ! * To install an instance of ExecutionControl, it is passed to ! * {@link jdk.jshell.JShell.Builder#executionEngine(jdk.jshell.spi.ExecutionControl) }. */ public interface ExecutionControl { ! /** ! * Represents the current status of a class in the execution engine. ! */ ! public enum ClassStatus { ! /** ! * Class is not known to the execution engine (not loaded). ! */ ! UNKNOWN, /** ! * Class is loaded, but the loaded/redefined bytes do not match those ! * returned by {@link ExecutionEnv#getClassBytes(java.lang.String) }. */ ! NOT_CURRENT, /** ! * Class is loaded and loaded/redefined bytes match those ! * returned by {@link ExecutionEnv#getClassBytes(java.lang.String) }. */ ! CURRENT ! }; /** ! * Initializes the instance. No methods in this interface can be called ! * before this. * ! * @param env the execution environment information provided by JShell ! * @throws Exception if the instance is unable to initialize */ ! void start(ExecutionEnv env) throws Exception; /** ! * Shuts down this execution engine. Implementation should free all ! * resources held by this execution engine. ! * <p> ! * No calls to methods on this interface should be made after close. */ ! void close(); /** * Adds the path to the execution class path. * * @param path the path to add ! * @return true if successful */ ! boolean addToClasspath(String path); /** ! * Invokes an executable Snippet by calling a method on the specified ! * wrapper class. The method must have no arguments and return String. * ! * @param classname the class whose method should be invoked ! * @param methodname the name of method to invoke ! * @return the result of the execution or null if no result ! * @throws JShellException if a user exception if thrown, ! * {@link jdk.jshell.EvalException EvalException} will be thrown; if an ! * unresolved reference is encountered, ! * {@link jdk.jshell.UnresolvedReferenceException UnresolvedReferenceException} ! * will be thrown */ ! String invoke(String classname, String methodname) throws JShellException; /** ! * Attempts to load new classes. Class bytes are retrieved from ! * {@link ExecutionEnv#getClassBytes(java.lang.String) } * ! * @param classes list of class names to load ! * @return true if load succeeded */ ! boolean load(Collection<String> classes); /** ! * Attempts to redefine previously loaded classes. Class bytes are retrieved ! * from {@link ExecutionEnv#getClassBytes(java.lang.String) } * ! * @param classes list of class names to redefine ! * @return true if redefine succeeded */ ! boolean redefine(Collection<String> classes); /** ! * Queries if the class is loaded and the class bytes are current. ! * ! * @param classname name of the wrapper class to query ! * @return {@code UNKNOWN} if the class is not loaded; {@code CURRENT} if ! * the loaded/redefined bytes are equal to the most recent bytes for this ! * wrapper class; otherwise {@code NOT_CURRENT} */ ! ClassStatus getClassStatus(String classname); /** ! * Interrupt a running invoke. */ ! void stop(); /** ! * Returns the value of a variable. * ! * @param classname the name of the wrapper class of the variable ! * @param varname the name of the variable ! * @return the value of the variable */ ! String varValue(String classname, String varname); } --- 20,293 ---- * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package jdk.jshell.spi; ! import java.io.Serializable; /** ! * This interface specifies the functionality that must provided to implement a ! * pluggable JShell execution engine. * <p> ! * The audience for this Service Provider Interface is engineers wishing to ! * implement their own version of the execution engine in support of the JShell ! * API. * <p> * A Snippet is compiled into code wrapped in a 'wrapper class'. The execution ! * engine is used by the core JShell implementation to load and, for executable ! * Snippets, execute the Snippet. * <p> * Methods defined in this interface should only be called by the core JShell * implementation. * <p> ! * To install an {@code ExecutionControl}, it's {@code Generator} is passed to ! * {@link jdk.jshell.JShell.Builder#executionEngine(ExecutionControl.Generator) }. */ public interface ExecutionControl { ! public interface Generator { ! ExecutionControl generate(ExecutionEnv env) throws Throwable; ! } /** ! * Attempts to load new classes. ! * ! * @param cbcs the class name and bytecodes to load ! * @throws ClassInstallException exception occurred loading the classes, ! * some or all were not loaded ! * @throws NotImplementedException if not implemented ! * @throws EngineTerminationException the execution engine has terminated */ ! void load(ClassBytecodes[] cbcs) ! throws ClassInstallException, NotImplementedException, EngineTerminationException; /** ! * Attempts to redefine previously loaded classes. ! * ! * @param cbcs the class name and bytecodes to redefine ! * @throws ClassInstallException exception occurred redefining the classes, ! * some or all were not redefined ! * @throws NotImplementedException if not implemented ! * @throws EngineTerminationException the execution engine has terminated */ ! void redefine(ClassBytecodes[] cbcs) ! throws ClassInstallException, NotImplementedException, EngineTerminationException; /** ! * Invokes an executable Snippet by calling a method on the specified ! * wrapper class. The method must have no arguments and return String. * ! * @param className the class whose method should be invoked ! * @param methodName the name of method to invoke ! * @return the result of the execution or null if no result ! * @throws UserException the invoke raised a user exception ! * @throws ResolutionException the invoke attempted to directly or ! * indirectly invoke an unresolved snippet ! * @throws StoppedException if the {@code invoke()} was canceled by ! * {@link ExecutionControl#stop} ! * @throws EngineTerminationException the execution engine has terminated ! * @throws InternalException an internal problem occurred */ ! String invoke(String className, String methodName) ! throws RunException, EngineTerminationException, InternalException; /** ! * Returns the value of a variable. ! * ! * @param className the name of the wrapper class of the variable ! * @param varName the name of the variable ! * @return the value of the variable ! * @throws UserException formatting the value raised a user exception ! * @throws ResolutionException formatting the value attempted to directly or ! * indirectly invoke an unresolved snippet ! * @throws StoppedException if the formatting the value was canceled by ! * {@link ExecutionControl#stop} ! * @throws EngineTerminationException the execution engine has terminated ! * @throws InternalException an internal problem occurred */ ! String varValue(String className, String varName) ! throws RunException, EngineTerminationException, InternalException; /** * Adds the path to the execution class path. * * @param path the path to add ! * @throws EngineTerminationException the execution engine has terminated ! * @throws InternalException an internal problem occurred */ ! void addToClasspath(String path) ! throws EngineTerminationException, InternalException; /** ! * Sets the execution class path to the specified path. * ! * @param path the path to add ! * @throws EngineTerminationException the execution engine has terminated ! * @throws InternalException an internal problem occurred */ ! void setClasspath(String path) ! throws EngineTerminationException, InternalException; /** ! * Interrupts a running invoke. * ! * @throws EngineTerminationException the execution engine has terminated ! * @throws InternalException an internal problem occurred */ ! void stop() ! throws EngineTerminationException, InternalException; /** ! * Run a non-standard command (or a standard command from a newer version). * ! * @param command the non-standard command ! * @param arg the commands argument ! * @return the commands return value ! * @throws UserException the command raised a user exception ! * @throws ResolutionException the command attempted to directly or ! * indirectly invoke an unresolved snippet ! * @throws StoppedException if the command was canceled by ! * {@link ExecutionControl#stop} ! * @throws EngineTerminationException the execution engine has terminated ! * @throws NotImplementedException if not implemented ! * @throws InternalException an internal problem occurred */ ! Object extensionCommand(String command, Object arg) ! throws RunException, EngineTerminationException, InternalException; /** ! * Shuts down this execution engine. Implementation should free all ! * resources held by this execution engine. ! * <p> ! * No calls to methods on this interface should be made after close. */ ! void close(); ! ! public static final class ClassBytecodes implements Serializable { ! ! private static final long serialVersionUID = 1L; ! ! public ClassBytecodes(String name, byte[] bytecodes) { ! this.name = name; ! this.bytecodes = bytecodes; ! } ! public final String name; ! public final byte[] bytecodes; ! } ! ! @SuppressWarnings("serial") ! public static abstract class ExecutionControlException extends Exception { ! ! public ExecutionControlException(String message) { ! super(message); ! } ! } ! ! /** ! * Unbidden execution engine termination has occurred. ! */ ! @SuppressWarnings("serial") ! public static class EngineTerminationException extends ExecutionControlException { ! ! public EngineTerminationException(String message) { ! super(message); ! } ! } ! ! @SuppressWarnings("serial") ! public static class NotImplementedException extends InternalException { ! ! public NotImplementedException(String message) { ! super(message); ! } ! } ! ! @SuppressWarnings("serial") ! public static class InternalException extends ExecutionControlException { ! ! public InternalException(String message) { ! super(message); ! } ! } ! ! @SuppressWarnings("serial") ! public static class ClassInstallException extends ExecutionControlException { ! ! private final boolean[] installed; ! ! public ClassInstallException(String message, boolean[] installed) { ! super(message); ! this.installed = installed; ! } ! ! public boolean[] installed() { ! return installed; ! } ! } ! ! @SuppressWarnings("serial") // serialVersionUID intentionally omitted ! public static abstract class RunException extends ExecutionControlException { ! ! private RunException(String message) { ! super(message); ! } ! } ! ! @SuppressWarnings("serial") // serialVersionUID intentionally omitted ! public static class UserException extends RunException { ! ! private final String causeExceptionClass; ! ! public UserException(String message, String causeExceptionClass, StackTraceElement[] stackElements) { ! super(message); ! this.causeExceptionClass = causeExceptionClass; ! this.setStackTrace(stackElements); ! } ! ! public String causeExceptionClass() { ! return causeExceptionClass; ! } ! } ! ! @SuppressWarnings("serial") // serialVersionUID intentionally omitted ! public static class ResolutionException extends RunException { ! ! private final int id; /** ! * Constructs an exception indicating that a ! * {@code DeclarationSnippet} with unresolved references has been ! * encountered. The throw of this exception is generated into the body ! * of a ! * {@link jdk.jshell.Snippet.Status#RECOVERABLE_DEFINED RECOVERABLE_DEFINED} ! * method. ! * ! * @param id An internal identifier of the specific method ! * @param stackElements the stack trace */ ! public ResolutionException(int id, StackTraceElement[] stackElements) { ! super("resolution exception: " + id); ! this.id = id; ! this.setStackTrace(stackElements); ! } /** ! * Retrieves the internal identifier of the unresolved identifier. * ! * @return the internal identifier */ ! public int id() { ! return id; ! } ! } ! ! @SuppressWarnings("serial") // serialVersionUID intentionally omitted ! public static class StoppedException extends RunException { ! ! public StoppedException() { ! super("stopped by stop()"); ! } ! } ! }