This discussion is archived
3 Replies Latest reply: Aug 11, 2010 2:23 AM by 843798 RSS

ClassLoading customization

843798 Newbie
Currently Being Moderated
Hi,

I execute a process with a custom ClassLoader (with -Djava.system.class.loader VM argument), in this process I want to change a static field of my custom ClassLoader through a static method, but this static setter doesn't works which seems very strange for a so simple code :

My custom class loader :

package test_;

import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class CustomClassLoader extends ClassLoader {

     private static String plop;

     public CustomClassLoader(ClassLoader parent) {
          super(parent);
     }

     private Class<?> getClass(String name) throws ClassNotFoundException {
          String file = name.replaceAll("\\.", File.separator) + ".class";
          byte[] b = null;
          try {
               b = loadClassData(file);
               Class<?> c = defineClass(name, b, 0, b.length);
               resolveClass(c);
               return c;
          } catch (IOException e) {
               throw new ClassNotFoundException(name);
          }
     }

     @Override
     public Class<?> loadClass(String name) throws ClassNotFoundException {
          System.out.println("loading class '" + name + "'");
          if (name.startsWith(CustomClassLoader.class.getPackage().getName())) {
               try {
                    return getClass(name);
               } catch (ClassNotFoundException e) {
                    return super.loadClass(name);
               }
          }
          
          return super.loadClass(name);
     }

     @Override
     protected Class<?> findClass(String name) throws ClassNotFoundException {
          if(plop!=null){
               try {
                    
                    String absolutePath = plop+"/"+name.replaceAll("\\.", File.pathSeparator)+".class";
                    URL url = new URL(absolutePath);
                    
                    InputStream stream = url.openStream();
                    int size = stream.available();
                    byte buff[] = new byte[size];
                    DataInputStream in = new DataInputStream(stream);
                    in.readFully(buff);
                    in.close();
                    
                    Class<?> c = defineClass(name, buff, 0, buff.length);
                    resolveClass(c);
                    return c;

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

     private byte[] loadClassData(String name) throws IOException {
          InputStream stream = getClass().getClassLoader().getResourceAsStream(
                    name);
          if(stream==null){
               throw new IOException();
          }
          int size = stream.available();
          byte buff[] = new byte[size];
          DataInputStream in = new DataInputStream(stream);
          in.readFully(buff);
          in.close();
          return buff;
     }
     
     public static void setClassLoaderURL(String newClassLoaderURL) {
          plop = newClassLoaderURL;          
     }
     
     public static String getClassLoaderURL() {
          return plop;          
     }

}



My main class :


package test_;

public class Main {

     public static void main(String[] args) {
          CustomClassLoader.setClassLoaderURL("plop");
          System.out.println(CustomClassLoader.getClassLoaderURL());
          try {
               ClassLoader.getSystemClassLoader().loadClass("Plip");
          } catch (ClassNotFoundException e) {
               e.printStackTrace();
          }
     }
}


then I launch this main class with -Djava.system.class.loader=test_.CustomClassLoader VM argument, but plop field null at CustomClassLoader.findClass() method execution.
I don't find my mistake?

Best Regards.
  • 1. Re: ClassLoading customization
    791266 Explorer
    Currently Being Moderated
    Please, use code formatting when you post code.

    Press the code button above the edit field, and then paste the code between the generated tags.
  • 2. Re: ClassLoading customization
    jschellSomeoneStoleMyAlias Expert
    Currently Being Moderated
    EstebanD wrote:
    Hi,

    I execute a process with a custom ClassLoader (with -Djava.system.class.loader VM argument), in this process I want to change a static field of my custom ClassLoader through a static method, but this static setter doesn't works which seems very strange for a so simple code :
    That doesn't seem like a good idea. Messing with that loader requires care.

    But other than that you didn't tell us how it doesn't work.

    Although as a guess...you accessed the method, so how exactly do you think that the class to which that method belongs got loaded?
  • 3. Re: ClassLoading customization
    843798 Newbie
    Currently Being Moderated
    Hi,

    Sorry for the missing formatting.

    jschell,

    Oh yes I have found my mistake, I loaded a second time my CustomClassloader while it was already loaded a first time by the bootstrap classloader.

    Thanks.