Example #1
0
  private void reloadSource(
      @NotNull ClassDescriptorSourceUnit sourceFile, boolean detectInnerClasses) {
    Class clasz = customClassLoader.loadClass(sourceFile, true);

    LinkedList<ClassDescriptorInner> innerClassDescList = sourceFile.getInnerClassDescriptors();
    if (innerClassDescList != null && !innerClassDescList.isEmpty()) {
      for (ClassDescriptorInner innerClassDesc : innerClassDescList) {
        customClassLoader.loadClass(innerClassDesc, true);
      }
    } else if (detectInnerClasses) {
      // Aprovechando la carga de la clase, hacemos el esfuerzo de cargar todas las clases
      // dependientes lo más
      // posible
      clasz
          .getDeclaredClasses(); // Provoca que las inner clases miembro indirectamente se procesen
                                 // y carguen
      // a través del JProxyClassLoader de la clase padre clasz

      // Ahora bien, lo anterior NO sirve para las anonymous inner classes, afortunadamente en ese
      // caso podemos
      // conocer y cargar por fuerza bruta
      // http://stackoverflow.com/questions/1654889/java-reflection-how-can-i-retrieve-anonymous-inner-classes
      // ?rq=1

      for (int i = 1; i < Integer.MAX_VALUE; i++) {
        String anonClassName = sourceFile.getClassName() + "$" + i;
        Class innerClasz = customClassLoader.loadInnerClass(sourceFile, anonClassName);
        if (innerClasz == null) {
          break; // No hay más o no hay ninguna (si i es 1)
        }
      }

      // ¿Qué es lo que queda por cargar pero que no podemos hacer explícitamente?
      // 1) Las clases privadas autónomas que fueron definidas en el mismo archivo que la clase
      // principal: no
      // las soportamos pues no podemos identificar en el ClassLoader que es una clase "hot
      // reloadable", no son
      // inner classes en el sentido estricto
      // 2) Las clases privadas "inner" locales, es decir no anónimas declaradas dentro de un
      // método, se
      // cargarán la primera vez que se usen, no podemos conocerlas a priori
      //    porque siguen la notación className$NclassName  ej.
      // JReloadExampleDocument$1AuxMemberInMethod. No
      // hay problema con que se carguen con un class loader antiguo pues
      //    el ClassLoader de la clase padre contenedora será el encargado de cargarla en cuanto se
      // pase por el
      // método que la declara.
    }
  }
Example #2
0
 @Nullable
 public synchronized <T> Class<?> findClass(String className) {
   // Si ya está cargada la devuelve, y si no se cargó por ningún JProxyClassLoader se intenta
   // cargar por el
   // parent ClassLoader, por lo que siempre devolverá distinto de null si la clase está en el
   // classpath, que
   // debería ser lo normal
   try {
     return customClassLoader.findClass(className);
   } catch (ClassNotFoundException ex) {
     return null;
   }
 }