You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Viewer.java 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. Alternatively, the contents of this file may be used under
  8. * the terms of the GNU Lesser General Public License Version 2.1 or later.
  9. *
  10. * Software distributed under the License is distributed on an "AS IS" basis,
  11. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. * for the specific language governing rights and limitations under the
  13. * License.
  14. */
  15. package javassist.tools.web;
  16. import java.io.*;
  17. import java.net.*;
  18. /**
  19. * A sample applet viewer.
  20. *
  21. * <p>This is a sort of applet viewer that can run any program even if
  22. * the main class is not a subclass of <code>Applet</code>.
  23. * This viewwer first calls <code>main()</code> in the main class.
  24. *
  25. * <p>To run, you should type:
  26. *
  27. * <ul><code>% java javassist.tools.web.Viewer <i>host port</i> Main arg1, ...</code></ul>
  28. *
  29. * <p>This command calls <code>Main.main()</code> with <code>arg1,...</code>
  30. * All classes including <code>Main</code> are fetched from
  31. * a server http://<i>host</i>:<i>port</i>.
  32. * Only the class file for <code>Viewer</code> must exist
  33. * on a local file system at the client side; even other
  34. * <code>javassist.*</code> classes are not needed at the client side.
  35. * <code>Viewer</code> uses only Java core API classes.
  36. *
  37. * <p>Note: since a <code>Viewer</code> object is a class loader,
  38. * a program loaded by this object can call a method in <code>Viewer</code>.
  39. * For example, you can write something like this:
  40. *
  41. * <ul><pre>
  42. * Viewer v = (Viewer)this.getClass().getClassLoader();
  43. * String port = v.getPort();
  44. * </pre></ul>
  45. *
  46. */
  47. public class Viewer extends ClassLoader {
  48. private String server;
  49. private int port;
  50. /**
  51. * Starts a program.
  52. */
  53. public static void main(String[] args) throws Throwable {
  54. if (args.length >= 3) {
  55. Viewer cl = new Viewer(args[0], Integer.parseInt(args[1]));
  56. String[] args2 = new String[args.length - 3];
  57. System.arraycopy(args, 3, args2, 0, args.length - 3);
  58. cl.run(args[2], args2);
  59. }
  60. else
  61. System.err.println(
  62. "Usage: java javassist.tools.web.Viewer <host> <port> class [args ...]");
  63. }
  64. /**
  65. * Constructs a viewer.
  66. *
  67. * @param host server name
  68. * @param p port number
  69. */
  70. public Viewer(String host, int p) {
  71. server = host;
  72. port = p;
  73. }
  74. /**
  75. * Returns the server name.
  76. */
  77. public String getServer() { return server; }
  78. /**
  79. * Returns the port number.
  80. */
  81. public int getPort() { return port; }
  82. /**
  83. * Invokes main() in the class specified by <code>classname</code>.
  84. *
  85. * @param classname executed class
  86. * @param args the arguments passed to <code>main()</code>.
  87. */
  88. public void run(String classname, String[] args)
  89. throws Throwable
  90. {
  91. Class c = loadClass(classname);
  92. try {
  93. c.getDeclaredMethod("main", new Class[] { String[].class })
  94. .invoke(null, new Object[] { args });
  95. }
  96. catch (java.lang.reflect.InvocationTargetException e) {
  97. throw e.getTargetException();
  98. }
  99. }
  100. /**
  101. * Requests the class loader to load a class.
  102. */
  103. protected synchronized Class loadClass(String name, boolean resolve)
  104. throws ClassNotFoundException
  105. {
  106. Class c = findLoadedClass(name);
  107. if (c == null)
  108. c = findClass(name);
  109. if (c == null)
  110. throw new ClassNotFoundException(name);
  111. if (resolve)
  112. resolveClass(c);
  113. return c;
  114. }
  115. /**
  116. * Finds the specified class. The implementation in this class
  117. * fetches the class from the http server. If the class is
  118. * either <code>java.*</code>, <code>javax.*</code>, or
  119. * <code>Viewer</code>, then it is loaded by the parent class
  120. * loader.
  121. *
  122. * <p>This method can be overridden by a subclass of
  123. * <code>Viewer</code>.
  124. */
  125. protected Class findClass(String name) throws ClassNotFoundException {
  126. Class c = null;
  127. if (name.startsWith("java.") || name.startsWith("javax.")
  128. || name.equals("javassist.tools.web.Viewer"))
  129. c = findSystemClass(name);
  130. if (c == null)
  131. try {
  132. byte[] b = fetchClass(name);
  133. if (b != null)
  134. c = defineClass(name, b, 0, b.length);
  135. }
  136. catch (Exception e) {
  137. }
  138. return c;
  139. }
  140. /**
  141. * Fetches the class file of the specified class from the http
  142. * server.
  143. */
  144. protected byte[] fetchClass(String classname) throws Exception
  145. {
  146. byte[] b;
  147. URL url = new URL("http", server, port,
  148. "/" + classname.replace('.', '/') + ".class");
  149. URLConnection con = url.openConnection();
  150. con.connect();
  151. int size = con.getContentLength();
  152. InputStream s = con.getInputStream();
  153. if (size <= 0)
  154. b = readStream(s);
  155. else {
  156. b = new byte[size];
  157. int len = 0;
  158. do {
  159. int n = s.read(b, len, size - len);
  160. if (n < 0) {
  161. s.close();
  162. throw new IOException("the stream was closed: "
  163. + classname);
  164. }
  165. len += n;
  166. } while (len < size);
  167. }
  168. s.close();
  169. return b;
  170. }
  171. private byte[] readStream(InputStream fin) throws IOException {
  172. byte[] buf = new byte[4096];
  173. int size = 0;
  174. int len = 0;
  175. do {
  176. size += len;
  177. if (buf.length - size <= 0) {
  178. byte[] newbuf = new byte[buf.length * 2];
  179. System.arraycopy(buf, 0, newbuf, 0, size);
  180. buf = newbuf;
  181. }
  182. len = fin.read(buf, size, buf.length - size);
  183. } while (len >= 0);
  184. byte[] result = new byte[size];
  185. System.arraycopy(buf, 0, result, 0, size);
  186. return result;
  187. }
  188. }