Package jetbrains.mps.classloading
Class ClassLoaderManager
- java.lang.Object
 - 
- jetbrains.mps.classloading.ClassLoaderManager
 
 
- 
- All Implemented Interfaces:
 CoreComponent
public class ClassLoaderManager extends Object implements CoreComponent
A ClassLoaderManager is a singleton and provides an internal API for loading classes within MPS. NOTE: External API is placed inReloadableModuleinterface. Using the methods of this class is not recommended. In order to get Class from a module callgetClass(org.jetbrains.mps.openapi.module.SModule, java.lang.String)method.- See Also:
 General information: A MPS java module is loadable iff it is possible to associate some ClassLoader with it. Currently there are two types of loadable modules: 1. Reloadable modules are modules which ClassLoader maybe redeployed on-the-fly,ReloadableModule,Presently the associated ClassLoader for these modules is . ClassLoaderManager stores a map of this ClassLoader instances, reloads them if needed, delegates class requests to them. 2. Non-reloadable modules are not reloadable modules. Currently such modules are bundled with Idea plugin, the associated ClassLoader for these modules is the result of the method call. CLManager delegates Class/ClassLoader requests to Idea plugin [for these modules]. Common part CLManager listens to newly added loadable modules (into the repository) and to modules' removal. When module is added, CLManager marks it as () and broadcasts the event to clients. When module's classes (or ClassLoader) are requested, the actual module load happens. When module is removed from the repository, CLManager unloaded module's data from its' storage.,for more information on module's loading progress and module's lifecycle Every module add/remove/reload triggers events dispatching to MPSClassesListeners,Also CLManager tracks the validity of the repository modules. The invariant condition is that a module can not be (class) loaded if any of its dependencies is absent in the repository. That means that for an invalid module CLManager will return null for all Class/ClassLoader requests (#getClass, #getClassLoader),ModulesWatcher,ModulesWatcher.ClassLoadingStatus,Reloadable part Any reloadable module M has a class loading lifecycle like this: # module M is added to the repository [no ModuleClassLoader created] # someone reloads M or asks for the classloader of M - initializing ModuleClassLoader creation for M (lazy load) [ModuleClassLoader is constructed] # more M reloads and class requests # module M is removed from the repository - ModuleClassLoader gets disposed. [ModuleClassLoader removed] Reload may be triggered by a client explicitly with . [**] Notice that it is a very uncommon case when you might need an explicit reload. Currently a module's reload happens automatically on module's changes (some specific changes, details below).,for details CLManager exploits a lazy mechanism of module's reloading. It stacks all module events, and occasionally refresh happens: CLM flushes them and processes all the accumulated events. When CLManager refreshes its state becomes actual. [in the sense of information about modules', their class loading status and their ClassLoader's] The state IS guaranteed to be actual at these points: 1. Right after the end of write action [CLManager has a ] 2. In the middle of write action if a Class or ClassLoader was requested []. Only write action holder is able to provoke refresh [!] 3. Explicit reload: a call of reload methods [, ].,documentation for more details on pt. 2,Repository lock policy Every reload requires a repository write lock. Actual ModuleClassLoader construction happens inside the read action,,FIXME logic here must be rewritten in a more abstract way to allow both lazy and non-lazy implementations FIXME the module dependecy tracking must be isolated from the class loading logic TODO the workflow between ModuleEventsHandler, ClassLoaderManager and ModulesWatcher is too complicated and impossible to perceive, it needs to be done over again TODO As for 23.01.19 the refactoring is planned for the 192 version, where the reloadable modules will be equipped with persisted cp. TODO Effectively it will remove all the repository locks from cl and will simplify it a lot since there wil be no performance problem anymore
 
- 
- 
Constructor Summary
Constructors Constructor Description ClassLoaderManager(SRepository repository) 
- 
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description voidaddListener(DeployListener listener)voiddispose()Class<?>getClass(SModule module, String classFqName)Deprecated.use module-specific methods which throw different ClassNotFoundExceptions, you need to process it on your own (probably show some user notification)MPSModuleClassLoadergetClassLoader(SModule module)static ClassLoaderManagergetInstance()Deprecated.Class<?>getOwnClass(SModule module, String classFqName)Deprecated.use module-specific methods which throw different ClassNotFoundExceptions, you need to process it by yourself (probably show some user notification)ReloadableModule.DeploymentStatusgetStatus(ReloadableModule module)voidinit()booleanisLoadedByMPS(ReloadableModule module)voidreloadAll(ProgressMonitor monitor)Deprecated.voidreloadModule(SModule module)voidreloadModules(Iterable<? extends SModule> modules)voidreloadModules(Iterable<? extends SModule> modules, ProgressMonitor monitor)Use this method to invalidate modules (namely, recreate their class loaders) There are also usefulreloadModules(Iterable)andreloadModule(SModule).voidremoveListener(DeployListener listener)voidrunNonReloadableTransaction(Runnable runnable)Deprecated. 
 - 
 
- 
- 
Constructor Detail
- 
ClassLoaderManager
public ClassLoaderManager(@NotNull SRepository repository)
 
 - 
 
- 
Method Detail
- 
getInstance
@Deprecated public static ClassLoaderManager getInstance()
Deprecated. 
- 
init
public void init()
- Specified by:
 initin interfaceCoreComponent
 
- 
dispose
public void dispose()
- Specified by:
 disposein interfaceCoreComponent
 
- 
getClass
@Deprecated @Nullable public Class<?> getClass(@NotNull SModule module, String classFqName)
Deprecated.use module-specific methods which throw different ClassNotFoundExceptions, you need to process it on your own (probably show some user notification)TODO refactor all usages of getClass() Contract: @param module must be loadable (myLoadableConditionSo if method returns true and the class file is in place you will get the class 
- 
getOwnClass
@Deprecated @Nullable public Class<?> getOwnClass(@NotNull SModule module, String classFqName)
Deprecated.use module-specific methods which throw different ClassNotFoundExceptions, you need to process it by yourself (probably show some user notification)TODO refactor all usages of getOwnClass()- See Also:
 ReloadableModule,ModuleIsNotLoadableException
 
- 
getClassLoader
@NotNull public MPSModuleClassLoader getClassLoader(SModule module)
- Returns:
 - the class loader associated with the module. Note that sometimes it may return "outdated" ClassLoader. To be exact it returns the classloader for module, which was actual for the moment of last refresh event.
 - See Also:
 Refresh happens at these points: 1. At the end of write action, 2. During #getClassLoader calls inside the write action, 3. Also it may be triggered explicitly by #reloadModules(), #reloadModule(), etc. call. This method can return the class loader of the IDEA plugin which manages the module's classes. Use it if you want to get a class from the module with IdeaPluginFacet. INTERNAL USE ONLY: use module-specific methods which throw ClassNotFoundException, you need to process it by yourself (probably show some user notification),ModuleIsNotLoadableException,ReloadableModule
 
- 
runNonReloadableTransaction
@Deprecated public void runNonReloadableTransaction(Runnable runnable)
Deprecated.hack for 3.4 
- 
addListener
public void addListener(@NotNull DeployListener listener)
 
- 
removeListener
public void removeListener(@NotNull DeployListener listener)
 
- 
reloadModules
public void reloadModules(Iterable<? extends SModule> modules, @NotNull ProgressMonitor monitor)
Use this method to invalidate modules (namely, recreate their class loaders) There are also usefulreloadModules(Iterable)andreloadModule(SModule). TODO: add listening to class files updating and remove explicit call from ModuleMaker and the others FIXME: remove TempModule: it should not be processed by CLManager. It maintains only repository modules! 
- 
reloadModule
public void reloadModule(SModule module)
- See Also:
 ReloadableModule
 
- 
reloadAll
public void reloadAll(@NotNull ProgressMonitor monitor)
Deprecated.Note: usually reloading only the "dirty" modules is enough. Please take a look atreloadModule(org.jetbrains.mps.openapi.module.SModule)andreloadModules(java.lang.Iterable<? extends org.jetbrains.mps.openapi.module.SModule>, org.jetbrains.mps.openapi.util.ProgressMonitor)methods. 
- 
getStatus
@NotNull public ReloadableModule.DeploymentStatus getStatus(@NotNull ReloadableModule module)
 
- 
isLoadedByMPS
public boolean isLoadedByMPS(@NotNull ReloadableModule module)
 
 - 
 
 -