Classloader

cs_soumia_info Messages postés 39 Date d'inscription samedi 26 mai 2007 Statut Membre Dernière intervention 31 août 2007 - 21 juin 2007 à 23:13
cs_soumia_info Messages postés 39 Date d'inscription samedi 26 mai 2007 Statut Membre Dernière intervention 31 août 2007 - 25 juin 2007 à 21:27
salut,
dans une application j'ai essaie de modifier une classe (craser cette classe par une autre classe a le mame nom) en suit de rechergr la nouvelle classe  et pour cela j'utilise mon propre classeloader ,
-le probleme est qaund si la classe est recharger avant la premiere utilisation les modification sont pris en considiration (cliquer sur le button pour recharger la classe )
mais dans le cas contraire c'est a dire la classe est utiliser avant le rechargement de la novelle classe (avant les modification) ""utiliser en suit modifier"" les modifications ne sont pas pris en consideration"  

14 réponses

eplanet Messages postés 112 Date d'inscription dimanche 6 juin 2004 Statut Membre Dernière intervention 19 septembre 2007
22 juin 2007 à 16:16
Quel charabia... Je voudrai bien t'aider mais je ne comprends pas ce que tu dis, tu devrais essayer de reformuler...
0
cs_soumia_info Messages postés 39 Date d'inscription samedi 26 mai 2007 Statut Membre Dernière intervention 31 août 2007
22 juin 2007 à 17:56
salut


-ma question est : comment recharger une classe pandant l'execution ?
0
eplanet Messages postés 112 Date d'inscription dimanche 6 juin 2004 Statut Membre Dernière intervention 19 septembre 2007
22 juin 2007 à 19:00
Cela me semble à peu près normal. Si tu utilises la classe avant de l'écraser par une nouvelle, l'objet utilisera la première classe (puisqu'il ne connaîtra pas encore la nouvelle). Il faut charger la nouvelle classe avant de créer l'objet. Si ce que tu veux faire, c'est de transformer l'objet une fois qu'il a été créé, tu vas devoir utiliser un adaptateur pour transformer l'objet en un autre. Mais j'ai peut-être mal compris ce que tu voulais faire...

Vince
0
cs_soumia_info Messages postés 39 Date d'inscription samedi 26 mai 2007 Statut Membre Dernière intervention 31 août 2007
22 juin 2007 à 20:40
salut
je veut recharger la classe apres la creation de l'objet
-comment faire ?comment supprimer cet objet ? c'est quio un adaptateur?
merci de votre aide
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
23 juin 2007 à 17:49
n y aurait i lpas confusion entre instance de class et ;o) prototype de class ;o) ?!!
le class loader et charger de fournir des instances a partir d un prototype ... ;o) si ton but est juste de changer l instance il te suffit de refaire un new Object sur ta reference quand à l objet non referencé il sera supprimé par le GC (tu peu le forcer qd meme mais rarement utile)...
sinon et si ta nouvelle instance doit respecter un nouveau model c est en effet au niveau du class loader qu il faut bosser ;o) mais pour autant il faudra qd meme l instancier... ;o)

[purple]GodConan/purple[:o)]
0
cs_soumia_info Messages postés 39 Date d'inscription samedi 26 mai 2007 Statut Membre Dernière intervention 31 août 2007
23 juin 2007 à 19:50
j'ai deja realiser mon propre classe loader mais  la nouvelle instance ne respecte pas le nouveus model saufe si la classe modifier n'a pas daja instancie


(si la classe est recharger avant  la premier instanciation)
voici le code de mon propre classe loader
public final class DynaCode {


 private String compileClasspath;


 private ClassLoader parentClassLoader;


 private ArrayList sourceDirs = new ArrayList();


 // class name => LoadedClass
 private HashMap loadedClasses = new HashMap();


 public DynaCode() {
  this(Thread.currentThread().getContextClassLoader());
 }


 public DynaCode(ClassLoader parentClassLoader) {
  this(extractClasspath(parentClassLoader), parentClassLoader);


 }


 /**
  * @param compileClasspath
  *            used to compile dynamic classes
  * @param parentClassLoader
  *            the parent of the class loader that loads all the dynamic
  *            classes
  */
 public DynaCode(String compileClasspath, ClassLoader parentClassLoader) {
  this.compileClasspath = compileClasspath;
  this.parentClassLoader = parentClassLoader;
 }


 /**
  * Add a directory that contains the source of dynamic java code.
  *
  * @param srcDir
  * @return true if the add is successful
  */
 public boolean addSourceDir(File srcDir) {


  try {
   srcDir = srcDir.getCanonicalFile();
  } catch (IOException e) {
   // ignore
  }


  synchronized (sourceDirs) {


   // check existence
   for (int i = 0; i < sourceDirs.size(); i++) {
    SourceDir src = (SourceDir) sourceDirs.get(i);
    if (src.srcDir.equals(srcDir)) {
     return false;
    }
   }


   // add new
   SourceDir src = new SourceDir(srcDir);
   sourceDirs.add(src);


   info("Add source dir " + srcDir);
  }


  return true;
 }


 /**
  * Returns the up-to-date dynamic class by name.
  *
  * @param className
  * @return
  * @throws ClassNotFoundException
  *             if source file not found or compilation error
  */
 public Class loadClass(String className) throws ClassNotFoundException {


  LoadedClass loadedClass = null;
  synchronized (loadedClasses) {
   loadedClass = (LoadedClass) loadedClasses.get(className);
  }


  // first access of a class
  if (loadedClass == null) {


   String resource = className.replace('.', '/') + ".java";
   SourceDir src = locateResource(resource);
   if (src == null) {
    throw new ClassNotFoundException("DynaCode class not found "
      + className);
   }


   synchronized (this) {


    // compile and load class
    loadedClass = new LoadedClass(className, src);


    synchronized (loadedClasses) {
     loadedClasses.put(className, loadedClass);
    }
   }


   return loadedClass.clazz;
  }


  // subsequent access
  if (loadedClass.isChanged()) {
   // unload and load again
   unload(loadedClass.srcDir);
   return loadClass(className);
  }


  return loadedClass.clazz;
 }


 private SourceDir locateResource(String resource) {
  for (int i = 0; i < sourceDirs.size(); i++) {
   SourceDir src = (SourceDir) sourceDirs.get(i);
   if (new File(src.srcDir, resource).exists()) {
    return src;
   }
  }
  return null;
 }


 private void unload(SourceDir src) {
  // clear loaded classes
  synchronized (loadedClasses) {
   for (Iterator iter = loadedClasses.values().iterator(); iter
     .hasNext();) {
    LoadedClass loadedClass = (LoadedClass) iter.next();
    if (loadedClass.srcDir == src) {
     iter.remove();
    }
   }
  }


  // create new class loader
  src.recreateClassLoader();
 }


 /**
  * Get a resource from added source directories.
  *
  * @param resource
  * @return the resource URL, or null if resource not found
  */
 public URL getResource(String resource) {
  try {


   SourceDir src = locateResource(resource);
   return src == null ? null : new File(src.srcDir, resource).toURL();


  } catch (MalformedURLException e) {
   // should not happen
   return null;
  }
 }


 /**
  * Get a resource stream from added source directories.
  *
  * @param resource
  * @return the resource stream, or null if resource not found
  */
 public InputStream getResourceAsStream(String resource) {
  try {


   SourceDir src = locateResource(resource);
   return src == null ? null : new FileInputStream(new File(
     src.srcDir, resource));


  } catch (FileNotFoundException e) {
   // should not happen
   return null;
  }
 }


 /**
  * Create a proxy instance that implements the specified access interface
  * and delegates incoming invocations to the specified dynamic
  * implementation. The dynamic implementation may change at run-time, and
  * the proxy will always delegates to the up-to-date implementation.
  *
  * @param interfaceClass
  *            the access interface
  * @param implClassName
  *            the backend dynamic implementation
  * @return
  * @throws RuntimeException
  *             if an instance cannot be created, because of class not found
  *             for example
  */
public Object   newProxyInstance( String implClassName,Class interfaceClass)
   throws RuntimeException {


            MyInvocationHandler handler = new MyInvocationHandler(
   implClassName);
                 System.out.println("fin de invocation invocation ");


     }


 private class SourceDir {
  File srcDir;


  File binDir;


  Javac javac;


  URLClassLoader classLoader;


  SourceDir(File srcDir) {
   this.srcDir = srcDir;


   String subdir = srcDir.getAbsolutePath().replace(':', '_').replace(
     '/', '_').replace('\\', '_');
   this.binDir = new File(System.getProperty("java.io.tmpdir"),
     "classes/" + subdir);
   this.binDir.mkdirs();


   // prepare compiler
                        System.out.println("compilation copilation compilation");
                        this.javac = new Javac(System.getProperty("java.class.path")
, "c:/mai/classes");
                        System.out.println("compilation copilation compilation");
   // class loader
   recreateClassLoader();
  }


  void recreateClassLoader() {
   try {
    classLoader = new URLClassLoader(new URL[] { binDir.toURL() },
      parentClassLoader);
   } catch (MalformedURLException e) {
    // should not happen
   }
  }


 }


 private static class LoadedClass {
  String className;


  SourceDir srcDir;


  File srcFile;


  File binFile;


  Class clazz;


  long lastModified;


  LoadedClass(String className, SourceDir src) {
   this.className = className;
   this.srcDir = src;


   String path = className.replace('.', '/');
   this.srcFile = new File(src.srcDir, path + ".java");
   this.binFile = new File(src.binDir, path + ".class");


   compileAndLoadClass();
  }


  boolean isChanged() {
   return srcFile.lastModified() != lastModified;
  }


  void compileAndLoadClass() {


   if (clazz != null) {
    return; // class already loaded
   }


   // compile, if required
   String error = null;
   if (binFile.lastModified() < srcFile.lastModified()) {
                     System.out.println("system compilation");
                            error = srcDir.javac.compile(new File[] {srcFile});
                            System.out.println("system compilation fin de compilation error nember"+error);
   }


   if (error != null) {
    throw new RuntimeException("Failed to compile "
      + srcFile.getAbsolutePath() + ". Error: " + error);
   }


   try {
    // load class
    clazz = srcDir.classLoader.loadClass(className);


    // load class success, remember timestamp
    lastModified = srcFile.lastModified();


   } catch (ClassNotFoundException e) {
    throw new RuntimeException("Failed to load DynaCode class "
      + srcFile.getAbsolutePath());
   }


   info("Init " + clazz);
  }
 }


 private class MyInvocationHandler implements InvocationHandler  {


  String backendClassName;


  Object backend;


  MyInvocationHandler(String className) {
   backendClassName = className;


   try {
                            Class clz = loadClass(backendClassName);


    backend = newDynaCodeInstance(clz);


   } catch (ClassNotFoundException e) {
    throw new RuntimeException(e);
   }
  }


  public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {


   // check if class has been updated
   Class clz = loadClass(backendClassName);
   if (backend.getClass() != clz) {
    backend = newDynaCodeInstance(clz);
   }


   try {
    // invoke on backend
    return method.invoke(backend, args);


   } catch (InvocationTargetException e) {
    throw e.getTargetException();
   }
  }


  private Object newDynaCodeInstance(Class clz) {
     try { FipaRequestInitiateur yy=(FipaRequestInitiateur)clz.newInstance();
                        return  yy ;
     } catch (Exception e) {
    throw new RuntimeException(
      "Failed to new instance of DynaCode class "
        + clz.getName(), e);
   }
  }


 }


 /**
  * Extracts a classpath string from a given class loader. Recognizes only
  * URLClassLoader.
  */
 private static String extractClasspath(ClassLoader cl) {
  StringBuffer buf = new StringBuffer();


  while (cl != null) {
   if (cl instanceof URLClassLoader) {
    URL urls[] = ((URLClassLoader) cl).getURLs();
    for (int i = 0; i < urls.length; i++) {
     if (buf.length() > 0) {
      buf.append(File.pathSeparatorChar);
     }
     buf.append(urls[i].getFile().toString());
    }
   }
   cl = cl.getParent();
  }


  return buf.toString();
 }


 /**
  * Log a message.
  */
 private static void info(String msg) {
  System.out.println("[DynaCode] " + msg);
 }


}
merci d'vance
0
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
24 juin 2007 à 17:58
if (clazz != null) {
    return; // class already loaded
   }

cela ne serait pas ca le soucis??!!!

GodConan ;o)
0
cs_soumia_info Messages postés 39 Date d'inscription samedi 26 mai 2007 Statut Membre Dernière intervention 31 août 2007
24 juin 2007 à 18:19
salut
le probleme c'est pas ce puisque on a toujour au debut laclzz=null
en tout les cas merci de votre aide
0
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
24 juin 2007 à 18:47
oui justement ;o) !!! donc elle n est charger que au début.... mais si tu veux la modifier il faut la recharger systématiquement !!!

GodConan ;o)
0
cs_soumia_info Messages postés 39 Date d'inscription samedi 26 mai 2007 Statut Membre Dernière intervention 31 août 2007
25 juin 2007 à 06:39
comment recharger une classe systématiquement?
merci merci merci
0
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
25 juin 2007 à 18:18
ben !! enleve le test  ;o) qui dit de sortir qd elle existe...
je n ai pas les moyen de tester ton code ici ... donc je ne vois surment pas tous mais à la premiere lecture c est ce qui me semble...

GodConan ;o)
0
cs_soumia_info Messages postés 39 Date d'inscription samedi 26 mai 2007 Statut Membre Dernière intervention 31 août 2007
25 juin 2007 à 19:23
salut , j'ai enleve le code de test (if(clazz!=null)...)
mais  le probleme reste toujour
''si la classe est instancie avant les modification ces modification ne sont pas pris en compt''
merci de votre aide
0
cs_GodConan Messages postés 2113 Date d'inscription samedi 8 novembre 2003 Statut Contributeur Dernière intervention 6 octobre 2012 12
25 juin 2007 à 21:06
Désolé je n est pas trop de temps cette semaine pour me lancer ds la création d un CL ;-( ...
Et c est vrai que je ne m etait jamais posé ce probleme avec mes class loader ;o) ...

GodConan ;o)
0
cs_soumia_info Messages postés 39 Date d'inscription samedi 26 mai 2007 Statut Membre Dernière intervention 31 août 2007
25 juin 2007 à 21:27
en tout les cas merci de votre aide
0