3 Replies Latest reply: Aug 11, 2010 4:23 AM by 843798 RSS

    ClassLoading customization

    843798
      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
          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
            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
              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.