14 Haziran 2015 Pazar

Java da ClassLoader nedir? Nasıl Çalışır?

JVM(Java Virtual Machine) ilk çalışırken sınıfların yüklenmesinden sorumlu Class tır diyebiliriz. Java da Interpretation(yorumlama) işleminden önce Class Loading işlemleri gerçekleşir. Her Class uniq olarak ClassLoader tarafından JVM Memory e yüklenir. JVM Class Loading işlemlerini yaparken, yani bir java uygulamasını ilk olarak ayağa kaldırırken, daha uygulamamız hiç çalışmaya başlamadan önce, ClassLoader sınıfından extend ederek sınıf yükleme işlemlerini özelleştirmemize olanak sağlar. Örneğin aynı isimli sınıfı iki kez özel olarak load edebiliriz, yada uygulama açılmadan önce güvenlik amaçlı kontroller yada şifrelemeler yapabiliriz.
Class Loading işlemi: JVM de önce Bootstrap Class Loader ile, java.lang, java.util vb gibi paketler içindeki çekirdek classlar yüklenir. Sonra kullanıcı tanımlı Class Loader lar çalışır. Sonra Array Classları create edilir, Constraint ler load edilir, türetilmiş classlara geçilir.
JVM, Class loading işleminden sonra; Classların doğrulanarak hazırlanıp, çözümlenmesi - Linking(Verification,Preparation,Resolution) sonra da yüklenen ve bağlanan Classların başlatılması - Initialization işlemlerini gerçekleştirir. Buraya kadar sorun yoksa normal şartlarda uygulama ayağa kalkmış demektir.
Hiyerarşik olarak Java Class Loader lar;
1)Bootstrap Class Loader : Bu java runtime ortamının parçası olan sınıflardır, “JAVA_HOME/jre/lib/rt.jar” içinde bulunan java.util, java.lang vb. gibi java çekirdek sınıflarını yükler. Bootstrap sınıf yükleyicisi native implementation dur ve bu yüzden farklı JVM'lerde farklılık gösterebilir.
2) Extensions Class Loader : “JAVA_HOME/jre/lib/ext”  altındaki sınıfları yükler.
3) System Class Loader : Java classpath de belirtilmiş olan sınıfları yükler.

Şekil : Java SE 7 JVM mimarisinde, JVM spesifikasyonu.

Örnek Özelleştirilmiş ClassLoader:
package classloaders.ocp7;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * Simple custom class loader implementation
 */
public class CustomClassLoader extends ClassLoader {

    /**
     * The HashMap where the classes will be cached
     */
    private Map<String, Class<?>> classes = new HashMap<String, Class<?>>();

    @Override
    public String toString() {
        return CustomClassLoader.class.getName();
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        if (classes.containsKey(name)) {
            return classes.get(name);
        }

        byte[] classData;

        try {
            classData = loadClassData(name);
        } catch (IOException e) {
            throw new ClassNotFoundException("Class [" + name
                    + "] could not be found", e);
        }

        Class<?> c = defineClass(name, classData, 0, classData.length);
        resolveClass(c);
        classes.put(name, c);

        return c;
    }

    /**
     * Load the class file into byte array
     */
    private byte[] loadClassData(String name) throws IOException {
        BufferedInputStream in = new BufferedInputStream(
                ClassLoader.getSystemResourceAsStream(name.replace(".", "/")
                        + ".class"));
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int i;

        while ((i = in.read()) != -1) {
            out.write(i);
        }

        in.close();
        byte[] classData = out.toByteArray();
        out.close();

        return classData;
    }

    /**
     * Simple usage of the CustomClassLoader implementation
     */
    public static void main(String[] args) throws ClassNotFoundException,
            InstantiationException, IllegalAccessException,
            NoSuchMethodException, SecurityException, IllegalArgumentException,
            InvocationTargetException
    {
        CustomClassLoader loader = new CustomClassLoader();
        // This class should be in your application class path
        Class<?> c = loader.findClass("classloaders.ocp7.TestClass");
        Object o = c.newInstance();
        Method m = c.getMethod("toString");
        System.out.println(m.invoke(o));
    }

}

Test sınıfı:
package classloaders.ocp7;

public class TestClass {
       public String toString() {
             String aciklama = "Bu bir test sınıfıdır.";
             return aciklama;
       }
}



Kaynaklar:

Hiç yorum yok :

Yorum Gönder