Class ExecutionEnvironment
- java.lang.Object
-
- gw.internal.gosu.parser.ExecutionEnvironment
-
- All Implemented Interfaces:
IExecutionEnvironment
public class ExecutionEnvironment extends java.lang.Object implements IExecutionEnvironment
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static classExecutionEnvironment.DefaultSingleModuleRuntimeProject
-
Field Summary
Fields Modifier and Type Field Description private IModule_defaultModuleprivate java.lang.String[]_discretePackagesprivate IModule_jreModuleprivate java.util.List<IModule>_modulesprivate IProject_projectprivate IModule_rootModuleprivate TypeSystemState_statestatic java.lang.StringCLASS_REDEFINER_THREADprivate intcounterDetect whether or not the jdwp agent is alive in this process, if so start a thread that wakes up every N seconds and checks to see if the ReloadClassesIndicator Java class has been redefined by a debugger.private static IProjectDEFAULT_PROJECTprivate static java.util.Map<java.lang.Object,ExecutionEnvironment>INSTANCESprivate static java.util.List<java.lang.String>SPECIAL_CLASSES"Special" java classes that will be used to locate "special" JARs which should be included in the classpath.private static ExecutionEnvironmentTHE_ONE-
Fields inherited from interface gw.lang.reflect.module.IExecutionEnvironment
DEFAULT_SINGLE_MODULE_NAME, GLOBAL_MODULE_NAME
-
-
Constructor Summary
Constructors Modifier Constructor Description privateExecutionEnvironment(IProject project)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidaddModule(IModule module)(package private) voidcheckForDuplicates(java.lang.String moduleName)static java.util.List<IDirectory>createDefaultClassPath()IModulecreateJreModule()private static java.util.List<IDirectory>expand(java.util.List<java.lang.String> paths)IModulefindRootModule()static java.util.Collection<? extends IExecutionEnvironment>getAll()private intgetCounter()java.lang.String[]getDiscretePackages()IModulegetGlobalModule()private static java.util.Set<java.lang.String>getJarsContainingSpecialClasses()This method is a hack to resolve "special" system-like classes provided by execution environment.IModulegetJreModule()IModulegetModule(IResource file)IModulegetModule(java.lang.String strModuleName)IModulegetModule(java.net.URL url)java.util.List<? extends IModule>getModules()IProjectgetProject()TypeSystemStategetState()voidinitializeCompiler(GosucModule gosucModule)voidinitializeDefaultSingleModule(java.util.List<? extends GosuPathEntry> pathEntries, java.util.List<IDirectory> backingSourceEntries, java.lang.String... discretePackages)voidinitializeMultipleModules(java.util.List<? extends IModule> modules)voidinitializeSimpleIde(GosucModule gosucModule)static ExecutionEnvironmentinstance()static ExecutionEnvironmentinstance(IProject project)private booleanisInModule(IModule module, IResource file)booleanisShadowingMode()java.lang.StringmakeGosucProjectFile(java.lang.String projectClassName)private static java.lang.StringremoveAllQuotes(java.lang.String classpath)voidremoveModule(IModule module)voidrenameModule(IModule module, java.lang.String newName)voidsetDiscretePackages(java.lang.String[] discretePackages)voidshutdown()private voidstartSneakyDebugThread()voiduninitializeCompiler()voiduninitializeDefaultSingleModule()voiduninitializeMultipleModules()voiduninitializeSimpleIde()
-
-
-
Field Detail
-
DEFAULT_PROJECT
private static final IProject DEFAULT_PROJECT
-
INSTANCES
private static final java.util.Map<java.lang.Object,ExecutionEnvironment> INSTANCES
-
THE_ONE
private static ExecutionEnvironment THE_ONE
-
CLASS_REDEFINER_THREAD
public static final java.lang.String CLASS_REDEFINER_THREAD
- See Also:
- Constant Field Values
-
SPECIAL_CLASSES
private static final java.util.List<java.lang.String> SPECIAL_CLASSES
"Special" java classes that will be used to locate "special" JARs which should be included in the classpath. This is a replacement to old SPECIAL_FILES variable.
-
_project
private IProject _project
-
_modules
private java.util.List<IModule> _modules
-
_defaultModule
private IModule _defaultModule
-
_jreModule
private IModule _jreModule
-
_rootModule
private IModule _rootModule
-
_discretePackages
private java.lang.String[] _discretePackages
-
_state
private TypeSystemState _state
-
counter
private int counter
Detect whether or not the jdwp agent is alive in this process, if so start a thread that wakes up every N seconds and checks to see if the ReloadClassesIndicator Java class has been redefined by a debugger. If so, it reloads Gosu classes that have changed.Why, you ask? Well since Gosu classes are not compiled to disk, the IDE hosting Gosu can't simply send the bytes in a conventional JDI redefineClasses() call. Yet it somehow needs to at least inform Gosu's type system in the target process that Gosu classes have changed. The JVMTI doesn't offer much help; there's no way to field an arbitrary call from the JDWP client, or for the client to send an arbitrary message. Nor is it possible to leverage the JVMTI's ability to handle method invocation etc. because the target thread must be suspended at a breakpoint, which is not necessarily the case during compilation, and certainly isn't the case for a thread dedicated to fielding such a call. What to do?
We can leverage redefineClasses() after all. The idea is for the IDE compiler to redefine a class (via asm) designated as the "ReloadClassIndicator". This class lives inside Gosu's type system. It has a single method: public static long timestamp() and returns a literal value. If the target process is being debugged (jdwp agent detection), a thread in the target process starts immediately and waits a few seconds before calling the timestamp() method, it does this in a forever loop. If the timestamp value changes, we assume the IDE redefined the class with a new value to indicate classes have changed. In turn we find and reload changed classes. What could be more straight forward?
An alternative approach would be for the IDE to establish an additional line of communication with the target process e.g., socket, memory, whatever. But that is messy (requires config on user's end) and error prone. One debug socket is plenty.
Improvements to this strategy include supplying not only an indication that stuff has changed, but also the names of the classes that have changed. This would releive the target process from having to keep track timestamps on all loaded classes. This could be implemented by having the class return an array of names. An even better improvement would be to include not just the names, but also the source of the classes. This would enable the debuger to modify in memory the classes during a remote debugging session.
-
-
Constructor Detail
-
ExecutionEnvironment
private ExecutionEnvironment(IProject project)
-
-
Method Detail
-
instance
public static ExecutionEnvironment instance()
-
instance
public static ExecutionEnvironment instance(IProject project)
-
getAll
public static java.util.Collection<? extends IExecutionEnvironment> getAll()
-
getProject
public IProject getProject()
- Specified by:
getProjectin interfaceIExecutionEnvironment
-
getModules
public java.util.List<? extends IModule> getModules()
- Specified by:
getModulesin interfaceIExecutionEnvironment
-
initializeDefaultSingleModule
public void initializeDefaultSingleModule(java.util.List<? extends GosuPathEntry> pathEntries, java.util.List<IDirectory> backingSourceEntries, java.lang.String... discretePackages)
-
uninitializeDefaultSingleModule
public void uninitializeDefaultSingleModule()
-
initializeMultipleModules
public void initializeMultipleModules(java.util.List<? extends IModule> modules)
-
uninitializeMultipleModules
public void uninitializeMultipleModules()
-
addModule
public void addModule(IModule module)
- Specified by:
addModulein interfaceIExecutionEnvironment
-
initializeCompiler
public void initializeCompiler(GosucModule gosucModule)
-
uninitializeCompiler
public void uninitializeCompiler()
-
initializeSimpleIde
public void initializeSimpleIde(GosucModule gosucModule)
-
uninitializeSimpleIde
public void uninitializeSimpleIde()
-
checkForDuplicates
void checkForDuplicates(java.lang.String moduleName)
-
getDiscretePackages
public java.lang.String[] getDiscretePackages()
-
setDiscretePackages
public void setDiscretePackages(java.lang.String[] discretePackages)
-
removeModule
public void removeModule(IModule module)
- Specified by:
removeModulein interfaceIExecutionEnvironment
-
getModule
public IModule getModule(java.lang.String strModuleName)
- Specified by:
getModulein interfaceIExecutionEnvironment
-
getModule
public IModule getModule(IResource file)
- Specified by:
getModulein interfaceIExecutionEnvironment
-
getModule
public IModule getModule(java.net.URL url)
- Specified by:
getModulein interfaceIExecutionEnvironment
-
createJreModule
public IModule createJreModule()
- Specified by:
createJreModulein interfaceIExecutionEnvironment
-
getJreModule
public IModule getJreModule()
- Specified by:
getJreModulein interfaceIExecutionEnvironment- Returns:
- The module responsible for resolving JRE core classes e.g., java.lang.* etc. Note in default single module environment this is the single module, otherwise this is the module create by calling createJreModule(). This method will never return null but it will throw an NPE if the JRE module is null.
-
getGlobalModule
public IModule getGlobalModule()
- Specified by:
getGlobalModulein interfaceIExecutionEnvironment
-
findRootModule
public IModule findRootModule()
-
getState
public TypeSystemState getState()
- Specified by:
getStatein interfaceIExecutionEnvironment
-
renameModule
public void renameModule(IModule module, java.lang.String newName)
- Specified by:
renameModulein interfaceIExecutionEnvironment
-
makeGosucProjectFile
public java.lang.String makeGosucProjectFile(java.lang.String projectClassName)
- Specified by:
makeGosucProjectFilein interfaceIExecutionEnvironment
-
shutdown
public void shutdown()
-
getCounter
private int getCounter()
-
startSneakyDebugThread
private void startSneakyDebugThread()
-
createDefaultClassPath
public static java.util.List<IDirectory> createDefaultClassPath()
-
removeAllQuotes
private static java.lang.String removeAllQuotes(java.lang.String classpath)
-
expand
private static java.util.List<IDirectory> expand(java.util.List<java.lang.String> paths)
-
isShadowingMode
public boolean isShadowingMode()
- Specified by:
isShadowingModein interfaceIExecutionEnvironment
-
getJarsContainingSpecialClasses
private static java.util.Set<java.lang.String> getJarsContainingSpecialClasses()
This method is a hack to resolve "special" system-like classes provided by execution environment. This is the replacement of old addSpecialJars() method
-
-