123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- /*
- * Javassist, a Java-bytecode translator toolkit.
- * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. Alternatively, the contents of this file may be used under
- * the terms of the GNU Lesser General Public License Version 2.1 or later,
- * or the Apache License Version 2.0.
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- */
-
- package javassist.tools.web;
-
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.URL;
- import java.net.URLConnection;
-
- /**
- * A sample applet viewer.
- *
- * <p>This is a sort of applet viewer that can run any program even if
- * the main class is not a subclass of <code>Applet</code>.
- * This viewwer first calls <code>main()</code> in the main class.
- *
- * <p>To run, you should type:
- *
- * <pre>% java javassist.tools.web.Viewer <i>host port</i> Main arg1, ...</pre>
- *
- * <p>This command calls <code>Main.main()</code> with <code>arg1,...</code>
- * All classes including <code>Main</code> are fetched from
- * a server http://<i>host</i>:<i>port</i>.
- * Only the class file for <code>Viewer</code> must exist
- * on a local file system at the client side; even other
- * <code>javassist.*</code> classes are not needed at the client side.
- * <code>Viewer</code> uses only Java core API classes.
- *
- * <p>Note: since a <code>Viewer</code> object is a class loader,
- * a program loaded by this object can call a method in <code>Viewer</code>.
- * For example, you can write something like this:
- *
- * <pre>
- * Viewer v = (Viewer)this.getClass().getClassLoader();
- * String port = v.getPort();
- * </pre>
- *
- */
- public class Viewer extends ClassLoader {
- private String server;
- private int port;
-
- /**
- * Starts a program.
- */
- public static void main(String[] args) throws Throwable {
- if (args.length >= 3) {
- Viewer cl = new Viewer(args[0], Integer.parseInt(args[1]));
- String[] args2 = new String[args.length - 3];
- System.arraycopy(args, 3, args2, 0, args.length - 3);
- cl.run(args[2], args2);
- }
- else
- System.err.println(
- "Usage: java javassist.tools.web.Viewer <host> <port> class [args ...]");
- }
-
- /**
- * Constructs a viewer.
- *
- * @param host server name
- * @param p port number
- */
- public Viewer(String host, int p) {
- server = host;
- port = p;
- }
-
- /**
- * Returns the server name.
- */
- public String getServer() { return server; }
-
- /**
- * Returns the port number.
- */
- public int getPort() { return port; }
-
- /**
- * Invokes main() in the class specified by <code>classname</code>.
- *
- * @param classname executed class
- * @param args the arguments passed to <code>main()</code>.
- */
- public void run(String classname, String[] args)
- throws Throwable
- {
- Class<?> c = loadClass(classname);
- try {
- c.getDeclaredMethod("main", new Class[] { String[].class })
- .invoke(null, new Object[] { args });
- }
- catch (java.lang.reflect.InvocationTargetException e) {
- throw e.getTargetException();
- }
- }
-
- /**
- * Requests the class loader to load a class.
- */
- @Override
- protected synchronized Class<?> loadClass(String name, boolean resolve)
- throws ClassNotFoundException
- {
- Class<?> c = findLoadedClass(name);
- if (c == null)
- c = findClass(name);
-
- if (c == null)
- throw new ClassNotFoundException(name);
-
- if (resolve)
- resolveClass(c);
-
- return c;
- }
-
- /**
- * Finds the specified class. The implementation in this class
- * fetches the class from the http server. If the class is
- * either <code>java.*</code>, <code>javax.*</code>, or
- * <code>Viewer</code>, then it is loaded by the parent class
- * loader.
- *
- * <p>This method can be overridden by a subclass of
- * <code>Viewer</code>.
- */
- @Override
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- Class<?> c = null;
- if (name.startsWith("java.") || name.startsWith("javax.")
- || name.equals("javassist.tools.web.Viewer"))
- c = findSystemClass(name);
-
- if (c == null)
- try {
- byte[] b = fetchClass(name);
- if (b != null)
- c = defineClass(name, b, 0, b.length);
- }
- catch (Exception e) {
- }
-
- return c;
- }
-
- /**
- * Fetches the class file of the specified class from the http
- * server.
- */
- protected byte[] fetchClass(String classname) throws Exception
- {
- byte[] b;
- URL url = new URL("http", server, port,
- "/" + classname.replace('.', '/') + ".class");
- URLConnection con = url.openConnection();
- con.connect();
- int size = con.getContentLength();
- try (InputStream s = con.getInputStream()) {
- if (size <= 0) {
- b = readStream(s);
- } else {
- b = new byte[size];
- int len = 0;
- do {
- int n = s.read(b, len, size - len);
- if (n < 0) {
- throw new IOException("the stream was closed: "
- + classname);
- }
- len += n;
- } while (len < size);
- }
- }
- return b;
- }
-
- private byte[] readStream(InputStream fin) throws IOException {
- byte[] buf = new byte[4096];
- int size = 0;
- int len = 0;
- do {
- size += len;
- if (buf.length - size <= 0) {
- byte[] newbuf = new byte[buf.length * 2];
- System.arraycopy(buf, 0, newbuf, 0, size);
- buf = newbuf;
- }
-
- len = fin.read(buf, size, buf.length - size);
- } while (len >= 0);
-
- byte[] result = new byte[size];
- System.arraycopy(buf, 0, result, 0, size);
- return result;
- }
- }
|