[JAVA] class 클래스 로딩

JAVA 2017. 10. 30. 13:31

class 클래스 로딩


CLASSPATH에 없는 클래스 로딩


java.lang.reflect를 이용하면 우리가 원하는 클래스에 대한 invoke가 가능하다는 것은 알고 있을 것이다.

하지만 classpath에 등록안되어진 클래스들에 대해서는 어떻게 할 것인가?

일일이 사용자에게 클래스 패스를 설정하게 할수만은 없는 일 입니다.

보통의 엔진들을 보게 되면 install되어진 디렉토리의 위치만을 세팅하도록 하고 있다.

set JAVA_HOME 이라던지

set ANT_HOME 이라던지

쉘스크립트에 의하여 그러한 것들을 정의하여 java process를 띄우곤 하는데 그러면 내가 ant.jar등을 등록하지 않았음에도 불구하고 해당 애플리케이션들이 잘 작동하는 이유는 무엇일까요?

그건은 바로 ClassLoader에 숨겨져 있습니다.


아래에서 보여지는 샘플코드는 classpath 프로퍼티에 등록이 되어지지 않은 클래스들에 대한 조작을 할 것입니다. 

그렇게 함으로서 우리들이 만든 애플리케이션이 별다른 클래스로딩 정책 없이도 작동이 될수 있습니다.

그러려면 또한 잘 알아야 하는것이 reflection API가 있습니다.


이 부분에서는 그러한 것을 생략하고 URLClassLoader를 이용하여 디렉토리나 jar파일을 등록하여 가져오는 방법을 설명하도록 하겠습니다.


ClassLoader클래스는 이미 1.0API부터 존재했으며 URLClassLoader1.2에 새롭게 추가된 클래스이다.


우리가 사용하는 파일시스템이 URL이란 이름하에 조작이 될 수 있다는 것을 우선 명심해주시기 바랍니다.


이유는 file:// 이란 URI를 사용하기 때문이다.


아래에서는 특정한 티렉토리 안의 jar 파일에 대한 class loading샘플을 보여줍니다.


import java.io.*; 

import java.net.*; 


public class ClassLoading { 

public static void main(String [] args) throws Exception { 

   // Create a File object on the root of the directory containing the class file 

    File file = 

new File("D:/_Develop/jmxSamples/customMBean/log4j-1.2.8.jar"); 

     

    try { 

      // Convert File to a URL 

      URL url = file.toURL();          

// file:/D:/_Develop/jmxSamples/customMBean/log4j-1.2.8.jar 

            URL[] urls = new URL[]{ url }; 

            System.out.println(urls); 

       

            // Create a new class loader with the directory 

            ClassLoader cl = new URLClassLoader(urls); 

            System.out.println(cl); 

       

            // Load in the class; Logger.class should be located in 

     // the directory file:/D:/_Develop/jmxSamples/customMBean/log4j-1.2.8.jar 

      

Class cls = cl.loadClass("org.apache.log4j.Logger"); 

            System.out.println(cls); 

     

    } catch (MalformedURLException e) { 

        e.printStackTrace(); 

    } catch (ClassNotFoundException e2) { 

          e2.printStackTrace(); 

    }

   

  }

}


위에서 보는 것처럼 디렉토리를 설정하거나 특정 jar 파일을 사용할 수 있도록 작성합니다.

특정파일이 가르키지 않으면 해당 디렉토리의 class파일들을 package형태로 참조하도록 할 수 있는데 해당 디렉토리에 대한 클래스 로딩 샘플을 아래와 같습니다.


import java.io.*; 

import java.net.*; 


public class ClassLoading {

//Create a File object on the root of the directory containing the class file

File file = 

new File("D:/_CVSDevelop/jca_hello_adapter/build/classes");


try {

// Convert File to a URL

URL url = file.toURL();

// file:/D:/_CVSDevelop/jca_hello_adapter/build

URL[] urls = new URL[]{ url };

System.out.println(urls);


// Create a new class loader with the directory 

ClassLoader cl = new URLClassLoader(urls);

System.out.println(cl);


// Load in the class; Test.class should be located in 

// the directory //file:/D:/_CVSDevelop/jca_hello_adapter/build/classes/com/b//ea/jca/test/Test 

Class cls = cl.loadClass("com.bea.jca.test.Test"); 

System.out.println(cls); 

}catch (MalformedURLException e){

e.printStackTrace(); 

}catch (ClassNotFoundException e2){

e2.printStackTrace();

}

}


위와 같은 경우에는 classpath의 root로 잡은 디렉토리를 기준의 package형태로 설정되 파일을 로딩하여 사용할수 있도록 한다.

이 이후의 코딩에는 class가 newInstance를 취한 후 method를 

invoking해야 하는 과정을 거치게 되는데 한 가지 주의할 점은 해당 클래스를 반드시 reflection API를 이용하여 호출해야 한다는 점이다.

대략 아래의 코드정도를 이용하여 main 메소드등을 호출하는 클래스를 작성할 수 있을 것이다.


public void invokeClass(String name, String[] args)

throws ClassNotFoundException, NoSuchMethodException,

InvocationTargetException

{

Class c = loadClass(name);

Method m = c.getMethod("main", new Class[] {args.getClass()});

m.setAccessible(true);

int mods = m.getModifiers(); 

if(m.getReturnType() != void.class || !Modifier.isStatic(mods) || !Modifier.isPublic(mods)){

throw new NoSuchMethodException("main");

}

try {

m.invoke(null, new Object[] { args }); 

}catch (IllegalAccessException e) { 

// This should not happen, as we have disabled //access checks 

}

}


위와 같은 샘플을 이용하게 되면 서버측 프로그램에 대한 작성을 해볼 수 있는 좋은 기회가 아닐까 생각 됩니다.



'JAVA' 카테고리의 다른 글

[JAVA]classes 위치 가져오기  (0) 2017.10.30
[JAVA] Class.forName 사용하기  (0) 2017.10.30
[JAVA] class 동적로딩  (0) 2017.10.30
[JAVA] class path에서 resource 찾기  (0) 2017.10.30
[JAVA] cache function  (0) 2017.10.27
블로그 이미지

마크제이콥스

초보 개발자의 이슈및 공부 내용 정리 블로그 입니다.

,