Archive CLassLoader

Résolu
VerInfo Messages postés 20 Date d'inscription mercredi 14 mars 2012 Statut Membre Dernière intervention 3 juillet 2012 - 29 juin 2012 à 17:55
VerInfo Messages postés 20 Date d'inscription mercredi 14 mars 2012 Statut Membre Dernière intervention 3 juillet 2012 - 30 juin 2012 à 01:35
Salut,

j'ai définit un nouveau ClassLoader héritant de java.lang.Classloader,ai créé une méthode qui va lire mon fichier, avec un BufferedInputStream , et récupérer un tableau de byte.
Ensuite j'ai fais appelles à la méthode defineClass(String, byte[], int, int) avec le tableau de byte précédent. Celle-ci va instancier ma classe mais le probléme que lors du chargement le programme gènére cette exception .

java.lang.LinkageError: loader (instance of com/parser/metier/JarLoaderVersion1): attempted duplicate class definition for name: "test1/HumanController"
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)

Est-ce quelqu'un peut m'aider?

Merciii

3 réponses

Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
29 juin 2012 à 23:11
Salut,

Si ton appel de la méthode defineClass se fait dans la méthode findClass, il faut que tu te protège en passant par une map (par exemple) pour ne pas faire cet appel 2x pour une même classe.

Tu peux faire un truc comme ça:
/* ... */
/* 
 * Liste des classes au sens Java.
 * La clé représente le nom au format: monpackage/MaClasse.class
 */
private Hashtable<String, Class<?>> classes;
/* 
 * Liste des classes au sens bytes.
 * La clé représente le nom au format: monpackage/MaClasse.class
 */
private Hashtable<String, byte[]>   classesData;
/* ... */
    
@Override
public Class<?> findClass(final String className) throws ClassNotFoundException{
  Class<?> clazz = null;
  /* Conversion du nom en chemin, exemple monpackage.MaClasse devient monpackage/MaClasse.class */
  final String classPath = className.replace('.', '/') + ".class";
  /* Test si la classe est déjà chargée ou non */
  /* Attention la jvm n'aime pas le double chargement... */
  if (classes.containsKey(classPath)) return classes.get(classPath);
  /* Récupération des datas */
  final byte[] classBytes = classesData.get(classPath);
  /* Si la classe n'est pas présente */
  if (classBytes null) clazz super.findClass(classPath);
  else {
    /* Charge la classe */
    clazz = defineClass(className, classBytes, 0, classBytes.length);
    resolveClass(clazz);
  }
  /* Ajoute la classe pour le prochain appel de findClass. */
  classes.put(classPath, clazz);
  return clazz;
}



-----

"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

OoWORAoO
3
VerInfo Messages postés 20 Date d'inscription mercredi 14 mars 2012 Statut Membre Dernière intervention 3 juillet 2012 2
30 juin 2012 à 01:24
Merci pour la réponse je vais l'essayer
0
VerInfo Messages postés 20 Date d'inscription mercredi 14 mars 2012 Statut Membre Dernière intervention 3 juillet 2012 2
30 juin 2012 à 01:35
Voici mon code comment je peux le modifier pour remédier à cette erreur ?



public class ZipEntitiesLoader extends ClassLoader {
    private final ZipFile file;

    public ZipEntitiesLoader(String filename,ClassLoader classLoader) throws IOException {
        super(classLoader);
    	this.file = new ZipFile(filename);
               
    }
    
    public List<Class<?>> loadClass() throws ClassNotFoundException
    {
    	List<Class<?>> listOfClasses = new ArrayList<Class<?>>();
    	Enumeration<?> zipEntries = file.entries();
           
         while (zipEntries.hasMoreElements()) 
         {
        	 ZipEntry entry = (ZipEntry)zipEntries.nextElement();
             if(entry.getName().endsWith(".class"))
             {
            	 
            	 String className = entry.getName().replace("/", ".").replace(".class", "");
             System.out.println("creating " + className+ " --");
             
             try {
                 byte[] array = new byte[1024];
                 InputStream in = this.file.getInputStream(entry);
                 ByteArrayOutputStream out = new ByteArrayOutputStream(array.length);
                 int length = in.read(array);
                 while (length > 0) {
                     out.write(array, 0, length);
                     length = in.read(array);
                 }
                if(! listOfClasses.contains(className+".class"))
                 listOfClasses.add(defineClass(className, out.toByteArray(), 0, out.size()));
             }
             catch (IOException exception) {
                 throw new ClassNotFoundException(className, exception);
             }
             }
             else
             {
            	 System.out.println("will not convert "+ entry.getName());
             }
         }
    	
    	return listOfClasses;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        ZipEntry entry = this.file.getEntry(name.replace('.', '/') + ".class");
        if (entry == null) 
        {
            throw new ClassNotFoundException(name);
        }
        try {
            byte[] array = new byte[1024];
            InputStream in = this.file.getInputStream(entry);
            ByteArrayOutputStream out = new ByteArrayOutputStream(array.length);
            int length = in.read(array);
            while (length > 0) {
                out.write(array, 0, length);
                length = in.read(array);
            }
            return defineClass(name, out.toByteArray(), 0, out.size());
        }
        catch (IOException exception) {
            throw new ClassNotFoundException(name, exception);
        }
    }
}


Merci
0
Rejoignez-nous