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()");
! }
! }
!
}