KEMBAR78
Class loader basic | PPT
Copyright © 2004 Samsung SDS Co.,Ltd. All rights reserved  |  Confidential ClassLoader  개요 강 명 철 2006.11 Core Java
Copyright © 2004 Samsung SDS Co.,Ltd. All rights reserved  |  Confidential 목차 Class Loader Custom Class Loader Diagnosing
ClassLoader 1. JVM Architecture
ClassLoader Class loading takes place in two phases : Loading Linking or resolution 2. How Classes are Loaded ?
3. Class Class in Java ClassLoader Instances of class java.lang.Class    represent classes and interfaces in a running Java application Class has no public constructors Any applications cannot instantiate it Class is automatically instantiated by JVM/class loader, when a class loading process is done Each instance of Class keeps a reference to a class loader that created it
4. Class Loading ClassLoader When you define a class, say Foo, and initiate it ( to create its instance)    i.e. when you execute new Foo(); A local JVM (class loader) tries to Obtain the class definition of Foo Given the name of a class (i.e. Foo), the class loader locates a binary representation of Foo’s class definition Typically, it transforms the class name into a file name, and reads a class file of that name (e.g. Foo.class) from the local file system If this step fails, JVM return a ClassDefNotFound exception Parse the obtained class definition into internal structures in the method area of the JVM The method area is a logical area of memory in the JVM that is used to store information about loaded classes/interfaces Create an instance of Class, which is associated with Foo These 3 activities are collectively called class loading. After successful class loading, an instance of Foo is created and returned
5. Class Loaders in JVM ClassLoader Every JVM has two types of class loaders Default class loaders Bootstrap class loader Used to find and load a set of standard class libraries (i.e. java.* classes) that are located in $JAVA_HOME$/jre/lib -> e.g. $JAVA_HOME$/jre/lib/rt.jar Extension class loader Used to find and load a set of extension class libraries (i.e. javax.* classes) that are located in $JAVA_HOME$/jre/lib/ext System class loader (java.lang.Classloader) Used to find and load user-defined classes Custom class loaders If a user wants to change the behavior of system class loader, the user can extend java.lang.Classloader as a Java class. The class is called a custom class loader A custom class loader overloads the methods defined in java.lang.Classloader to implement its own class loading behavior. Different custom class loaders can specialize different class loading behaviors (policies)
6. Class Loaders Rules ClassLoader Consistency Rule Class loaders never load the same class more than once Delegation Rule Class loaders always consult a parent class loader before loading a class Visibility Rule Classes can only “see” other classes loaded by their class loader’s delegation, the recursive set of a class’s loader and all its parent loaders
6. Visibility  ClassLoader
6. Visibility  실습 ClassLoader Java Statics public class Dummy { public static int staticCount = 0; public Dummy(){ staticCount++; System.out.println("Instance #" + staticCount + " constructed."); } } public class StaticTest { public static void main(String[] args) { new Dummy(); new Dummy(); new Dummy(); new Dummy(); new Dummy(); } } Instance #1 constructed. Instance #2 constructed. Instance #3 constructed. Instance #4 constructed. Instance #5 constructed.
6. Visibility  실습 ClassLoader Java Statics public class Dummy { public static int staticCount = 0; public Dummy(){ staticCount++; System.out.println("Instance #" + staticCount + " constructed."); } } public class StaticTestClassLoader { public static void main(String[] args) throws Exception { URL[] url = {new File("../target/bin").toURL()}; URLClassLoader cl1 = new URLClassLoader(url); URLClassLoader cl2 = new URLClassLoader(url); URLClassLoader cl3 = new URLClassLoader(url); cl1.loadClass("Dummy").newInstance(); cl2.loadClass("Dummy").newInstance(); cl3.loadClass("Dummy").newInstance(); } } Instance #1 constructed. Instance #1 constructed. Instance #1 constructed.
7. Delegation Model ClassLoader class NetworkClassLoader extends ClassLoader { String host; int port; public Class findClass(String name) { byte[] b = loadClassData(name); return defineClass(name, b, 0, b.length); } private byte[] loadClassData(String name) { // load the class data from the connection  . . . } }
7. Delegation Model ClassLoader
7. Delegation Model  실습 ClassLoader Java 1.1 Style public class TestClassLoader extends ClassLoader { protected Hashtable m_classes  = new Hashtable(); protected boolean  m_cacle  = false; protected byte[] loadClassBytes(String name)  throws  ClassNotFoundException{ byte[] result = null; try{ FileInputStream in =  new FileInputStream("../Target/bin/" + name.replace('.', '/') + ".class"); ByteArrayOutputStream data =  new ByteArrayOutputStream(); int ch; while((ch = in.read()) != -1) data.write(ch); result = data.toByteArray(); } catch (Exception e){ throw new ClassNotFoundException(name); } return result; } protected synchronized Class loadClass (String name, boolean resolve)  throws ClassNotFoundException{ System.out.println(" 요청된  Class : " + name); Class result = (Class)m_classes.get(name); try{ if(result==null) return super.findSystemClass(name); else return result; } catch(Exception e) {} System.out.println("TestClassLoader Loading Class : "  + name); byte bytes[] = loadClassBytes(name); result = defineClass(name, bytes, 0, bytes.length); if(result == null)  throw new ClassNotFoundException(name); if(resolve) resolveClass(result); m_classes.put(name, result); return result; } }
7. Delegation Model  실습 ClassLoader Java 1.2 Style public class TestClassLoader extends ClassLoader { protected byte[] loadClassBytes(String name)  throws  ClassNotFoundException{ byte[] result = null; try{ FileInputStream in =  new FileInputStream("../Target/bin/" + name.replace('.', '/') + ".class"); ByteArrayOutputStream data =  new ByteArrayOutputStream(); int ch; while((ch = in.read()) != -1) data.write(ch); result = data.toByteArray(); } catch (Exception e){ throw new ClassNotFoundException(name); } return result; } protected Class findClass(String name)  throws ClassNotFoundException{ System.out.println(" 요청된  Class : " + name); System.out.println("TestClassLoader Loading Class : "  + name); byte bytes[] = loadClassBytes(name); return defineClass(name, bytes, 0, bytes.length); } }
//java.lanag.ClassLoader  일부 protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { // First, check if the class has already been loaded Class c = findLoadedClass(name); if (c == null) {   try { if (parent != null) {   c = parent.loadClass(name, false); } else {   c = findBootstrapClass0(name); }   } catch (ClassNotFoundException e) {   // If still not found, then invoke findClass in order   // to find the class.   c = findClass(name);   } } if (resolve) {   resolveClass(c); } return c; } 7. Delegation Model  실습 ClassLoader Java 1.2 Style
8. Standard Class Loader ClassLoader Standard ClassLoader
8. Standard Class Loader ClassLoader Java Options
 
public class ClassLoaderTree { public static void printClassLoaderTree(ClassLoader l) { if(l== null){ System.out.println(&quot;BootStrap ClassLoader&quot;); return; } ClassLoader p = l.getParent(); if ( p!= null) { printClassLoaderTree(p); } else { System.out.println(&quot;BootStrap ClassLoader&quot;); } String u = &quot;&quot;; if ( l instanceof URLClassLoader) { u = getURLs(  ((URLClassLoader)l).getURLs()); } // end of if () System.out.println(&quot;\t|\n&quot;+l+&quot; &quot; +u); }  8. Standard Class Loader ClassLoader ClassLoader Tree public static String getURLs(URL[] urls) { if ( urls == null) { return &quot;{}&quot;; } // end of if () StringBuffer b = new StringBuffer(&quot;{&quot;); for ( int i = 0;i<urls.length;i++) { b.append( urls[i] ).append(&quot;:&quot;); } // end of for () b.append(&quot;}&quot;); return b.toString(); } public static void main(String[] args) { ClassLoaderTree.printClassLoaderTree (ClassLoaderTree.class.getClassLoader()); } }
java -classpath ./bin ClassLoaderTree java -Djava.ext.dirs=./bin ClassLoaderTree java -Xbootclasspath:.\bin;D:\JDK\SDK13\jre\lib\rt.jar;... ClassLoaderTree 8. Standard Class Loader ClassLoader
What is a class loader? mechanism for loading classes into the JVM subclass of java.lang.ClassLoader Hierarchical structure Parent-child relationships Uses delegation Load requests delegated to parent Summary ClassLoader ClassLoader Basics ClassLoader-A Class-X ClassLoader-B ClassLoader-C Class-Y Class-Z Class-Z
Unidirectional   visibility Parent-loaded classes cannot see child-loaded classes Thread.getContextClassloader() Unique   Namespaces Classes referenced as classloader.classname Variety of class file locations File system Databases Remote server locations Database Remote Server File system ClassLoader-A Class-X ClassLoader-B ClassLoader-C Class-Y Class-Z Class-R Class-D Summary ClassLoader ClassLoader Basics
Bootstrap ClassLoader aka Primordial ClassLoader Created by the JVM Loads the JDK classes included in the JVM  (including  java.lang.ClassLoader ) Bootstrap   ClassLoader Extensions   ClassLoader JVM Application Shared Lib System ClassLoader System   ClassLoader loads classes specified in the classpath Loads applications, shared libraries, jars, etc. Extensions   ClassLoader Loads   JRE   classes JAR Summary ClassLoader ClassLoader Basics
Determine   Initial ClassLoader Delegate to Parent ClassLoader Class Loaded? No – Delegate to Parent Lastly – If class is not loaded in parent hierarchy then the Initial loader will attempt to load the class itself. JVM Class Loader A MyClass Class Loader B Class Loader C System ClassLoader Bootstrap ClassLoader Extension ClassLoader Summary ClassLoader Typical Loading Scenario
Copyright © 2004 Samsung SDS Co.,Ltd. All rights reserved  |  Confidential 목차 Class Loader Custom Class Loader Diagnosing
1. Java  내부의  ClassLoader Custom ClassLoader java.security.SecureClassLoader Java 2 Platform  보안부분 지원 Java.net.URLClassLoader Java 2 Runtime Library  내부에서 유일하게 실제 구현된  ClassLoader sun.applet.AppletClassLoader java.rmi.server.RMIClassLoader RMI runtime system 에서  class 를 마샬링하고 로딩하는 기능을 하는  wrapper class sun.rmi.server.LoaderHandler Class 에 대한 다리 역할 BootStrap ClassLoader Native Code 로 구현 Sun.boot.class.path  프로퍼티 참조 sun.misc.Launcher$ExtClassLoader Java.ext.dirs  프로퍼티 참조 sun.misc.Launcher$AppClassLoader
public static void main(String[] args) throws Exception { URL[] urlArray = { //new java.io.File(&quot;subdir.jar&quot;).toURL() // For loading-from-subdir.jar, uncomment the // above line and comment out the below line new java.io.File(&quot;subdir/&quot;).toURL() // For loading-from-subdirectory-subdir, // comment out the first line and uncomment // out this one }; URLClassLoader ucl = new URLClassLoader(urlArray); Object obj =  ucl.loadClass(&quot;Hello&quot;).newInstance(); // Hello should print &quot;Hello&quot; to the System.out stream } 1.URLClassLoader  사용 예 ClassLoader FileURLClient
public static void main(String[] args) throws Exception { URL[] urlArray = { new URL(&quot;http&quot;, &quot;www.javageeks.com&quot;, &quot;/SSJ/examples/&quot;) }; URLClassLoader ucl = new URLClassLoader(urlArray); Object obj =  ucl.loadClass(&quot;com.javageeks.util.Hello&quot;).newInstance(); // Hello should print &quot;Hello from JavaGeeks.com!&quot; to the // System.out stream } 1.URLClassLoader  사용 예 ClassLoader HttpURLClient
public static void main(String[] args) throws Exception { URL[] urlArray = { new URL(&quot;ftp&quot;, &quot;reader:password@www.javageeks.com&quot;,  &quot;/examples&quot;) }; URLClassLoader ucl = new URLClassLoader(urlArray); Object obj =  ucl.loadClass(&quot;Hello&quot;).newInstance(); } 1.URLClassLoader  사용 예 ClassLoader FTPURLClient
2. Why write a ClassLoader ? Custom ClassLoader The default ClassLoader only knows how to load class files from the local file system. 대부분의 경우에 만족 일반적으로  Local File System, Network 으로 부터  File 을  Loading 하는 것 이외에 다음과 같은 용도로 사용됨 Automatically verify a digital signature before executing untrusted code Transparently decrypt code with a user-defined password Create dynamically built classes customized to the user’s specific needs
3. Class Loader  확장 Custom ClassLoader findClass(…) Class  이름으로 부터  Byte Code 를 얻는데 사용 defineClass(…) 를 호출하여  Class Object 로 변환함 findResource(…) 주어진 임의의 이름에 대한  Byte Code 를 얻는데 사용 getResource(..)  에서 호출함 findLibrary(…) ClassLoader 가  native library 를 포함한  Class 를  Load 할 때 호출 Binary Data 가 아닌 절대 경로명 만 반환 protected Class findClass(String name)  throws ClassNotFoundException { throw new ClassNotFoundException(name); } protected URL findResource(String name) { return null; } protected String findLibrary(String libname) { return null; }
4. Class Loader  실습 Custom ClassLoader FileSystemClassLoader Local File System 에서  Class Byte Code 를 뽑아내는  ClassLoader  제작 .jar/.zip 에 대한 부분은 고려하지 않음 ClassLoader Class 를  extends 하여 구현 findClass(String name)  부분  overriding  구현 java -classpath ./bin -Dloader.dir=./bin/ FileSystemClassLoader
4. Class Loader  실습 Custom ClassLoader CompilingClassLoader When a class is requested, see if it exists on the disk, in the current directory, or in the appropriate subdirectory If the class is not available, but the source is, call the java compiler to generate the class file If the class file does exist, check to see if it is older than its source code. If it is older than the source, call the java compiler to generate the class file. If the compile fails, or if for any reason the class file could not be generated from existing source, throw a ClassNotFoundException If we still don’t have the class, maybe it’s in some other library, so call findSystemClass to see if that will work If we still don’t have the class, throw a ClassNotFoundException Otherwise, return the class java -classpath ./bin CCLRun Foo aaa bbb
4. Class Loader  실습 Custom ClassLoader HotDeploy java -classpath ./bin athena.loader.PointClient
4. Class Loader  실습 Custom ClassLoader Context Class Loader java -classpath ./bin DynamicLoader Echo aaa aaa aaa java -Djava.ext.dirs=./jar -classpath ./bin DynamicLoader Echo aaa aaa aaa java -Djava.ext.dirs=./jar -classpath ./bin FixedDynamicLoader Echo aaa aaa aaa
Copyright © 2004 Samsung SDS Co.,Ltd. All rights reserved  |  Confidential 목차 Class Loader Custom Class Loader Diagnosing
1. Class Not Found Diagnosing ClassNotFoundException  Used String representation (e.g. ClassLoader.LoadClass(className)) Typically, dependent Class is only visible to children  NoClassDefFoundError  Class existed at compile time Typically, dependent Class is only visible to children NoClassDefFoundException  An interesting phenomenon: this Exception is not in the JDK,  but it appears in dozens of topics in developer forums   EJB JAR STRUTS.JAR WAR B AppBForm WAR A AppAForm
ClassCastException same Class was loaded by two different ClassLoaders ClassCircularityError A Class and one of its dependents are both dependent on a third Class; different ClassLoaders are used to load that third Class 2. Class Cast Diagnosing EJB JAR public void utilityMethod (Object o) { ((Apple)o).doSomething(); } WAR B Apple WAR A Apple Apple CLASSCASTEXCEPTION
Place diagnostic statements in the application code Place diagnostic statements in a custom ClassLoader Place diagnostic statements in the core Java ClassLoaders. The -Xbootclasspath option makes to possible to supersede core Classes in a development environment. Use the –verbose option C:\>java -Xbootclasspath:C:\debug;j2sdk1.4.2_03\jre\lib\rt.jar  … [all other boot.class.path jars] app.java 3. Getting Diagnostic Info. Diagnosing
import java.io.File; import java.net.MalformedURLException; import java.net.URLClassLoader; import java.net.URL; import demo.Rabbit; /** * Instantiates and displays a Rabbit. */ public class TopHat { public static void main (String args[]) { try { // Create a ClassLoader that knows where to find demo. Rabbit URL rabbitURL = new File(&quot;rabbit.jar&quot;).toURL(); URL[] urls = new URL[]{rabbitURL}; URLClassLoader rabbitClassLoader = new URLClassLoader(urls,Thread.currentThread().getContextClassLoader()); // Set the ContextClassLoader for the current Thread so that it can find Rabbit.class Thread.currentThread().setContextClassLoader(rabbitClassLoader); // Make a Rabbit appear. System.out.println(new Rabbit());  } catch (MalformedURLException malformedURLException) {   malformedURLException.printStackTrace();   }  } } TopHat.java 3.  실습 Diagnosing
package demo; public class Rabbit { } Rabbit.java rabbit.jar C:\> jar tf rabbit.jar demo/ demo.Rabbit.class   C:\> javac –classpath rabbit.jar TopHat.java C:\> java –classpath ./bin TopHat Command Line Compilation Rabbit.java 3.  실습 Diagnosing
TopHat should instantiate and display a String  representation of a Rabbit, even though rabbit.jar is not referenced on the application classpath. Actual Behavior C:\>java TopHat Exception in thread &quot;main&quot; java.lang.NoClassDefFoundError: demo/Rabbit at TopHat.main(TopHat.java:23) Desired Behavior Desired Behavior Vs. Actual Behavior 3.  실습 Diagnosing
// Create a ClassLoader that knows where to find demo. Rabbit URL rabbitURL = new File(&quot;rabbit.jar&quot;).toURL(); URL[] urls = new URL[]{rabbitURL}; URLClassLoader rabbitClassLoader = new URLClassLoader(urls,Thread.currentThread().getContextClassLoader()); System.out.println(&quot;---> ClassLoader for TopHat: &quot; + TopHat.class.getClassLoader());  System.out.println(&quot;---> Before setting a custom ContextClassLoader, ContextClassLoader is: “); System.out.println( Thread.currentThread().getContextClassLoader()); // Set the ContextClassLoader for the current Thread so that it can find // Rabbit Thread.currentThread().setContextClassLoader(rabbitClassLoader); System.out.println(&quot;---> After setting a custom ContextClassLoader ContextClassLoader is: &quot;); System.out.println( Thread.currentThread().getContextClassLoader());  // Make a Rabbit appear. System.out.println(new Rabbit());   TopHat.java with Diagnostic Statements 3.  실습 Diagnosing
C:\>java TopHat ---> ClassLoader for TopHat: sun.misc.Launcher$AppClassLoader@e80a59 ---> Before setting a custom ContextClassLoader, ContextClassLoader is: sun.misc.Launcher$AppClassLoader@e80a59 ---> After setting a custom ContextClassLoader, ContextClassLoader is: [email_address] Exception in thread &quot;main&quot; java.lang.NoClassDefFoundError: demo/Rabbit at TopHat.main(TopHat.java:28) Output From Diagnostics in the Application 3.  실습 Diagnosing
protected Class findClass(final String name) throws ClassNotFoundException { try { return (Class)   AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() throws ClassNotFoundException {   String path = name.replace('.', '/').concat(&quot;.class&quot;);   Resource res = ucp.getResource(path, false);   if (res != null) {   try {   return defineClass(name, res);   } catch (IOException e) {   throw new ClassNotFoundException(name, e);   }   } else { System.out.println(“--   Looked in:”);   URL[] urls = getURLs();   for (int i = 0;i<urls.length;i++) {   System.out.println(urls[i]);     }   throw new ClassNotFoundException(name);   }   } }, acc); } catch (java.security.PrivilegedActionException pae) {   throw (ClassNotFoundException) pae.getException(); } } Diagnostics in java.net.URLClassLoader 3.  실습 Diagnosing
protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { Class c = findLoadedClass(name); if (c == null) {   try {   if (name.equals(&quot;demo.Rabbit&quot;))    System.out.println(&quot;---> &quot; + this + &quot;is asking parent (&quot; + parent + &quot;) to try to load &quot; + name + &quot;.&quot;);   if (parent != null) {   c = parent.loadClass(name, false); } else {   c = findBootstrapClass0(name); }   } catch (ClassNotFoundException e) {   // If still not found, then call findClass in order   // to find the class.   if (name.equals(&quot;demo.Rabbit&quot;))    System.out.println(&quot;---> &quot; + name + &quot; was not found by parent (&quot; + parent + &quot;), so &quot; + this +  &quot; will try.&quot;);   c = findClass(name);   } } if (resolve) {   resolveClass(c); } return c; }  void addClass(Class c) { if (c.toString().equals(&quot;class demo.Rabbit&quot;))    System.out.println(&quot;---> &quot; + this + &quot;loaded &quot; + c); classes.addElement(c); } private synchronized Class loadClassInternal(String name)throws ClassNotFoundException { if (name.equals(&quot;demo.Rabbit&quot;)) { System.out.println(&quot;JVM is requesting that &quot; +  this +&quot; load &quot;+ name);  }   return loadClass(name); } Diagnostics in java.lang.ClassLoader 3.  실습 Diagnosing
---> JVM is requesting that sun.misc.Launcher$AppClassLoader@e80a59 load demo.Rabbit --->  sun.misc.Launcher$AppClassLoader@e80a59  is asking parent (sun.misc.Launcher$ ExtClassLoader@1ff5ea7) to try to load demo.Rabbit. --->  sun.misc.Launcher$ExtClassLoader@1ff5ea7  is asking parent (null) to try to load demo.Rabbit. ---> demo.Rabbit was not found by parent (null), so sun.misc.Launcher$ExtClassLoader@1ff5ea7 will try. --> Looked in: file:/C:/j2sdk1.4.2_03/jre/lib/ext/dnsns.jar file:/C:/j2sdk1.4.2_03/jre/lib/ext/ldapsec.jar file:/C:/j2sdk1.4.2_03/jre/lib/ext/localedata.jar file:/C:/j2sdk1.4.2_03/jre/lib/ext/sunjce_provider.jar ---> demo.Rabbit was not found by parent (sun.misc.Launcher$ExtClassLoader@1ff5ea7), so sun.misc.Launcher$AppClassLoader@e80a59 will try. --> Looked in: file:/C:/ Exception in thread &quot;main&quot; java.lang.NoClassDefFoundError: demo/Rabbit at TopHat.main(TopHat.java:28) Output from Diagnostics in the Core Java Classes 3.  실습 Diagnosing java -Xbootclasspath/p:D:\Classloader\Util\bin -classpath ./bin TopHat
Regardless of how the Context ClassLoader is set , the classloader that loaded the calling Class will  always  be   used to load a requested Class when no ClassLoader is specified new ClassName() Class.forName(“package.ClassName”) Context ClassLoaders are used by JNDI JAXP Analysis 3.  실습 Diagnosing
ClassLoader loader = Thread.currentThread().getContextClassLoader(); loader.loadClass(“demo.Rabbit”).newInstance(); ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class.forName(“demo.Rabbit”,true, loader).newInstance(); –  or – Possible Solutions 3.  실습 Diagnosing
--->  [email_address]  is asking parent (sun.misc.Launcher$AppClassL oader@e80a59) to try to load demo.Rabbit. --->  sun.misc.Launcher$AppClassLoader@e80a59  is asking parent (sun.misc.Launcher$ ExtClassLoader@1ff5ea7) to try to load demo.Rabbit. --->  sun.misc.Launcher$ExtClassLoader@1ff5ea7  is asking parent (null) to try to  load demo.Rabbit. ---> demo.Rabbit was not found by parent (null), so sun.misc.Launcher$ExtClassLo ader@1ff5ea7 will try. --> Looked in: file:/C:/j2sdk1.4.2_03/jre/lib/ext/dnsns.jar file:/C:/j2sdk1.4.2_03/jre/lib/ext/ldapsec.jar file:/C:/j2sdk1.4.2_03/jre/lib/ext/localedata.jar file:/C:/j2sdk1.4.2_03/jre/lib/ext/sunjce_provider.jar ---> demo.Rabbit was not found by parent (sun.misc.Launcher$ExtClassLoader@1ff5e a7), so sun.misc.Launcher$AppClassLoader@e80a59 will try. --> Looked in: file:/C:/ ---> demo.Rabbit was not found by parent (sun.misc.Launcher$AppClassLoader@e80a5 9), so java.net.URLClassLoader@defa1a will try. --->  [email_address]  loaded class demo.Rabbit [email_address] Rabbit Appears 3.  실습 Diagnosing
감사합니다 . Copyright © 2004 Samsung SDS Co.,Ltd. All rights reserved  |  Confidential 대표전화 : +82-2-6484-0930 E-mail: chris_lee@samsung.com http://www.sds.samsung.co.kr

Class loader basic

  • 1.
    Copyright © 2004Samsung SDS Co.,Ltd. All rights reserved | Confidential ClassLoader 개요 강 명 철 2006.11 Core Java
  • 2.
    Copyright © 2004Samsung SDS Co.,Ltd. All rights reserved | Confidential 목차 Class Loader Custom Class Loader Diagnosing
  • 3.
    ClassLoader 1. JVMArchitecture
  • 4.
    ClassLoader Class loadingtakes place in two phases : Loading Linking or resolution 2. How Classes are Loaded ?
  • 5.
    3. Class Classin Java ClassLoader Instances of class java.lang.Class  represent classes and interfaces in a running Java application Class has no public constructors Any applications cannot instantiate it Class is automatically instantiated by JVM/class loader, when a class loading process is done Each instance of Class keeps a reference to a class loader that created it
  • 6.
    4. Class LoadingClassLoader When you define a class, say Foo, and initiate it ( to create its instance)  i.e. when you execute new Foo(); A local JVM (class loader) tries to Obtain the class definition of Foo Given the name of a class (i.e. Foo), the class loader locates a binary representation of Foo’s class definition Typically, it transforms the class name into a file name, and reads a class file of that name (e.g. Foo.class) from the local file system If this step fails, JVM return a ClassDefNotFound exception Parse the obtained class definition into internal structures in the method area of the JVM The method area is a logical area of memory in the JVM that is used to store information about loaded classes/interfaces Create an instance of Class, which is associated with Foo These 3 activities are collectively called class loading. After successful class loading, an instance of Foo is created and returned
  • 7.
    5. Class Loadersin JVM ClassLoader Every JVM has two types of class loaders Default class loaders Bootstrap class loader Used to find and load a set of standard class libraries (i.e. java.* classes) that are located in $JAVA_HOME$/jre/lib -> e.g. $JAVA_HOME$/jre/lib/rt.jar Extension class loader Used to find and load a set of extension class libraries (i.e. javax.* classes) that are located in $JAVA_HOME$/jre/lib/ext System class loader (java.lang.Classloader) Used to find and load user-defined classes Custom class loaders If a user wants to change the behavior of system class loader, the user can extend java.lang.Classloader as a Java class. The class is called a custom class loader A custom class loader overloads the methods defined in java.lang.Classloader to implement its own class loading behavior. Different custom class loaders can specialize different class loading behaviors (policies)
  • 8.
    6. Class LoadersRules ClassLoader Consistency Rule Class loaders never load the same class more than once Delegation Rule Class loaders always consult a parent class loader before loading a class Visibility Rule Classes can only “see” other classes loaded by their class loader’s delegation, the recursive set of a class’s loader and all its parent loaders
  • 9.
    6. Visibility ClassLoader
  • 10.
    6. Visibility 실습 ClassLoader Java Statics public class Dummy { public static int staticCount = 0; public Dummy(){ staticCount++; System.out.println(&quot;Instance #&quot; + staticCount + &quot; constructed.&quot;); } } public class StaticTest { public static void main(String[] args) { new Dummy(); new Dummy(); new Dummy(); new Dummy(); new Dummy(); } } Instance #1 constructed. Instance #2 constructed. Instance #3 constructed. Instance #4 constructed. Instance #5 constructed.
  • 11.
    6. Visibility 실습 ClassLoader Java Statics public class Dummy { public static int staticCount = 0; public Dummy(){ staticCount++; System.out.println(&quot;Instance #&quot; + staticCount + &quot; constructed.&quot;); } } public class StaticTestClassLoader { public static void main(String[] args) throws Exception { URL[] url = {new File(&quot;../target/bin&quot;).toURL()}; URLClassLoader cl1 = new URLClassLoader(url); URLClassLoader cl2 = new URLClassLoader(url); URLClassLoader cl3 = new URLClassLoader(url); cl1.loadClass(&quot;Dummy&quot;).newInstance(); cl2.loadClass(&quot;Dummy&quot;).newInstance(); cl3.loadClass(&quot;Dummy&quot;).newInstance(); } } Instance #1 constructed. Instance #1 constructed. Instance #1 constructed.
  • 12.
    7. Delegation ModelClassLoader class NetworkClassLoader extends ClassLoader { String host; int port; public Class findClass(String name) { byte[] b = loadClassData(name); return defineClass(name, b, 0, b.length); } private byte[] loadClassData(String name) { // load the class data from the connection &nbsp;.&nbsp;.&nbsp;. } }
  • 13.
  • 14.
    7. Delegation Model 실습 ClassLoader Java 1.1 Style public class TestClassLoader extends ClassLoader { protected Hashtable m_classes = new Hashtable(); protected boolean m_cacle = false; protected byte[] loadClassBytes(String name) throws ClassNotFoundException{ byte[] result = null; try{ FileInputStream in = new FileInputStream(&quot;../Target/bin/&quot; + name.replace('.', '/') + &quot;.class&quot;); ByteArrayOutputStream data = new ByteArrayOutputStream(); int ch; while((ch = in.read()) != -1) data.write(ch); result = data.toByteArray(); } catch (Exception e){ throw new ClassNotFoundException(name); } return result; } protected synchronized Class loadClass (String name, boolean resolve) throws ClassNotFoundException{ System.out.println(&quot; 요청된 Class : &quot; + name); Class result = (Class)m_classes.get(name); try{ if(result==null) return super.findSystemClass(name); else return result; } catch(Exception e) {} System.out.println(&quot;TestClassLoader Loading Class : &quot; + name); byte bytes[] = loadClassBytes(name); result = defineClass(name, bytes, 0, bytes.length); if(result == null) throw new ClassNotFoundException(name); if(resolve) resolveClass(result); m_classes.put(name, result); return result; } }
  • 15.
    7. Delegation Model 실습 ClassLoader Java 1.2 Style public class TestClassLoader extends ClassLoader { protected byte[] loadClassBytes(String name) throws ClassNotFoundException{ byte[] result = null; try{ FileInputStream in = new FileInputStream(&quot;../Target/bin/&quot; + name.replace('.', '/') + &quot;.class&quot;); ByteArrayOutputStream data = new ByteArrayOutputStream(); int ch; while((ch = in.read()) != -1) data.write(ch); result = data.toByteArray(); } catch (Exception e){ throw new ClassNotFoundException(name); } return result; } protected Class findClass(String name) throws ClassNotFoundException{ System.out.println(&quot; 요청된 Class : &quot; + name); System.out.println(&quot;TestClassLoader Loading Class : &quot; + name); byte bytes[] = loadClassBytes(name); return defineClass(name, bytes, 0, bytes.length); } }
  • 16.
    //java.lanag.ClassLoader 일부protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { // First, check if the class has already been loaded Class c = findLoadedClass(name); if (c == null) { try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClass0(name); } } catch (ClassNotFoundException e) { // If still not found, then invoke findClass in order // to find the class. c = findClass(name); } } if (resolve) { resolveClass(c); } return c; } 7. Delegation Model 실습 ClassLoader Java 1.2 Style
  • 17.
    8. Standard ClassLoader ClassLoader Standard ClassLoader
  • 18.
    8. Standard ClassLoader ClassLoader Java Options
  • 19.
  • 20.
    public class ClassLoaderTree{ public static void printClassLoaderTree(ClassLoader l) { if(l== null){ System.out.println(&quot;BootStrap ClassLoader&quot;); return; } ClassLoader p = l.getParent(); if ( p!= null) { printClassLoaderTree(p); } else { System.out.println(&quot;BootStrap ClassLoader&quot;); } String u = &quot;&quot;; if ( l instanceof URLClassLoader) { u = getURLs( ((URLClassLoader)l).getURLs()); } // end of if () System.out.println(&quot;\t|\n&quot;+l+&quot; &quot; +u); } 8. Standard Class Loader ClassLoader ClassLoader Tree public static String getURLs(URL[] urls) { if ( urls == null) { return &quot;{}&quot;; } // end of if () StringBuffer b = new StringBuffer(&quot;{&quot;); for ( int i = 0;i<urls.length;i++) { b.append( urls[i] ).append(&quot;:&quot;); } // end of for () b.append(&quot;}&quot;); return b.toString(); } public static void main(String[] args) { ClassLoaderTree.printClassLoaderTree (ClassLoaderTree.class.getClassLoader()); } }
  • 21.
    java -classpath ./binClassLoaderTree java -Djava.ext.dirs=./bin ClassLoaderTree java -Xbootclasspath:.\bin;D:\JDK\SDK13\jre\lib\rt.jar;... ClassLoaderTree 8. Standard Class Loader ClassLoader
  • 22.
    What is aclass loader? mechanism for loading classes into the JVM subclass of java.lang.ClassLoader Hierarchical structure Parent-child relationships Uses delegation Load requests delegated to parent Summary ClassLoader ClassLoader Basics ClassLoader-A Class-X ClassLoader-B ClassLoader-C Class-Y Class-Z Class-Z
  • 23.
    Unidirectional visibility Parent-loaded classes cannot see child-loaded classes Thread.getContextClassloader() Unique Namespaces Classes referenced as classloader.classname Variety of class file locations File system Databases Remote server locations Database Remote Server File system ClassLoader-A Class-X ClassLoader-B ClassLoader-C Class-Y Class-Z Class-R Class-D Summary ClassLoader ClassLoader Basics
  • 24.
    Bootstrap ClassLoader akaPrimordial ClassLoader Created by the JVM Loads the JDK classes included in the JVM (including java.lang.ClassLoader ) Bootstrap ClassLoader Extensions ClassLoader JVM Application Shared Lib System ClassLoader System ClassLoader loads classes specified in the classpath Loads applications, shared libraries, jars, etc. Extensions ClassLoader Loads JRE classes JAR Summary ClassLoader ClassLoader Basics
  • 25.
    Determine Initial ClassLoader Delegate to Parent ClassLoader Class Loaded? No – Delegate to Parent Lastly – If class is not loaded in parent hierarchy then the Initial loader will attempt to load the class itself. JVM Class Loader A MyClass Class Loader B Class Loader C System ClassLoader Bootstrap ClassLoader Extension ClassLoader Summary ClassLoader Typical Loading Scenario
  • 26.
    Copyright © 2004Samsung SDS Co.,Ltd. All rights reserved | Confidential 목차 Class Loader Custom Class Loader Diagnosing
  • 27.
    1. Java 내부의 ClassLoader Custom ClassLoader java.security.SecureClassLoader Java 2 Platform 보안부분 지원 Java.net.URLClassLoader Java 2 Runtime Library 내부에서 유일하게 실제 구현된 ClassLoader sun.applet.AppletClassLoader java.rmi.server.RMIClassLoader RMI runtime system 에서 class 를 마샬링하고 로딩하는 기능을 하는 wrapper class sun.rmi.server.LoaderHandler Class 에 대한 다리 역할 BootStrap ClassLoader Native Code 로 구현 Sun.boot.class.path 프로퍼티 참조 sun.misc.Launcher$ExtClassLoader Java.ext.dirs 프로퍼티 참조 sun.misc.Launcher$AppClassLoader
  • 28.
    public static voidmain(String[] args) throws Exception { URL[] urlArray = { //new java.io.File(&quot;subdir.jar&quot;).toURL() // For loading-from-subdir.jar, uncomment the // above line and comment out the below line new java.io.File(&quot;subdir/&quot;).toURL() // For loading-from-subdirectory-subdir, // comment out the first line and uncomment // out this one }; URLClassLoader ucl = new URLClassLoader(urlArray); Object obj = ucl.loadClass(&quot;Hello&quot;).newInstance(); // Hello should print &quot;Hello&quot; to the System.out stream } 1.URLClassLoader 사용 예 ClassLoader FileURLClient
  • 29.
    public static voidmain(String[] args) throws Exception { URL[] urlArray = { new URL(&quot;http&quot;, &quot;www.javageeks.com&quot;, &quot;/SSJ/examples/&quot;) }; URLClassLoader ucl = new URLClassLoader(urlArray); Object obj = ucl.loadClass(&quot;com.javageeks.util.Hello&quot;).newInstance(); // Hello should print &quot;Hello from JavaGeeks.com!&quot; to the // System.out stream } 1.URLClassLoader 사용 예 ClassLoader HttpURLClient
  • 30.
    public static voidmain(String[] args) throws Exception { URL[] urlArray = { new URL(&quot;ftp&quot;, &quot;reader:password@www.javageeks.com&quot;, &quot;/examples&quot;) }; URLClassLoader ucl = new URLClassLoader(urlArray); Object obj = ucl.loadClass(&quot;Hello&quot;).newInstance(); } 1.URLClassLoader 사용 예 ClassLoader FTPURLClient
  • 31.
    2. Why writea ClassLoader ? Custom ClassLoader The default ClassLoader only knows how to load class files from the local file system. 대부분의 경우에 만족 일반적으로 Local File System, Network 으로 부터 File 을 Loading 하는 것 이외에 다음과 같은 용도로 사용됨 Automatically verify a digital signature before executing untrusted code Transparently decrypt code with a user-defined password Create dynamically built classes customized to the user’s specific needs
  • 32.
    3. Class Loader 확장 Custom ClassLoader findClass(…) Class 이름으로 부터 Byte Code 를 얻는데 사용 defineClass(…) 를 호출하여 Class Object 로 변환함 findResource(…) 주어진 임의의 이름에 대한 Byte Code 를 얻는데 사용 getResource(..) 에서 호출함 findLibrary(…) ClassLoader 가 native library 를 포함한 Class 를 Load 할 때 호출 Binary Data 가 아닌 절대 경로명 만 반환 protected Class findClass(String name) throws ClassNotFoundException { throw new ClassNotFoundException(name); } protected URL findResource(String name) { return null; } protected String findLibrary(String libname) { return null; }
  • 33.
    4. Class Loader 실습 Custom ClassLoader FileSystemClassLoader Local File System 에서 Class Byte Code 를 뽑아내는 ClassLoader 제작 .jar/.zip 에 대한 부분은 고려하지 않음 ClassLoader Class 를 extends 하여 구현 findClass(String name) 부분 overriding 구현 java -classpath ./bin -Dloader.dir=./bin/ FileSystemClassLoader
  • 34.
    4. Class Loader 실습 Custom ClassLoader CompilingClassLoader When a class is requested, see if it exists on the disk, in the current directory, or in the appropriate subdirectory If the class is not available, but the source is, call the java compiler to generate the class file If the class file does exist, check to see if it is older than its source code. If it is older than the source, call the java compiler to generate the class file. If the compile fails, or if for any reason the class file could not be generated from existing source, throw a ClassNotFoundException If we still don’t have the class, maybe it’s in some other library, so call findSystemClass to see if that will work If we still don’t have the class, throw a ClassNotFoundException Otherwise, return the class java -classpath ./bin CCLRun Foo aaa bbb
  • 35.
    4. Class Loader 실습 Custom ClassLoader HotDeploy java -classpath ./bin athena.loader.PointClient
  • 36.
    4. Class Loader 실습 Custom ClassLoader Context Class Loader java -classpath ./bin DynamicLoader Echo aaa aaa aaa java -Djava.ext.dirs=./jar -classpath ./bin DynamicLoader Echo aaa aaa aaa java -Djava.ext.dirs=./jar -classpath ./bin FixedDynamicLoader Echo aaa aaa aaa
  • 37.
    Copyright © 2004Samsung SDS Co.,Ltd. All rights reserved | Confidential 목차 Class Loader Custom Class Loader Diagnosing
  • 38.
    1. Class NotFound Diagnosing ClassNotFoundException Used String representation (e.g. ClassLoader.LoadClass(className)) Typically, dependent Class is only visible to children NoClassDefFoundError Class existed at compile time Typically, dependent Class is only visible to children NoClassDefFoundException An interesting phenomenon: this Exception is not in the JDK, but it appears in dozens of topics in developer forums  EJB JAR STRUTS.JAR WAR B AppBForm WAR A AppAForm
  • 39.
    ClassCastException same Classwas loaded by two different ClassLoaders ClassCircularityError A Class and one of its dependents are both dependent on a third Class; different ClassLoaders are used to load that third Class 2. Class Cast Diagnosing EJB JAR public void utilityMethod (Object o) { ((Apple)o).doSomething(); } WAR B Apple WAR A Apple Apple CLASSCASTEXCEPTION
  • 40.
    Place diagnostic statementsin the application code Place diagnostic statements in a custom ClassLoader Place diagnostic statements in the core Java ClassLoaders. The -Xbootclasspath option makes to possible to supersede core Classes in a development environment. Use the –verbose option C:\>java -Xbootclasspath:C:\debug;j2sdk1.4.2_03\jre\lib\rt.jar … [all other boot.class.path jars] app.java 3. Getting Diagnostic Info. Diagnosing
  • 41.
    import java.io.File; importjava.net.MalformedURLException; import java.net.URLClassLoader; import java.net.URL; import demo.Rabbit; /** * Instantiates and displays a Rabbit. */ public class TopHat { public static void main (String args[]) { try { // Create a ClassLoader that knows where to find demo. Rabbit URL rabbitURL = new File(&quot;rabbit.jar&quot;).toURL(); URL[] urls = new URL[]{rabbitURL}; URLClassLoader rabbitClassLoader = new URLClassLoader(urls,Thread.currentThread().getContextClassLoader()); // Set the ContextClassLoader for the current Thread so that it can find Rabbit.class Thread.currentThread().setContextClassLoader(rabbitClassLoader); // Make a Rabbit appear. System.out.println(new Rabbit()); } catch (MalformedURLException malformedURLException) { malformedURLException.printStackTrace(); } } } TopHat.java 3. 실습 Diagnosing
  • 42.
    package demo; publicclass Rabbit { } Rabbit.java rabbit.jar C:\> jar tf rabbit.jar demo/ demo.Rabbit.class C:\> javac –classpath rabbit.jar TopHat.java C:\> java –classpath ./bin TopHat Command Line Compilation Rabbit.java 3. 실습 Diagnosing
  • 43.
    TopHat should instantiateand display a String representation of a Rabbit, even though rabbit.jar is not referenced on the application classpath. Actual Behavior C:\>java TopHat Exception in thread &quot;main&quot; java.lang.NoClassDefFoundError: demo/Rabbit at TopHat.main(TopHat.java:23) Desired Behavior Desired Behavior Vs. Actual Behavior 3. 실습 Diagnosing
  • 44.
    // Create aClassLoader that knows where to find demo. Rabbit URL rabbitURL = new File(&quot;rabbit.jar&quot;).toURL(); URL[] urls = new URL[]{rabbitURL}; URLClassLoader rabbitClassLoader = new URLClassLoader(urls,Thread.currentThread().getContextClassLoader()); System.out.println(&quot;---> ClassLoader for TopHat: &quot; + TopHat.class.getClassLoader()); System.out.println(&quot;---> Before setting a custom ContextClassLoader, ContextClassLoader is: “); System.out.println( Thread.currentThread().getContextClassLoader()); // Set the ContextClassLoader for the current Thread so that it can find // Rabbit Thread.currentThread().setContextClassLoader(rabbitClassLoader); System.out.println(&quot;---> After setting a custom ContextClassLoader ContextClassLoader is: &quot;); System.out.println( Thread.currentThread().getContextClassLoader()); // Make a Rabbit appear. System.out.println(new Rabbit()); TopHat.java with Diagnostic Statements 3. 실습 Diagnosing
  • 45.
    C:\>java TopHat --->ClassLoader for TopHat: sun.misc.Launcher$AppClassLoader@e80a59 ---> Before setting a custom ContextClassLoader, ContextClassLoader is: sun.misc.Launcher$AppClassLoader@e80a59 ---> After setting a custom ContextClassLoader, ContextClassLoader is: [email_address] Exception in thread &quot;main&quot; java.lang.NoClassDefFoundError: demo/Rabbit at TopHat.main(TopHat.java:28) Output From Diagnostics in the Application 3. 실습 Diagnosing
  • 46.
    protected Class findClass(finalString name) throws ClassNotFoundException { try { return (Class) AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() throws ClassNotFoundException { String path = name.replace('.', '/').concat(&quot;.class&quot;); Resource res = ucp.getResource(path, false); if (res != null) { try { return defineClass(name, res); } catch (IOException e) { throw new ClassNotFoundException(name, e); } } else { System.out.println(“--  Looked in:”); URL[] urls = getURLs(); for (int i = 0;i<urls.length;i++) { System.out.println(urls[i]); } throw new ClassNotFoundException(name); } } }, acc); } catch (java.security.PrivilegedActionException pae) { throw (ClassNotFoundException) pae.getException(); } } Diagnostics in java.net.URLClassLoader 3. 실습 Diagnosing
  • 47.
    protected synchronized ClassloadClass(String name, boolean resolve) throws ClassNotFoundException { Class c = findLoadedClass(name); if (c == null) { try { if (name.equals(&quot;demo.Rabbit&quot;)) System.out.println(&quot;---> &quot; + this + &quot;is asking parent (&quot; + parent + &quot;) to try to load &quot; + name + &quot;.&quot;); if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClass0(name); } } catch (ClassNotFoundException e) { // If still not found, then call findClass in order // to find the class. if (name.equals(&quot;demo.Rabbit&quot;)) System.out.println(&quot;---> &quot; + name + &quot; was not found by parent (&quot; + parent + &quot;), so &quot; + this + &quot; will try.&quot;); c = findClass(name); } } if (resolve) { resolveClass(c); } return c; } void addClass(Class c) { if (c.toString().equals(&quot;class demo.Rabbit&quot;)) System.out.println(&quot;---> &quot; + this + &quot;loaded &quot; + c); classes.addElement(c); } private synchronized Class loadClassInternal(String name)throws ClassNotFoundException { if (name.equals(&quot;demo.Rabbit&quot;)) { System.out.println(&quot;JVM is requesting that &quot; + this +&quot; load &quot;+ name); } return loadClass(name); } Diagnostics in java.lang.ClassLoader 3. 실습 Diagnosing
  • 48.
    ---> JVM isrequesting that sun.misc.Launcher$AppClassLoader@e80a59 load demo.Rabbit ---> sun.misc.Launcher$AppClassLoader@e80a59 is asking parent (sun.misc.Launcher$ ExtClassLoader@1ff5ea7) to try to load demo.Rabbit. ---> sun.misc.Launcher$ExtClassLoader@1ff5ea7 is asking parent (null) to try to load demo.Rabbit. ---> demo.Rabbit was not found by parent (null), so sun.misc.Launcher$ExtClassLoader@1ff5ea7 will try. --> Looked in: file:/C:/j2sdk1.4.2_03/jre/lib/ext/dnsns.jar file:/C:/j2sdk1.4.2_03/jre/lib/ext/ldapsec.jar file:/C:/j2sdk1.4.2_03/jre/lib/ext/localedata.jar file:/C:/j2sdk1.4.2_03/jre/lib/ext/sunjce_provider.jar ---> demo.Rabbit was not found by parent (sun.misc.Launcher$ExtClassLoader@1ff5ea7), so sun.misc.Launcher$AppClassLoader@e80a59 will try. --> Looked in: file:/C:/ Exception in thread &quot;main&quot; java.lang.NoClassDefFoundError: demo/Rabbit at TopHat.main(TopHat.java:28) Output from Diagnostics in the Core Java Classes 3. 실습 Diagnosing java -Xbootclasspath/p:D:\Classloader\Util\bin -classpath ./bin TopHat
  • 49.
    Regardless of howthe Context ClassLoader is set , the classloader that loaded the calling Class will always be used to load a requested Class when no ClassLoader is specified new ClassName() Class.forName(“package.ClassName”) Context ClassLoaders are used by JNDI JAXP Analysis 3. 실습 Diagnosing
  • 50.
    ClassLoader loader =Thread.currentThread().getContextClassLoader(); loader.loadClass(“demo.Rabbit”).newInstance(); ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class.forName(“demo.Rabbit”,true, loader).newInstance(); – or – Possible Solutions 3. 실습 Diagnosing
  • 51.
    ---> [email_address] is asking parent (sun.misc.Launcher$AppClassL oader@e80a59) to try to load demo.Rabbit. ---> sun.misc.Launcher$AppClassLoader@e80a59 is asking parent (sun.misc.Launcher$ ExtClassLoader@1ff5ea7) to try to load demo.Rabbit. ---> sun.misc.Launcher$ExtClassLoader@1ff5ea7 is asking parent (null) to try to load demo.Rabbit. ---> demo.Rabbit was not found by parent (null), so sun.misc.Launcher$ExtClassLo ader@1ff5ea7 will try. --> Looked in: file:/C:/j2sdk1.4.2_03/jre/lib/ext/dnsns.jar file:/C:/j2sdk1.4.2_03/jre/lib/ext/ldapsec.jar file:/C:/j2sdk1.4.2_03/jre/lib/ext/localedata.jar file:/C:/j2sdk1.4.2_03/jre/lib/ext/sunjce_provider.jar ---> demo.Rabbit was not found by parent (sun.misc.Launcher$ExtClassLoader@1ff5e a7), so sun.misc.Launcher$AppClassLoader@e80a59 will try. --> Looked in: file:/C:/ ---> demo.Rabbit was not found by parent (sun.misc.Launcher$AppClassLoader@e80a5 9), so java.net.URLClassLoader@defa1a will try. ---> [email_address] loaded class demo.Rabbit [email_address] Rabbit Appears 3. 실습 Diagnosing
  • 52.
    감사합니다 . Copyright© 2004 Samsung SDS Co.,Ltd. All rights reserved | Confidential 대표전화 : +82-2-6484-0930 E-mail: chris_lee@samsung.com http://www.sds.samsung.co.kr