Задача: Загрузчик классов
Исходник: Пример эмуляции загрузки байт-кода класса программы, язык: java [code #193, hits: 8927]
автор: - [добавлен: 02.05.2007]
  1. /*
  2. * Copyright (c) Ian F. Darwin, http://www.darwinsys.com/, 1996-2002.
  3. * All rights reserved. Software written by Ian F. Darwin and others.
  4. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  17. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  18. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
  19. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. * POSSIBILITY OF SUCH DAMAGE.
  26. *
  27. * Java, the Duke mascot, and all variants of Sun's Java "steaming coffee
  28. * cup" logo are trademarks of Sun Microsystems. Sun's, and James Gosling's,
  29. * pioneering role in inventing and promulgating (and standardizing) the Java
  30. * language and environment is gratefully acknowledged.
  31. *
  32. * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
  33. * inventing predecessor languages C and C++ is also gratefully acknowledged.
  34. */
  35.  
  36. import java.lang.reflect.InvocationTargetException;
  37. import java.lang.reflect.Method;
  38. import java.util.Hashtable;
  39.  
  40. /**
  41. * Demonstration of a ClassLoader
  42. */
  43. public class ClassLoaderDemo1 extends ClassLoader {
  44. /** The Hashtable to keep track of classes, to avoid re-loading them */
  45. protected Hashtable cache = new Hashtable();
  46.  
  47. /** data's expected length */
  48. private final int dataLength = 433;
  49.  
  50. /** data, obtained by dumping a compiled .class file */
  51. private int[] data = { 202, 254, 186, 190, 0, 3, 0, 45, 0, 31, 8, 0, 20, 7,
  52. 0, 17, 7, 0, 25, 7, 0, 26, 7, 0, 27, 10, 0, 4, 0, 9, 9, 0, 5, 0,
  53. 10, 10, 0, 3, 0, 11, 12, 0, 14, 0, 12, 12, 0, 28, 0, 22, 12, 0, 29,
  54. 0, 13, 1, 0, 3, 40, 41, 86, 1, 0, 21, 40, 76, 106, 97, 118, 97, 47,
  55. 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 86, 1,
  56. 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 4, 67, 111, 100, 101, 1, 0,
  57. 13, 67, 111, 110, 115, 116, 97, 110, 116, 86, 97, 108, 117, 101, 1,
  58. 0, 4, 68, 101, 109, 111, 1, 0, 9, 68, 101, 109, 111, 46, 106, 97,
  59. 118, 97, 1, 0, 10, 69, 120, 99, 101, 112, 116, 105, 111, 110, 115,
  60. 1, 0, 10, 72, 101, 108, 108, 111, 32, 74, 97, 118, 97, 1, 0, 15,
  61. 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108,
  62. 101, 1, 0, 21, 76, 106, 97, 118, 97, 47, 105, 111, 47, 80, 114,
  63. 105, 110, 116, 83, 116, 114, 101, 97, 109, 59, 1, 0, 14, 76, 111,
  64. 99, 97, 108, 86, 97, 114, 105, 97, 98, 108, 101, 115, 1, 0, 10, 83,
  65. 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 19, 106, 97, 118,
  66. 97, 47, 105, 111, 47, 80, 114, 105, 110, 116, 83, 116, 114, 101,
  67. 97, 109, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79,
  68. 98, 106, 101, 99, 116, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97,
  69. 110, 103, 47, 83, 121, 115, 116, 101, 109, 1, 0, 3, 111, 117, 116,
  70. 1, 0, 7, 112, 114, 105, 110, 116, 108, 110, 1, 0, 4, 116, 101, 115,
  71. 116, 0, 33, 0, 2, 0, 4, 0, 0, 0, 0, 0, 2, 0, 9, 0, 30, 0, 12, 0, 1,
  72. 0, 15, 0, 0, 0, 37, 0, 2, 0, 0, 0, 0, 0, 9, 178, 0, 7, 18, 1, 182,
  73. 0, 8, 177, 0, 0, 0, 1, 0, 21, 0, 0, 0, 10, 0, 2, 0, 0, 0, 9, 0, 8,
  74. 0, 8, 0, 1, 0, 14, 0, 12, 0, 1, 0, 15, 0, 0, 0, 29, 0, 1, 0, 1, 0,
  75. 0, 0, 5, 42, 183, 0, 6, 177, 0, 0, 0, 1, 0, 21, 0, 0, 0, 6, 0, 1,
  76. 0, 0, 0, 7, 0, 1, 0, 24, 0, 0, 0, 2, 0, 18 };
  77.  
  78. /** "load", that is, make up, the data for the class */
  79. private byte[] genClassData(String name) {
  80. if (dataLength != data.length)
  81. throw new IllegalArgumentException("data corrupt");
  82. byte[] bd = new byte[data.length];
  83. for (int i = 0; i < bd.length; i++)
  84. bd[i] = (byte) data[i];
  85. return bd;
  86. }
  87.  
  88. public synchronized Class loadClass(String name, boolean resolve)
  89. /**
  90. * We can expect to be called to resolve at least demo's superclass
  91. * (java.lang.Object). Fortunatetely, we can just use
  92. * super.findSystemClass() to load such things...
  93. */
  94. if (name.startsWith("java.")) {
  95. System.out.println("loadClass: SystemLoading " + name);
  96. return findSystemClass(name);
  97. }
  98. Class c = (Class) cache.get(name);
  99. if (c == null) {
  100. System.out.println("loadClass: About to genClassData " + name);
  101. byte mydata[] = genClassData(name);
  102. System.out.println("loadClass: About to defineClass " + name);
  103. c = defineClass(name, mydata, 0, mydata.length);
  104. System.out.println("loadClass: storing " + name + " in cache.");
  105. cache.put(name, c);
  106. } else
  107. System.out.println("loadClass: found " + name + " in cache.");
  108. if (resolve) {
  109. System.out.println("loadClass: About to resolveClass " + name);
  110. resolveClass(c);
  111. }
  112. return c;
  113. }
  114.  
  115. public static void main(String[] argv) {
  116. System.out.println("ClassLoaderDemo1 starting");
  117. ClassLoaderDemo1 loader = new ClassLoaderDemo1();
  118. Class c = null;
  119. Object demo;
  120. try {
  121. /* Load the "Demo" class from memory */
  122.  
  123. System.out.println("About to load class Demo");
  124. c = loader.loadClass("Demo", true);
  125. System.out.println("About to instantiate class Demo");
  126. demo = c.newInstance();
  127. System.out.println("Got Demo class loaded: " + demo);
  128.  
  129. /* Now try to call a method */
  130.  
  131. Method mi = c.getMethod("test", null);
  132. mi.invoke(demo, null);
  133.  
  134. // The invoked method threw an exception. We get it
  135. // wrapped up inside another exception, hence the
  136. // extra call here:
  137. e.getTargetException().printStackTrace();
  138. System.out.println("Could not run test method");
  139. } catch (Exception e) {
  140. e.printStackTrace();
  141. System.out.println("Could not run test method");
  142. }
  143.  
  144. /**
  145. * Try to load some arbitrary class, to see if our ClassLoader gets
  146. * called.
  147. */
  148. System.out.println("Trying to load an unrelated class");
  149. java.awt.image.DirectColorModel jnk = new java.awt.image.DirectColorModel(
  150. 24, 8, 8, 8);
  151. System.out
  152. .println("Load an unrelated class - was your ClassLoader called?");
  153.  
  154. /** Try to instantiate a second ClassLoader */
  155. System.out.println("Trying to install another ClassLoader");
  156. ClassLoaderDemo1 loader2 = new ClassLoaderDemo1();
  157. System.out.println("Instantiated another ClassLoader...");
  158. }
  159. }
Массив байтов эмулирует данные, которые могут получены из каких-угодно источников и потоков.
Данные представляют из себя байт-код простого класса.
Таким образом, байты считываются. Полученный байт-код нового класса динамически подгружается в jvm, и далее просто инстанцируется экземпляр.
Тестировалось на: java 1.5.0_04

+добавить реализацию