Interface Integration


public interface Integration

Provides hooks for integrating JRebel with custom containers, frameworks and classloaders. To use it acquire an instance from IntegrationFactory

A typical (classloader) integration will look like this:

 class MyClassLoader extends URLClassLoader {
   public MyClassLoader() {
     ...
     IntegrationFactory.getInstance().registerClassLoader(
      this,
      new FindResourceClassResourceSource(this)));
   }
   ...
   public Class findClass(String classname) {
     synchronized(classloader) {
       Class result =
         classloader.findLoadedClass(classname);
       if (result != null)
         return result;
         
       result = 
         IntegrationFactory.getInstance()
           .findReloadableClass(this, classname);
       if (result != null)
         return result;
     }
      ...
   }   
 }
 

You can use the addIntegrationProcessor(String, ClassBytecodeProcessor) and addIntegrationProcessor(String[], ClassBytecodeProcessor) instrument specific classes to enhance their behaviour with JRebel.

Author:
Jevgeni Kabanov
See Also:
  • Method Details

    • registerClassLoader

      void registerClassLoader(ClassLoader cl, ClassResourceSource cfs)
      Registers a ClassLoader with JRebel associating with it the class-to-file resolution strategy provided by ClassResourceSource. It is necessary to do this before any calls to findReloadableClass(ClassLoader, String), the best place is usually the constructor.
      Parameters:
      cl - The custom class loader being integrated.
      cfs - The class-to-file resolution strategy source.
      See Also:
    • reinitializeClassLoader

      void reinitializeClassLoader(ClassLoader cl)
      Reinitializes the ClassLoader with JRebel.

      This should be called if the class path of the given ClassLoader was updated.

      Parameters:
      cl - The custom class loader being integrated.
    • unregisterClassLoader

      void unregisterClassLoader(ClassLoader cl)
      Unregisters the ClassLoader from JRebel. It is recommended to do this in case the corresponding ClassLoader is destroyed (e.g. the web application is undeployed).
      Parameters:
      cl - The custom class loader being integrated.
    • isRegisteredClassLoader

      boolean isRegisteredClassLoader(ClassLoader cl)
      Says if this ClassLoader is registerd with JRebel.
      Parameters:
      cl - The custom class loader being integrated.
      Returns:
      true if this ClassLoader is registerd with JRebel.
    • getRebelURLs

      URL[] getRebelURLs(ClassLoader cl)
      Returns the additional class path of the given ClassLoader managed by JRebel.

      Same as getRebelURLs(cl, false).

      Parameters:
      cl - The custom class loader being integrated.
      Returns:
      additional class path of the given ClassLoader or null if nothing found.
    • getRebelURLs

      URL[] getRebelURLs(ClassLoader cl, boolean onlyFullMatch)
      Returns the additional class path of the given ClassLoader managed by JRebel.
      Parameters:
      cl - The custom class loader being integrated.
      onlyFullMatch - whether to only return locations with no custom patterns.
      Returns:
      additional class path of the given ClassLoader or null if nothing found.
    • getRebelSources

      RebelSource[] getRebelSources(ClassLoader cl)
      Returns the additional class path of the given ClassLoader managed by JRebel.
      Parameters:
      cl - The custom class loader being integrated.
      Returns:
      additional class path of the given ClassLoader or null if nothing found.
    • getScanHelper

      ScanHelper getScanHelper(ClassLoader cl, String name)
      Returns helper object to perform class path scanning in the given ClassLoader. NOTE: this api is experimental and may be removed or changed in future versions.
      Parameters:
      cl - The class loader used to find resources to scan.
      name - name of resource to start scanning from.
      Returns:
      helper for class path scanning or null if not available.
    • findReloadableClass

      Class<?> findReloadableClass(ClassLoader cl, String className) throws ClassNotFoundException
      Resolves classes managed by JRebel. These and only these classes will be reloadable. Returns null if class couldn't be resolved and the non-JRebel class loading should be used as fail-over. Throws ClassNotFoundException if class does not exist and the non-JRebel class loading should be skipped.
      Parameters:
      cl - The custom class loader being integrated.
      className - The public class name.
      Returns:
      Resolved class or null.
      Throws:
      ClassNotFoundException - if class does not exist.
      See Also:
    • defineReloadableClass

      Class<?> defineReloadableClass(ClassLoader cl, String className, Resource mutableResource, ProtectionDomain protectionDomain, boolean processedByLoader)
      (Re)defines a class managed by JRebel. When the class is reloaded, the Resource provided here is used to get the new bytes. This can be used to re-generate the bytes for a proxy class after a reload. Returns null if this class loader is not registered with JRebel.
      Parameters:
      cl - The custom class loader being integrated.
      className - The public class name.
      mutableResource - bytes for the class.
      protectionDomain - The ProtectionDomain of the class (may be null).
      processedByLoader - Whether given bytes should be processed by class loader in the same way as a normally loaded classes. Set to false when class is supposed to be define similarly to reflectively calling ClassLoader.defineClass that bypasses logic inside defining loader.
      Returns:
      (Re)defined class or null.
      Since:
      18.2.5
    • defineReloadableClass

      Class<?> defineReloadableClass(ClassLoader cl, String className, byte[] bytecode, ProtectionDomain protectionDomain, boolean processedByLoader)
      (Re)defines a class managed by JRebel.

      This method may be called for loading as well as reloading the class.

      This method is intended to replace defineClass, e.g. used from the same context as defineClass is currently used. So in normal java ClassLoader the caller of defineClass should already be synchronized and we should not do it inside defineReloadableClass in order to avoid creating extra deadlocks.

      The defined class will only be reloaded if this method is called again. Even if the class was first loaded by findReloadableClass(ClassLoader, String) the resolved class resource will not be checked for updates.

      Returns null if this class loader is not registered with JRebel.
      Parameters:
      cl - The custom class loader being integrated.
      className - The public class name.
      bytecode - class bytes.
      protectionDomain - The ProtectionDomain of the class (may be null).
      processedByLoader - Whether given bytes should be processed by class loader in the same way as a normally loaded classes. Set to false when class is supposed to be define similarly to reflectively calling ClassLoader.defineClass that bypasses logic inside defining loader.
      Returns:
      (Re)defined class or null.
      Since:
      7.0.1
    • defineReloadableClass

      Class<?> defineReloadableClass(ClassLoader cl, String className, byte[] bytecode, ProtectionDomain protectionDomain)
      Same as defineReloadableClass(cl, className, bytecode, protectionDomain, true)
      Parameters:
      cl - The custom class loader being integrated.
      className - The public class name.
      bytecode - class bytes.
      protectionDomain - The ProtectionDomain of the class (may be null).
      Returns:
      true if the class was managed by JRebel and redefined.
      Since:
      3.0
    • redefineReloadableClass

      boolean redefineReloadableClass(Class<?> klass, byte[] bytecode, boolean processedByLoader)
      Redefines a class managed by JRebel.
      Parameters:
      klass - Class managed by JRebel.
      bytecode - class bytes.
      processedByLoader - Whether given bytes should be processed by class loader in the same way as a normally loaded classes. Set to false when class is supposed to be define similarly to reflectively calling ClassLoader.defineClass that bypasses logic inside defining loader.
      Returns:
      true if the class was managed by JRebel and redefined.
      Since:
      7.0.1
    • redefineReloadableClass

      boolean redefineReloadableClass(Class<?> klass, byte[] bytecode)
      Same as redefineReloadableClass(klass, bytecode, true)
      Parameters:
      klass - Class managed by JRebel.
      bytecode - class bytes.
      Returns:
      true if the class was managed by JRebel and redefined.
      Since:
      3.0
    • redefineReloadableHiddenClass

      Class<?> redefineReloadableHiddenClass(Class<?> klass, byte[] bytecode)
      Redefines a hidden class managed by JRebel.
      Parameters:
      klass - hidden class managed by JRebel.
      bytecode - class bytes.
      Returns:
      the redefined hidden class.
      Since:
      2022.1.2
    • redefineClasses

      void redefineClasses(ClassDefinition... classDefinitions)
      Redefine a set of classes managed by JRebel.
      Parameters:
      classDefinitions - Array of ClassDefinition objects containing the Class and new class-bytes
    • isResourceReplaced

      boolean isResourceReplaced(ClassLoader cl, String name)
      Returns true if the given resource is managed by JRebel.

      In that case resources can be resolved using the corresponding methods of the Integration. If any of these methods returns a null it must be returned by the ClassLoader as well.

      Parameters:
      cl - The custom class loader being integrated.
      name - The public resource name.
      Returns:
      true if the given resource is managed by JRebel.
    • findResource

      URL findResource(ClassLoader cl, String name)
      Resolves resources managed by JRebel.
      Parameters:
      cl - The custom class loader being integrated.
      name - The public resource name.
      Returns:
      Resolved resource URL or null.
    • findRebelResource

      URL findRebelResource(ClassLoader cl, String name)
      Resolves resources only managed by JRebel.
      Parameters:
      cl - The custom class loader being integrated.
      name - The public resource name.
      Returns:
      Resolved resource URL or null.
    • findResources

      Enumeration<URL> findResources(ClassLoader cl, String name)
      Resolves resources managed by JRebel.
      Parameters:
      cl - The custom class loader being integrated.
      name - The public resource name.
      Returns:
      Resolved resource URLs or null.
    • findRebelResources

      Enumeration<URL> findRebelResources(ClassLoader cl, String name)
      Resolves resources only managed by JRebel.
      Parameters:
      cl - The custom class loader being integrated.
      name - The public resource name.
      Returns:
      Resolved resource URLs or null.
    • getTransparentResources

      Enumeration<URL> getTransparentResources(ClassLoader cl, String name)
      Returns the original resources with given name. This is used to get the original result unaltered by JRebel.
      Parameters:
      cl - The custom class loader being integrated.
      name - The resource name.
      Returns:
      Resolved resource URLs or null.
    • getTransparentResource

      URL getTransparentResource(ClassLoader cl, String name)
      Returns the original resource with given name. This is used to get the original result unaltered by JRebel.
      Parameters:
      cl - The custom class loader being integrated.
      name - The resource name.
      Returns:
      Resolved resource URL or null.
    • recordClassResource

      void recordClassResource(ClassLoader cl, String className, URL url)
      Record location of found class. This method may be used to improve cache hit ration for overhead resource requests in class loaders whose findClass does not call findResource.
      Parameters:
      cl - The custom class loader being integrated.
      className - The public class name.
      url - URL of class resource.
      Since:
      4.6
    • recordClassResource

      void recordClassResource(ClassLoader cl, String className, URL url, byte[] bytes)
    • useSeparateCacheForClassesAndResources

      void useSeparateCacheForClassesAndResources(ClassLoader cl)
      Cache results for class and resource request separately. Use when the result of resource lookup as returned by findResource may be different from what is recorded with recordClassResource.
      Parameters:
      cl - The custom class loader being integrated.
    • addIntegrationProcessor

      void addIntegrationProcessor(ClassLoader cl, String className, ClassBytecodeProcessor processor)
      Adds a bytecode processor for the given class in the given classloader. It will be run before that class is loaded and is mainly use to enable integration with a specific framework or classloader. Allows to additionally restrict the bytecode processing to the given classloader.
      Parameters:
      cl - the ClassLoader for the class
      className - the target class by name
      processor - the processor to add
    • addIntegrationProcessor

      void addIntegrationProcessor(String className, ClassBytecodeProcessor processor)
      Adds a bytecode processor for the given class. It will be run before that class is loaded and is mainly use to enable integration with a specific framework or classloader.
      Parameters:
      className - the target class by name
      processor - the processor to add
    • addIntegrationProcessor

      void addIntegrationProcessor(ClassLoader cl, ClassBytecodeProcessor processor)
      Adds a bytecode processor for the given classloader. It will be run before that class is loaded and is mainly use to enable integration with a specific framework or classloader. Allows to additionally restrict the bytecode processing to the given classloader.
      Parameters:
      cl - the ClassLoader for the classes
      processor - the processor to add
    • addIntegrationProcessor

      void addIntegrationProcessor(ClassBytecodeProcessor processor, boolean managedOnly)
      Adds a bytecode processor for all classes. It will be run before that class is loaded and is mainly used for integration with preprocessors like AspectJ.

      If managedOnly is true the processor will only be run for the classes managed by JRebel. This is useful to enable processing usually done in the class loader findClass() method, e.g. the JBoss AOP.

      Parameters:
      processor - the processor to add
      managedOnly - should we only run it on reloadable classes
    • addIntegrationProcessor

      void addIntegrationProcessor(ClassLoader cl, ClassBytecodeProcessor processor, boolean managedOnly)
      AAdds a bytecode processor for the given classloader. It will be run before that class is loaded and is mainly used for integration with preprocessors like AspectJ.

      If managedOnly is true the processor will only be run for the classes managed by JRebel. This is useful to enable processing usually done in the class loader findClass() method, e.g. the JBoss AOP.

      Parameters:
      cl - the ClassLoader for the classes
      processor - the processor to add
      managedOnly - should we only run it on reloadable classes
    • addIntegrationProcessor

      void addIntegrationProcessor(String[] classNames, ClassBytecodeProcessor processor)
      Adds a bytecode processor for the set of given classes. It will be run before those classes are loaded and is mainly use to enable integration with a specific framework or classloader.
      Parameters:
      classNames - the class to associate the processor with
      processor - the processor to add
      See Also:
    • addIntegrationProcessor

      void addIntegrationProcessor(ClassLoader cl, String[] classNames, ClassBytecodeProcessor processor)
      Adds a bytecode processor for the set of given classes in the given classloader. It will be run before those classes are loaded and is mainly use to enable integration with a specific framework or classloader. Allows to additionally restrict the bytecode processing to the given classloader.
      Parameters:
      cl - the ClassLoader for the classes
      classNames - the class to associate the processor with
      processor - the processor to add
      See Also:
    • removeIntegrationProcessor

      void removeIntegrationProcessor(ClassBytecodeProcessor processor)
      Remove bytecode processor.
      Parameters:
      processor - the processor to remove
    • removeIntegrationProcessors

      void removeIntegrationProcessors(ClassLoader cl)
      Remove bytecode processors that are loaded by the ClassLoader
      Parameters:
      cl - the ClassLoader to remove all processors from
    • addBootClassProcessor

      void addBootClassProcessor(String className, ClassBytecodeProcessor processor)
      Adds a bytecode processor for the given class in boot classloader. It will be run before that class is loaded and is mainly use to enable integration with a specific framework or classloader.
      Parameters:
      className - the class to associate the processor with
      processor - the processor to add
    • addBootClassProcessor

      void addBootClassProcessor(String[] classNames, ClassBytecodeProcessor processor)
      Adds a bytecode processor for set of given classes in boot classloader. It will be run before that class is loaded and is mainly use to enable integration with a specific framework or classloader.
      Parameters:
      classNames - the classes to associate the processor with
      processor - the processor to add
      See Also:
    • addBootClassProcessor

      void addBootClassProcessor(ClassBytecodeProcessor classBytecodeProcessor)
      Adds a bytecode processor in boot classloader. It is mainly use to enable integration with a specific framework or classloader. This API is only available when JRebel is configured as java agent.
      Parameters:
      classBytecodeProcessor - the processor to add
    • reportError

      void reportError(Throwable e, String version, String jarFile)
      Report CBP failure, implementation must be async.
      Parameters:
      e - the error to report
      version - version
      jarFile - location
    • addClassLoaderDestructionListener

      void addClassLoaderDestructionListener(ClassLoader cl, ClassLoaderDestructionListener listener)
      Registers a call back invoked when a given class loader is being destroyed.
      Parameters:
      cl - The custom class loader being integrated.
      listener - class loader destruction listener.
    • removeClassLoaderDestructionListener

      void removeClassLoaderDestructionListener(ClassLoaderDestructionListener listener)
      Removes a call back invoked when a given class loader is being destroyed.
      Parameters:
      listener - class loader destruction listener.
    • isCheckingPluginDependencies

      boolean isCheckingPluginDependencies(ClassLoader cl)
      Returns true if Plugin.checkDependencies(ClassLoader, ClassResourceSource) is being called for the given class loader.

      During the given process no class path entries should be altered.

      Parameters:
      cl - the target ClassLoader
      Returns:
      true if Plugin.checkDependencies(ClassLoader, ClassResourceSource) is being called for the given class loader.
    • disablePlugins

      void disablePlugins(ClassLoader cl)
      Disable running plugins in given class loader.
      Parameters:
      cl - the target ClassLoader
    • disableReloading

      void disableReloading(ClassLoader cl)
      Disable class reloading in given class loader. Resource management will still be enabled.
      Parameters:
      cl - the target ClassLoader
    • disableReloadDetection

      void disableReloadDetection(ClassLoader cl)
      Disable class reload check in given class loader. Resource management will still be enabled.
      Parameters:
      cl - the target ClassLoader
    • addAfterMainCallback

      void addAfterMainCallback(AfterMainCallback callback)
      Registers a callback that will be invoked after the main method is called. Callback will be invoked in the same order as they were added. If a callback is added after the main method has been called it will be invoked immediately.
      Parameters:
      callback - the callback
    • disableSecurityManager

      void disableSecurityManager()
      Disables the SecurityManager in the current thread.
    • enableSecurityManager

      void enableSecurityManager()
      Re-enables the disabled SecurityManager in the current thread.
    • getClassBytecodeProcessorCache

      ClassBytecodeProcessorCache getClassBytecodeProcessorCache()
      Returns an instance of ClassBytecodeProcessorCache which can be used by class bytecode processors to cache their transformations between runs.
      Returns:
      cacheCleaner the cache
    • bindToClassLoader

      void bindToClassLoader(ClassLoader cl, Object value)
      Add reference from given class loader to given object. This will prevent GC from collecting the input object before class loader is collected.
      Parameters:
      cl - Class loader that will be used to keep object alive.
      value - Object that will be made to live as long as class loader.
      Since:
      2019.2.2
    • addCacheCleaner

      void addCacheCleaner(CacheCleaner cacheCleaner)
      An integration point to add once per reload caches that should be cleared after reload.
      Parameters:
      cacheCleaner - a listener to be called for cleanup
      Since:
      2020.1.2