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.3KB

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