0001: /*
0002: * @(#)IxcClassLoader.java 1.29 06/10/10
0003: *
0004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
0005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006: *
0007: * This program is free software; you can redistribute it and/or
0008: * modify it under the terms of the GNU General Public License version
0009: * 2 only, as published by the Free Software Foundation.
0010: *
0011: * This program is distributed in the hope that it will be useful, but
0012: * WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * General Public License version 2 for more details (a copy is
0015: * included at /legal/license.txt).
0016: *
0017: * You should have received a copy of the GNU General Public License
0018: * version 2 along with this work; if not, write to the Free Software
0019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020: * 02110-1301 USA
0021: *
0022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023: * Clara, CA 95054 or visit www.sun.com if you need additional
0024: * information or have any questions.
0025: *
0026: */
0027:
0028: package com.sun.xlet.ixc;
0029:
0030: import java.rmi.Remote;
0031: import java.rmi.RemoteException;
0032: import javax.microedition.xlet.XletContext;
0033: import javax.microedition.xlet.ixc.StubException;
0034: import java.net.URL;
0035: import java.lang.reflect.Method;
0036: import java.lang.reflect.Array;
0037: import java.util.Enumeration;
0038: import java.util.Hashtable;
0039: import java.util.HashSet;
0040: import java.util.Iterator;
0041: import java.io.ByteArrayOutputStream;
0042: import java.io.DataOutputStream;
0043: import java.io.IOException;
0044: import java.security.AccessController;
0045: import java.security.PrivilegedAction;
0046:
0047: /**
0048: * Class loader for Xlets. This is needed to automatically generate stub
0049: * classes for IXC.
0050: * <p>
0051: * Suppose, for example, that a user class implemens a remote interface UserIF,
0052: * and that interface contains two methods, void frob(Something), and
0053: * int glorp(float). This classloader will automatically generate
0054: * a remote stub. The stub will be equivalent to the following class:
0055: * <pre>
0056: *
0057: * package com.sun.xlet;
0058: *
0059: * import java.lang.reflect.Method;
0060: *
0061: * public final class StubClass$$42 extends com.sun.xlet.WrappedRemote
0062: * implements UserIF {
0063: *
0064: * private static Method com_sun_xlet_method0;
0065: * private static Method com_sun_xlet_method1;
0066: *
0067: *
0068: * public static void com_sun_xlet_init(Method findMethodMethod)
0069: * throws Exception {
0070: * // findMethodMethod is Utils.findMethod for the ClassLoader
0071: * // where the *target* Remote object lives.
0072: *
0073: * if (com_sun_xlet_method0 != null) {
0074: * return;
0075: * }
0076: * com_sun_xlet_method0 = (Method) findMethodMethod.invoke(null,
0077: * new Object[] { "UserIF", "frob", new Object[] { "Something" }});
0078: * com_sun_xlet_method1 = (Method) findMethodMethod.invoke(null,
0079: * new Object[] { "UserIF", "glorp",
0080: * new Object[] { java.lang.Float.TYPE }});
0081: * }
0082: *
0083: * public static void com_sun_xlet_destroy() {
0084: * com_sun_xlet_method0 = null;
0085: * com_sun_xlet_method1 = null;
0086: * }
0087: *
0088: * public StubClass$$42(Remote target, ImportRegistryImpl registry,
0089: * RegistryKey key) {
0090: * super(target, registry, key);
0091: * }
0092: *
0093: * public void frob(Something arg1) throws org.dvb.ixc.RemoteException {
0094: * com_sun_xlet_execute(com_sun_xlet_method0,
0095: * new Object[] { arg1 });
0096: * }
0097: *
0098: * public int glorp(float arg1) throws org.dvb.ixc.RemoteException {
0099: * Object r = com_sun_xlet_execute(com_sun_xlet_method1,
0100: * new Object[] { new Float(arg1) });
0101: * return ((Integer) r).intValue();
0102: * }
0103: * }
0104: *
0105: * </pre>
0106: * <p>
0107: * @@ Add the synthetic attribute
0108: * @@ Do this with a security manager installed
0109: * @@ Make exception handling consistent with 1.2 behavior. Specifically,
0110: * RemoteExceptions should be cloned and wrapped, RuntimeExceptions
0111: * should be cloned and re-thrown, checked exception that appear in the
0112: * interface method's signature should be cloned and re-thrown (probably
0113: * with our deprecated friend, Thread.stop(Throwable)), and unexpected
0114: * checked exceptions should be cloned and wrapped (there's some exception
0115: * under java.rmi specifically for this).
0116: */
0117:
0118: /*
0119: * This classloader is deligated from an Xlet's class loader and generates
0120: * a stub class to be used for inter-xlet communication
0121: */
0122:
0123: class IxcClassLoader extends ClassLoader {
0124: private static Class theRemoteIF = Remote.class;
0125: private Hashtable generated = new Hashtable(11);
0126: // Key is remote class, value is stub we generate.
0127: private static// for debugging
0128: int nextStubNumber = 1;
0129: // ImportRegistryImpl.copyObject needs to
0130: // deserialize objects in the context of this classloader. To do this,
0131: // it defines a class called com.sun.xlet.DeserializeUtility, with
0132: // a single static method, deserialize(byte[]). The source for this
0133: // class, and a little utility for converting the .class to a
0134: // byte[], can be found in ~/misc/com/sun/xlet.
0135: private Method deserializeMethod = null;
0136: private Method findMethodMethod = null;
0137: private Class utilsClass = null;
0138: private static byte[] utilsClassBody = { // The .class file
0139: (byte) 0xca, (byte) 0xfe, (byte) 0xba, (byte) 0xbe, (byte) 0x00,
0140: (byte) 0x00, (byte) 0x00, (byte) 0x2e, (byte) 0x00,
0141: (byte) 0x3d, (byte) 0x0a, (byte) 0x00, (byte) 0x11,
0142: (byte) 0x00, (byte) 0x1f, (byte) 0x07, (byte) 0x00,
0143: (byte) 0x20, (byte) 0x07, (byte) 0x00, (byte) 0x21,
0144: (byte) 0x0a, (byte) 0x00, (byte) 0x03, (byte) 0x00,
0145: (byte) 0x22, (byte) 0x0a, (byte) 0x00, (byte) 0x02,
0146: (byte) 0x00, (byte) 0x23, (byte) 0x0a, (byte) 0x00,
0147: (byte) 0x02, (byte) 0x00, (byte) 0x24, (byte) 0x07,
0148: (byte) 0x00, (byte) 0x25, (byte) 0x07, (byte) 0x00,
0149: (byte) 0x26, (byte) 0x07, (byte) 0x00, (byte) 0x27,
0150: (byte) 0x0a, (byte) 0x00, (byte) 0x08, (byte) 0x00,
0151: (byte) 0x28, (byte) 0x0a, (byte) 0x00, (byte) 0x08,
0152: (byte) 0x00, (byte) 0x29, (byte) 0x07, (byte) 0x00,
0153: (byte) 0x2a, (byte) 0x07, (byte) 0x00, (byte) 0x2b,
0154: (byte) 0x0a, (byte) 0x00, (byte) 0x0c, (byte) 0x00,
0155: (byte) 0x2c, (byte) 0x0a, (byte) 0x00, (byte) 0x0d,
0156: (byte) 0x00, (byte) 0x2d, (byte) 0x07, (byte) 0x00,
0157: (byte) 0x2e, (byte) 0x07, (byte) 0x00, (byte) 0x2f,
0158: (byte) 0x01, (byte) 0x00, (byte) 0x06, (byte) 0x3c,
0159: (byte) 0x69, (byte) 0x6e, (byte) 0x69, (byte) 0x74,
0160: (byte) 0x3e, (byte) 0x01, (byte) 0x00, (byte) 0x03,
0161: (byte) 0x28, (byte) 0x29, (byte) 0x56, (byte) 0x01,
0162: (byte) 0x00, (byte) 0x04, (byte) 0x43, (byte) 0x6f,
0163: (byte) 0x64, (byte) 0x65, (byte) 0x01, (byte) 0x00,
0164: (byte) 0x0f, (byte) 0x4c, (byte) 0x69, (byte) 0x6e,
0165: (byte) 0x65, (byte) 0x4e, (byte) 0x75, (byte) 0x6d,
0166: (byte) 0x62, (byte) 0x65, (byte) 0x72, (byte) 0x54,
0167: (byte) 0x61, (byte) 0x62, (byte) 0x6c, (byte) 0x65,
0168: (byte) 0x01, (byte) 0x00, (byte) 0x0b, (byte) 0x64,
0169: (byte) 0x65, (byte) 0x73, (byte) 0x65, (byte) 0x72,
0170: (byte) 0x69, (byte) 0x61, (byte) 0x6c, (byte) 0x69,
0171: (byte) 0x7a, (byte) 0x65, (byte) 0x01, (byte) 0x00,
0172: (byte) 0x1a, (byte) 0x28, (byte) 0x5b, (byte) 0x42,
0173: (byte) 0x29, (byte) 0x4c, (byte) 0x6a, (byte) 0x61,
0174: (byte) 0x76, (byte) 0x61, (byte) 0x2f, (byte) 0x69,
0175: (byte) 0x6f, (byte) 0x2f, (byte) 0x53, (byte) 0x65,
0176: (byte) 0x72, (byte) 0x69, (byte) 0x61, (byte) 0x6c,
0177: (byte) 0x69, (byte) 0x7a, (byte) 0x61, (byte) 0x62,
0178: (byte) 0x6c, (byte) 0x65, (byte) 0x3b, (byte) 0x01,
0179: (byte) 0x00, (byte) 0x0a, (byte) 0x45, (byte) 0x78,
0180: (byte) 0x63, (byte) 0x65, (byte) 0x70, (byte) 0x74,
0181: (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x73,
0182: (byte) 0x07, (byte) 0x00, (byte) 0x30, (byte) 0x07,
0183: (byte) 0x00, (byte) 0x31, (byte) 0x01, (byte) 0x00,
0184: (byte) 0x0a, (byte) 0x66, (byte) 0x69, (byte) 0x6e,
0185: (byte) 0x64, (byte) 0x4d, (byte) 0x65, (byte) 0x74,
0186: (byte) 0x68, (byte) 0x6f, (byte) 0x64, (byte) 0x01,
0187: (byte) 0x00, (byte) 0x4b, (byte) 0x28, (byte) 0x4c,
0188: (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61,
0189: (byte) 0x2f, (byte) 0x6c, (byte) 0x61, (byte) 0x6e,
0190: (byte) 0x67, (byte) 0x2f, (byte) 0x53, (byte) 0x74,
0191: (byte) 0x72, (byte) 0x69, (byte) 0x6e, (byte) 0x67,
0192: (byte) 0x3b, (byte) 0x4c, (byte) 0x6a, (byte) 0x61,
0193: (byte) 0x76, (byte) 0x61, (byte) 0x2f, (byte) 0x6c,
0194: (byte) 0x61, (byte) 0x6e, (byte) 0x67, (byte) 0x2f,
0195: (byte) 0x53, (byte) 0x74, (byte) 0x72, (byte) 0x69,
0196: (byte) 0x6e, (byte) 0x67, (byte) 0x3b, (byte) 0x5b,
0197: (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76,
0198: (byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61,
0199: (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x4f,
0200: (byte) 0x62, (byte) 0x6a, (byte) 0x65, (byte) 0x63,
0201: (byte) 0x74, (byte) 0x3b, (byte) 0x29, (byte) 0x4c,
0202: (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61,
0203: (byte) 0x2f, (byte) 0x6c, (byte) 0x61, (byte) 0x6e,
0204: (byte) 0x67, (byte) 0x2f, (byte) 0x4f, (byte) 0x62,
0205: (byte) 0x6a, (byte) 0x65, (byte) 0x63, (byte) 0x74,
0206: (byte) 0x3b, (byte) 0x01, (byte) 0x00, (byte) 0x0a,
0207: (byte) 0x53, (byte) 0x6f, (byte) 0x75, (byte) 0x72,
0208: (byte) 0x63, (byte) 0x65, (byte) 0x46, (byte) 0x69,
0209: (byte) 0x6c, (byte) 0x65, (byte) 0x01, (byte) 0x00,
0210: (byte) 0x0a, (byte) 0x55, (byte) 0x74, (byte) 0x69,
0211: (byte) 0x6c, (byte) 0x73, (byte) 0x2e, (byte) 0x6a,
0212: (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x0c,
0213: (byte) 0x00, (byte) 0x12, (byte) 0x00, (byte) 0x13,
0214: (byte) 0x01, (byte) 0x00, (byte) 0x19, (byte) 0x6a,
0215: (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2f,
0216: (byte) 0x69, (byte) 0x6f, (byte) 0x2f, (byte) 0x4f,
0217: (byte) 0x62, (byte) 0x6a, (byte) 0x65, (byte) 0x63,
0218: (byte) 0x74, (byte) 0x49, (byte) 0x6e, (byte) 0x70,
0219: (byte) 0x75, (byte) 0x74, (byte) 0x53, (byte) 0x74,
0220: (byte) 0x72, (byte) 0x65, (byte) 0x61, (byte) 0x6d,
0221: (byte) 0x01, (byte) 0x00, (byte) 0x1c, (byte) 0x6a,
0222: (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2f,
0223: (byte) 0x69, (byte) 0x6f, (byte) 0x2f, (byte) 0x42,
0224: (byte) 0x79, (byte) 0x74, (byte) 0x65, (byte) 0x41,
0225: (byte) 0x72, (byte) 0x72, (byte) 0x61, (byte) 0x79,
0226: (byte) 0x49, (byte) 0x6e, (byte) 0x70, (byte) 0x75,
0227: (byte) 0x74, (byte) 0x53, (byte) 0x74, (byte) 0x72,
0228: (byte) 0x65, (byte) 0x61, (byte) 0x6d, (byte) 0x0c,
0229: (byte) 0x00, (byte) 0x12, (byte) 0x00, (byte) 0x32,
0230: (byte) 0x0c, (byte) 0x00, (byte) 0x12, (byte) 0x00,
0231: (byte) 0x33, (byte) 0x0c, (byte) 0x00, (byte) 0x34,
0232: (byte) 0x00, (byte) 0x35, (byte) 0x01, (byte) 0x00,
0233: (byte) 0x14, (byte) 0x6a, (byte) 0x61, (byte) 0x76,
0234: (byte) 0x61, (byte) 0x2f, (byte) 0x69, (byte) 0x6f,
0235: (byte) 0x2f, (byte) 0x53, (byte) 0x65, (byte) 0x72,
0236: (byte) 0x69, (byte) 0x61, (byte) 0x6c, (byte) 0x69,
0237: (byte) 0x7a, (byte) 0x61, (byte) 0x62, (byte) 0x6c,
0238: (byte) 0x65, (byte) 0x01, (byte) 0x00, (byte) 0x0f,
0239: (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61,
0240: (byte) 0x2f, (byte) 0x6c, (byte) 0x61, (byte) 0x6e,
0241: (byte) 0x67, (byte) 0x2f, (byte) 0x43, (byte) 0x6c,
0242: (byte) 0x61, (byte) 0x73, (byte) 0x73, (byte) 0x01,
0243: (byte) 0x00, (byte) 0x10, (byte) 0x6a, (byte) 0x61,
0244: (byte) 0x76, (byte) 0x61, (byte) 0x2f, (byte) 0x6c,
0245: (byte) 0x61, (byte) 0x6e, (byte) 0x67, (byte) 0x2f,
0246: (byte) 0x53, (byte) 0x74, (byte) 0x72, (byte) 0x69,
0247: (byte) 0x6e, (byte) 0x67, (byte) 0x0c, (byte) 0x00,
0248: (byte) 0x36, (byte) 0x00, (byte) 0x37, (byte) 0x0c,
0249: (byte) 0x00, (byte) 0x38, (byte) 0x00, (byte) 0x39,
0250: (byte) 0x01, (byte) 0x00, (byte) 0x13, (byte) 0x6a,
0251: (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2f,
0252: (byte) 0x6c, (byte) 0x61, (byte) 0x6e, (byte) 0x67,
0253: (byte) 0x2f, (byte) 0x45, (byte) 0x78, (byte) 0x63,
0254: (byte) 0x65, (byte) 0x70, (byte) 0x74, (byte) 0x69,
0255: (byte) 0x6f, (byte) 0x6e, (byte) 0x01, (byte) 0x00,
0256: (byte) 0x1a, (byte) 0x6a, (byte) 0x61, (byte) 0x76,
0257: (byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61,
0258: (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x52,
0259: (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x69,
0260: (byte) 0x6d, (byte) 0x65, (byte) 0x45, (byte) 0x78,
0261: (byte) 0x63, (byte) 0x65, (byte) 0x70, (byte) 0x74,
0262: (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x0c,
0263: (byte) 0x00, (byte) 0x3a, (byte) 0x00, (byte) 0x3b,
0264: (byte) 0x0c, (byte) 0x00, (byte) 0x12, (byte) 0x00,
0265: (byte) 0x3c, (byte) 0x01, (byte) 0x00, (byte) 0x12,
0266: (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x2f,
0267: (byte) 0x73, (byte) 0x75, (byte) 0x6e, (byte) 0x2f,
0268: (byte) 0x78, (byte) 0x6c, (byte) 0x65, (byte) 0x74,
0269: (byte) 0x2f, (byte) 0x55, (byte) 0x74, (byte) 0x69,
0270: (byte) 0x6c, (byte) 0x73, (byte) 0x01, (byte) 0x00,
0271: (byte) 0x10, (byte) 0x6a, (byte) 0x61, (byte) 0x76,
0272: (byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61,
0273: (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x4f,
0274: (byte) 0x62, (byte) 0x6a, (byte) 0x65, (byte) 0x63,
0275: (byte) 0x74, (byte) 0x01, (byte) 0x00, (byte) 0x13,
0276: (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61,
0277: (byte) 0x2f, (byte) 0x69, (byte) 0x6f, (byte) 0x2f,
0278: (byte) 0x49, (byte) 0x4f, (byte) 0x45, (byte) 0x78,
0279: (byte) 0x63, (byte) 0x65, (byte) 0x70, (byte) 0x74,
0280: (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x01,
0281: (byte) 0x00, (byte) 0x20, (byte) 0x6a, (byte) 0x61,
0282: (byte) 0x76, (byte) 0x61, (byte) 0x2f, (byte) 0x6c,
0283: (byte) 0x61, (byte) 0x6e, (byte) 0x67, (byte) 0x2f,
0284: (byte) 0x43, (byte) 0x6c, (byte) 0x61, (byte) 0x73,
0285: (byte) 0x73, (byte) 0x4e, (byte) 0x6f, (byte) 0x74,
0286: (byte) 0x46, (byte) 0x6f, (byte) 0x75, (byte) 0x6e,
0287: (byte) 0x64, (byte) 0x45, (byte) 0x78, (byte) 0x63,
0288: (byte) 0x65, (byte) 0x70, (byte) 0x74, (byte) 0x69,
0289: (byte) 0x6f, (byte) 0x6e, (byte) 0x01, (byte) 0x00,
0290: (byte) 0x05, (byte) 0x28, (byte) 0x5b, (byte) 0x42,
0291: (byte) 0x29, (byte) 0x56, (byte) 0x01, (byte) 0x00,
0292: (byte) 0x18, (byte) 0x28, (byte) 0x4c, (byte) 0x6a,
0293: (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2f,
0294: (byte) 0x69, (byte) 0x6f, (byte) 0x2f, (byte) 0x49,
0295: (byte) 0x6e, (byte) 0x70, (byte) 0x75, (byte) 0x74,
0296: (byte) 0x53, (byte) 0x74, (byte) 0x72, (byte) 0x65,
0297: (byte) 0x61, (byte) 0x6d, (byte) 0x3b, (byte) 0x29,
0298: (byte) 0x56, (byte) 0x01, (byte) 0x00, (byte) 0x0a,
0299: (byte) 0x72, (byte) 0x65, (byte) 0x61, (byte) 0x64,
0300: (byte) 0x4f, (byte) 0x62, (byte) 0x6a, (byte) 0x65,
0301: (byte) 0x63, (byte) 0x74, (byte) 0x01, (byte) 0x00,
0302: (byte) 0x14, (byte) 0x28, (byte) 0x29, (byte) 0x4c,
0303: (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61,
0304: (byte) 0x2f, (byte) 0x6c, (byte) 0x61, (byte) 0x6e,
0305: (byte) 0x67, (byte) 0x2f, (byte) 0x4f, (byte) 0x62,
0306: (byte) 0x6a, (byte) 0x65, (byte) 0x63, (byte) 0x74,
0307: (byte) 0x3b, (byte) 0x01, (byte) 0x00, (byte) 0x07,
0308: (byte) 0x66, (byte) 0x6f, (byte) 0x72, (byte) 0x4e,
0309: (byte) 0x61, (byte) 0x6d, (byte) 0x65, (byte) 0x01,
0310: (byte) 0x00, (byte) 0x25, (byte) 0x28, (byte) 0x4c,
0311: (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61,
0312: (byte) 0x2f, (byte) 0x6c, (byte) 0x61, (byte) 0x6e,
0313: (byte) 0x67, (byte) 0x2f, (byte) 0x53, (byte) 0x74,
0314: (byte) 0x72, (byte) 0x69, (byte) 0x6e, (byte) 0x67,
0315: (byte) 0x3b, (byte) 0x29, (byte) 0x4c, (byte) 0x6a,
0316: (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2f,
0317: (byte) 0x6c, (byte) 0x61, (byte) 0x6e, (byte) 0x67,
0318: (byte) 0x2f, (byte) 0x43, (byte) 0x6c, (byte) 0x61,
0319: (byte) 0x73, (byte) 0x73, (byte) 0x3b, (byte) 0x01,
0320: (byte) 0x00, (byte) 0x09, (byte) 0x67, (byte) 0x65,
0321: (byte) 0x74, (byte) 0x4d, (byte) 0x65, (byte) 0x74,
0322: (byte) 0x68, (byte) 0x6f, (byte) 0x64, (byte) 0x01,
0323: (byte) 0x00, (byte) 0x40, (byte) 0x28, (byte) 0x4c,
0324: (byte) 0x6a, (byte) 0x61, (byte) 0x76, (byte) 0x61,
0325: (byte) 0x2f, (byte) 0x6c, (byte) 0x61, (byte) 0x6e,
0326: (byte) 0x67, (byte) 0x2f, (byte) 0x53, (byte) 0x74,
0327: (byte) 0x72, (byte) 0x69, (byte) 0x6e, (byte) 0x67,
0328: (byte) 0x3b, (byte) 0x5b, (byte) 0x4c, (byte) 0x6a,
0329: (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2f,
0330: (byte) 0x6c, (byte) 0x61, (byte) 0x6e, (byte) 0x67,
0331: (byte) 0x2f, (byte) 0x43, (byte) 0x6c, (byte) 0x61,
0332: (byte) 0x73, (byte) 0x73, (byte) 0x3b, (byte) 0x29,
0333: (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76,
0334: (byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61,
0335: (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x72,
0336: (byte) 0x65, (byte) 0x66, (byte) 0x6c, (byte) 0x65,
0337: (byte) 0x63, (byte) 0x74, (byte) 0x2f, (byte) 0x4d,
0338: (byte) 0x65, (byte) 0x74, (byte) 0x68, (byte) 0x6f,
0339: (byte) 0x64, (byte) 0x3b, (byte) 0x01, (byte) 0x00,
0340: (byte) 0x08, (byte) 0x74, (byte) 0x6f, (byte) 0x53,
0341: (byte) 0x74, (byte) 0x72, (byte) 0x69, (byte) 0x6e,
0342: (byte) 0x67, (byte) 0x01, (byte) 0x00, (byte) 0x14,
0343: (byte) 0x28, (byte) 0x29, (byte) 0x4c, (byte) 0x6a,
0344: (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2f,
0345: (byte) 0x6c, (byte) 0x61, (byte) 0x6e, (byte) 0x67,
0346: (byte) 0x2f, (byte) 0x53, (byte) 0x74, (byte) 0x72,
0347: (byte) 0x69, (byte) 0x6e, (byte) 0x67, (byte) 0x3b,
0348: (byte) 0x01, (byte) 0x00, (byte) 0x15, (byte) 0x28,
0349: (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76,
0350: (byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61,
0351: (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x53,
0352: (byte) 0x74, (byte) 0x72, (byte) 0x69, (byte) 0x6e,
0353: (byte) 0x67, (byte) 0x3b, (byte) 0x29, (byte) 0x56,
0354: (byte) 0x00, (byte) 0x21, (byte) 0x00, (byte) 0x10,
0355: (byte) 0x00, (byte) 0x11, (byte) 0x00, (byte) 0x00,
0356: (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03,
0357: (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x12,
0358: (byte) 0x00, (byte) 0x13, (byte) 0x00, (byte) 0x01,
0359: (byte) 0x00, (byte) 0x14, (byte) 0x00, (byte) 0x00,
0360: (byte) 0x00, (byte) 0x1d, (byte) 0x00, (byte) 0x01,
0361: (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00,
0362: (byte) 0x00, (byte) 0x05, (byte) 0x2a, (byte) 0xb7,
0363: (byte) 0x00, (byte) 0x01, (byte) 0xb1, (byte) 0x00,
0364: (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00,
0365: (byte) 0x15, (byte) 0x00, (byte) 0x00, (byte) 0x00,
0366: (byte) 0x06, (byte) 0x00, (byte) 0x01, (byte) 0x00,
0367: (byte) 0x00, (byte) 0x00, (byte) 0x08, (byte) 0x00,
0368: (byte) 0x09, (byte) 0x00, (byte) 0x16, (byte) 0x00,
0369: (byte) 0x17, (byte) 0x00, (byte) 0x02, (byte) 0x00,
0370: (byte) 0x14, (byte) 0x00, (byte) 0x00, (byte) 0x00,
0371: (byte) 0x34, (byte) 0x00, (byte) 0x05, (byte) 0x00,
0372: (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00,
0373: (byte) 0x18, (byte) 0xbb, (byte) 0x00, (byte) 0x02,
0374: (byte) 0x59, (byte) 0xbb, (byte) 0x00, (byte) 0x03,
0375: (byte) 0x59, (byte) 0x2a, (byte) 0xb7, (byte) 0x00,
0376: (byte) 0x04, (byte) 0xb7, (byte) 0x00, (byte) 0x05,
0377: (byte) 0x4c, (byte) 0x2b, (byte) 0xb6, (byte) 0x00,
0378: (byte) 0x06, (byte) 0xc0, (byte) 0x00, (byte) 0x07,
0379: (byte) 0xb0, (byte) 0x00, (byte) 0x00, (byte) 0x00,
0380: (byte) 0x01, (byte) 0x00, (byte) 0x15, (byte) 0x00,
0381: (byte) 0x00, (byte) 0x00, (byte) 0x0a, (byte) 0x00,
0382: (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00,
0383: (byte) 0x0b, (byte) 0x00, (byte) 0x10, (byte) 0x00,
0384: (byte) 0x0d, (byte) 0x00, (byte) 0x18, (byte) 0x00,
0385: (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x00,
0386: (byte) 0x02, (byte) 0x00, (byte) 0x19, (byte) 0x00,
0387: (byte) 0x1a, (byte) 0x00, (byte) 0x09, (byte) 0x00,
0388: (byte) 0x1b, (byte) 0x00, (byte) 0x1c, (byte) 0x00,
0389: (byte) 0x01, (byte) 0x00, (byte) 0x14, (byte) 0x00,
0390: (byte) 0x00, (byte) 0x00, (byte) 0x93, (byte) 0x00,
0391: (byte) 0x04, (byte) 0x00, (byte) 0x05, (byte) 0x00,
0392: (byte) 0x00, (byte) 0x00, (byte) 0x53, (byte) 0x2c,
0393: (byte) 0xbe, (byte) 0xbd, (byte) 0x00, (byte) 0x08,
0394: (byte) 0x4e, (byte) 0x03, (byte) 0x36, (byte) 0x04,
0395: (byte) 0x15, (byte) 0x04, (byte) 0x2c, (byte) 0xbe,
0396: (byte) 0xa2, (byte) 0x00, (byte) 0x2f, (byte) 0x2c,
0397: (byte) 0x15, (byte) 0x04, (byte) 0x32, (byte) 0xc1,
0398: (byte) 0x00, (byte) 0x08, (byte) 0x99, (byte) 0x00,
0399: (byte) 0x11, (byte) 0x2d, (byte) 0x15, (byte) 0x04,
0400: (byte) 0x2c, (byte) 0x15, (byte) 0x04, (byte) 0x32,
0401: (byte) 0xc0, (byte) 0x00, (byte) 0x08, (byte) 0x53,
0402: (byte) 0xa7, (byte) 0x00, (byte) 0x11, (byte) 0x2d,
0403: (byte) 0x15, (byte) 0x04, (byte) 0x2c, (byte) 0x15,
0404: (byte) 0x04, (byte) 0x32, (byte) 0xc0, (byte) 0x00,
0405: (byte) 0x09, (byte) 0xb8, (byte) 0x00, (byte) 0x0a,
0406: (byte) 0x53, (byte) 0x84, (byte) 0x04, (byte) 0x01,
0407: (byte) 0xa7, (byte) 0xff, (byte) 0xd0, (byte) 0x2a,
0408: (byte) 0xb8, (byte) 0x00, (byte) 0x0a, (byte) 0x2b,
0409: (byte) 0x2d, (byte) 0xb6, (byte) 0x00, (byte) 0x0b,
0410: (byte) 0xb0, (byte) 0x4e, (byte) 0xbb, (byte) 0x00,
0411: (byte) 0x0d, (byte) 0x59, (byte) 0x2d, (byte) 0xb6,
0412: (byte) 0x00, (byte) 0x0e, (byte) 0xb7, (byte) 0x00,
0413: (byte) 0x0f, (byte) 0xbf, (byte) 0x00, (byte) 0x01,
0414: (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x45,
0415: (byte) 0x00, (byte) 0x46, (byte) 0x00, (byte) 0x0c,
0416: (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x15,
0417: (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x26,
0418: (byte) 0x00, (byte) 0x09, (byte) 0x00, (byte) 0x00,
0419: (byte) 0x00, (byte) 0x13, (byte) 0x00, (byte) 0x06,
0420: (byte) 0x00, (byte) 0x14, (byte) 0x00, (byte) 0x10,
0421: (byte) 0x00, (byte) 0x15, (byte) 0x00, (byte) 0x1a,
0422: (byte) 0x00, (byte) 0x16, (byte) 0x00, (byte) 0x28,
0423: (byte) 0x00, (byte) 0x18, (byte) 0x00, (byte) 0x36,
0424: (byte) 0x00, (byte) 0x14, (byte) 0x00, (byte) 0x3c,
0425: (byte) 0x00, (byte) 0x1b, (byte) 0x00, (byte) 0x46,
0426: (byte) 0x00, (byte) 0x1c, (byte) 0x00, (byte) 0x47,
0427: (byte) 0x00, (byte) 0x1d, (byte) 0x00, (byte) 0x01,
0428: (byte) 0x00, (byte) 0x1d, (byte) 0x00, (byte) 0x00,
0429: (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x1e };
0430:
0431: IxcClassLoader(ClassLoader l) {
0432: super (l);
0433: }
0434:
0435: private void addMethodsFor(Class clazz, Hashtable methods) {
0436: if (theRemoteIF.isAssignableFrom(clazz)) {
0437: if (clazz.isInterface()) {
0438: Method[] m = clazz.getMethods();
0439: for (int i = 0; i < m.length; i++) {
0440: methods.put(m[i], m[i]);
0441: }
0442: } else {
0443: Class[] ifs = clazz.getInterfaces();
0444: for (int i = 0; i < ifs.length; i++) {
0445: addMethodsFor(ifs[i], methods);
0446: }
0447: Class sup = clazz.getSuperclass();
0448: if (sup != null) {
0449: addMethodsFor(sup, methods);
0450: }
0451: }
0452: }
0453: }
0454:
0455: private Method[] getMethodsFor(Class remote) {
0456: Hashtable methods = new Hashtable(11);
0457: // Set of methods we have to generate. Both key and value are
0458: // (the same instance of) Method. This eliminates duplicates.
0459: addMethodsFor(remote, methods);
0460: Method[] result = new Method[methods.size()];
0461: int i = 0;
0462: for (Enumeration e = methods.elements(); e.hasMoreElements();) {
0463: result[i++] = (Method) e.nextElement();
0464: }
0465: return result;
0466: }
0467:
0468: private void addInterfacesFor(Class clazz, Hashtable interfaces,
0469: boolean addAll) {
0470: // If addAll = true, then add any interface to the list.
0471: // Else add interfaces that extend java.rmi.Remote to the list.
0472:
0473: if (clazz.isInterface()) {
0474: if (addAll) {
0475: interfaces.put(clazz, clazz);
0476: } else {
0477: if (theRemoteIF.isAssignableFrom(clazz)) {
0478: interfaces.put(clazz, clazz);
0479: addAll = true;
0480: }
0481: }
0482: }
0483: Class[] ifs = clazz.getInterfaces();
0484: for (int i = 0; i < ifs.length; i++) {
0485: addInterfacesFor(ifs[i], interfaces, addAll);
0486: }
0487: Class sup = clazz.getSuperclass();
0488: if (sup != null) {
0489: addInterfacesFor(sup, interfaces, addAll);
0490: }
0491: }
0492:
0493: private Class[] getInterfacesFor(Class remote) {
0494: // Returns a set of interfaces we have to add to a ConstantPool.
0495:
0496: Hashtable interfaces = new Hashtable(11);
0497: addInterfacesFor(remote, interfaces, false);
0498: Class[] result = new Class[interfaces.size()];
0499: int i = 0;
0500: for (Enumeration e = interfaces.elements(); e.hasMoreElements();) {
0501: result[i++] = (Class) e.nextElement();
0502: }
0503: return result;
0504: }
0505:
0506: //
0507: // Get the set of remote interfaces that are
0508: // implemented by the class cl. This includes
0509: // remote interfaces implemented by
0510: // the superclasses of cl.
0511: //
0512: private Class[] getRemoteInterfaces(Class cl) {
0513: HashSet interfaces = new HashSet();
0514: getRemoteInterfacesFor(cl, interfaces);
0515: Class[] result = new Class[interfaces.size()];
0516: Iterator it = interfaces.iterator();
0517: for (int i = 0; it.hasNext(); i++) {
0518: result[i] = (Class) it.next();
0519: }
0520: return result;
0521: }
0522:
0523: private void getRemoteInterfacesFor(Class cl, HashSet interfaces) {
0524: while (cl != null) {
0525: Class[] ifs = cl.getInterfaces();
0526: for (int i = 0; i < ifs.length; i++) {
0527: if (theRemoteIF.isAssignableFrom(ifs[i])) {
0528: interfaces.add(ifs[i]);
0529: }
0530: }
0531: cl = cl.getSuperclass();
0532: }
0533: }
0534:
0535: private String nextStubName(String className) {
0536: // We expect to be called with this's lock held
0537:
0538: // fix for 4977190
0539: return new String(className + "_stub" + (nextStubNumber++));
0540: }
0541:
0542: private String descriptorFor(Method m) {
0543: String descriptor = "(";
0544: Class[] params = m.getParameterTypes();
0545: for (int j = 0; j < params.length; j++) {
0546: descriptor += TypeInfo.descriptorFor(params[j]);
0547: }
0548: descriptor += ")";
0549: descriptor += TypeInfo.descriptorFor(m.getReturnType());
0550: return descriptor;
0551: }
0552:
0553: synchronized Class getStubClass(IxcClassLoader target, Class remote)
0554: throws RemoteException {
0555: loadUtilsClass();
0556: Class result = (Class) generated.get(remote);
0557: if (result != null) {
0558: return result;
0559: }
0560: if (!theRemoteIF.isAssignableFrom(remote)) {
0561: throw new StubException(
0562: "Remote class must implement Remote");
0563: }
0564: try {
0565: String stubName = nextStubName(remote.getName());
0566: // fix for 4977190
0567: byte[] classBytes = generateStubClass(stubName.replace('.',
0568: '/'), remote);
0569:
0570: // workaround to invoke defineClass() of a ClassLoader
0571: // that loaded an xlet..
0572:
0573: ClassLoader loader = getParent();
0574: final java.lang.reflect.Method m = ClassLoader.class
0575: .getDeclaredMethod("defineClass", new Class[] {
0576: String.class, classBytes.getClass(),
0577: int.class, int.class });
0578:
0579: AccessController.doPrivileged(new PrivilegedAction() {
0580: public Object run() {
0581: m
0582: .setAccessible(
0583: new java.lang.reflect.AccessibleObject[] { m },
0584: true);
0585: return null;
0586: }
0587: });
0588:
0589: result = (Class) m.invoke(loader, new Object[] { stubName,
0590: classBytes, new Integer(0),
0591: new Integer(classBytes.length) });
0592:
0593: Method initialize = result.getMethod("com_sun_xlet_init",
0594: new Class[] { Method.class });
0595: Method findMethod = target.getFindMethodMethod();
0596: initialize.invoke(null, new Object[] { findMethod });
0597: generated.put(remote, result);
0598: return result;
0599: } catch (StubException r) {
0600: throw r;
0601: } catch (Exception ex) {
0602: throw new StubException("getStub() failed", ex);
0603: } catch (NoClassDefFoundError err) {
0604: throw new StubException(
0605: "Cannot find a class definition for "
0606: + err.getMessage(), err);
0607: }
0608: }
0609:
0610: synchronized void forgetStubsFor(ClassLoader other) {
0611: Class[] keys = new Class[generated.size()];
0612: int i = 0;
0613: for (Enumeration e = generated.keys(); e.hasMoreElements();) {
0614: keys[i++] = (Class) e.nextElement();
0615: }
0616: for (i = 0; i < keys.length; i++) {
0617: Class stub = (Class) generated.get(keys[i]);
0618: // Now, we invoke com_sun_xlet_destroy on the stub. This
0619: // is important, because our stub maintains references to
0620: // methods of the ClassLoader that is being destroyed. If
0621: // we maintained them, that ClassLoader would still be reachable
0622: // through our stub class, so the victim ClassLoader would never
0623: // become collectible.
0624: try {
0625: Method destroy = stub.getMethod("com_sun_xlet_destroy",
0626: new Class[0]);
0627: destroy.invoke(null, new Object[0]);
0628: } catch (Exception ex) {
0629: ex.printStackTrace(); // Should never happen
0630: }
0631: generated.remove(keys[i]);
0632: }
0633: }
0634:
0635: private synchronized byte[] generateStubClass(String stubName,
0636: Class remote) throws IOException, RemoteException {
0637: Method[] methods = getMethodsFor(remote);
0638: // The stub would include methods defined in 'remote interface',
0639: // which is an interface that directly or indirectly extends
0640: // java.rmi.Remote. In other words,
0641: // interface BaseInterface extends java.rmi.Remote
0642: // interface ExtendedInterface extends java.rmi.Remote, Xlet
0643: // class TestXlet implements ExtendedInterface
0644: // then, ExtendedInterface is a 'remote interface' for TestXlet
0645: // and methods declared in BaseInterface, ExtendedInterface
0646: // and Xlet interface are treated as remote methods.
0647: //
0648: Class[] allInterfaces = getInterfacesFor(remote);
0649: Class[] toplevelInterfaces = getRemoteInterfaces(remote);
0650: // time to check if all method declarations are valid..
0651: verifyRemoteMethods(methods);
0652: ConstantPool cp = new ConstantPool();
0653: ByteArrayOutputStream bos = new ByteArrayOutputStream();
0654: DataOutputStream dos = new DataOutputStream(bos);
0655: cp.addString("Code"); // For the code attribute
0656: cp.addString("Exceptions"); // For the exceptoins attribute
0657: String wrappedRemote = "com/sun/xlet/ixc/WrappedRemote";
0658: String constructorDescriptor = "(Ljava/rmi/Remote;Lcom/sun/xlet/ixc/ImportRegistry;Lcom/sun/xlet/ixc/RegistryKey;)V";
0659: String executeDescriptor = "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;";
0660: String invokeDescriptor = "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;";
0661: // Add constant pool entries for names derived from the stuff
0662: // we're implementing.
0663: cp.addClass(wrappedRemote);
0664: cp.addClass(stubName);
0665: cp.addClass("com/sun/xlet/Utils");
0666: cp.addClass("java/lang/Object");
0667: cp.addClass("java/lang/Exception");
0668: cp.addClass("java/lang/reflect/Method");
0669: cp.addClass("java/rmi/RemoteException");
0670: for (int i = 0; i < allInterfaces.length; i++) {
0671: cp.addClass(allInterfaces[i].getName().replace('.', '/'));
0672: }
0673: Hashtable primArgsDone = new Hashtable(11);
0674: Hashtable primRetsDone = new Hashtable(11);
0675: for (int i = 0; i < methods.length; i++) {
0676: cp.addField(stubName, "com_sun_xlet_method" + i,
0677: "Ljava/lang/reflect/Method;"); // For class init method
0678: cp.addStringConstant(methods[i].getName());
0679: cp.addIfMethodReference(methods[i].getDeclaringClass()
0680: .getName().replace('.', '/'), methods[i].getName(),
0681: descriptorFor(methods[i]));
0682: cp.addStringConstant(methods[i].getDeclaringClass()
0683: .getName());
0684: Class rt = methods[i].getReturnType();
0685: if (Void.TYPE.equals(rt)) {
0686: } else if (rt.isPrimitive()) {
0687: TypeInfo info = TypeInfo.get(rt);
0688: String rtNm = info.primitiveWrapper.getName().replace(
0689: '.', '/');
0690: cp.addClass(rtNm);
0691: cp.addMethodReference(rtNm, info.valueMethod, "()"
0692: + info.typeDescriptor);
0693: } else {
0694: cp.addClass(rt.getName().replace('.', '/'));
0695: }
0696: Class[] params = methods[i].getParameterTypes();
0697: for (int j = 0; j < params.length; j++) {
0698: if (params[j].isPrimitive()) {
0699: // Don't need to worry about void here
0700: TypeInfo info = TypeInfo.get(params[j]);
0701: Class p = info.primitiveWrapper;
0702: String nm = p.getName().replace('.', '/');
0703: if (primArgsDone.get(nm) == null) {
0704: primArgsDone.put(nm, nm);
0705: cp.addClass(nm);
0706: // The constructor for the wrapper class:
0707: cp.addMethodReference(nm, "<init>", "("
0708: + TypeInfo.descriptorFor(params[j])
0709: + ")V");
0710: // The TYPE field
0711: cp.addField(nm, "TYPE", "Ljava/lang/Class;");
0712: }
0713: } else {
0714: cp.addStringConstant(params[j].getName());
0715: }
0716: }
0717: //for exceptions
0718: //Class[] exceptions = methods[i].getExceptionTypes();
0719: //for (int j = 0; j < exceptions.length; j++) {
0720: // cp.addClass(exceptions[j].getName().replace('.', '/'));
0721: //}
0722: cp.addClass("java/rmi/RemoteException");
0723: }
0724: cp.addString("com_sun_xlet_init");
0725: cp.addString("(Ljava/lang/reflect/Method;)V");
0726: cp.addString("com_sun_xlet_destroy");
0727: cp.addString("()V");
0728: // Add constructor constants...
0729: cp.addString("<init>");
0730: cp.addMethodReference(wrappedRemote, "<init>",
0731: constructorDescriptor);
0732: cp.addMethodReference(wrappedRemote, "com_sun_xlet_execute",
0733: executeDescriptor);
0734: cp.addMethodReference("java/lang/reflect/Method", "invoke",
0735: invokeDescriptor);
0736: // Now write out the .class!
0737: dos.writeInt(0xcafebabe);
0738: dos.writeShort(0x3a); // Minor version, JDK 1.1.3
0739: dos.writeShort(0x2d); // Major version, JDK 1.1.3
0740: // It's what I observed in 1.1.3, which was handy. Nothing magic
0741: // about 1.1.3.
0742:
0743: cp.write(dos); // Constant pool
0744: dos.writeShort(0x31); // ACC_SUPER | ACC_PUBLIC | ACC_FINAL
0745: // this_class:
0746: dos.writeShort(cp.lookupClass(stubName));
0747: // super_class:
0748: dos.writeShort(cp.lookupClass(wrappedRemote));
0749: // Interfaces:
0750: dos.writeShort(toplevelInterfaces.length);
0751: for (int i = 0; i < toplevelInterfaces.length; i++) {
0752: dos.writeShort(cp.lookupClass(toplevelInterfaces[i]
0753: .getName().replace('.', '/')));
0754: }
0755: // Fields:
0756: dos.writeShort(methods.length);
0757: int methodClassType = cp
0758: .lookupString("Ljava/lang/reflect/Method;");
0759: for (int i = 0; i < methods.length; i++) {
0760: dos.writeShort(0x8 | 0x2); // STATIC, PRIVATE
0761: dos.writeShort(cp.lookupString("com_sun_xlet_method" + i));
0762: dos.writeShort(methodClassType);
0763: dos.writeShort(0); // attributes_count
0764: }
0765: // Methods:
0766: dos.writeShort(methods.length + 3); // First, the constructor:
0767: {
0768: dos.writeShort(0x1); // PUBLIC
0769: dos.writeShort(cp.lookupString("<init>"));
0770: dos.writeShort(cp.lookupString(constructorDescriptor));
0771: dos.writeShort(1); // 1 attribute, the Code attribute
0772: dos.writeShort(cp.lookupString("Code"));
0773: int codeLen = 8;
0774: dos.writeInt(12 + codeLen); // attribute_length
0775: dos.writeShort(10); // max_stack; be conservative
0776: dos.writeShort(10); // max_locals; be conservative
0777: dos.writeInt(codeLen);
0778: // The code:
0779: dos.write(0x2a); // aload_0
0780: dos.write(0x2b); // aload_1
0781: dos.write(0x2c); // aload_2
0782: dos.write(0x2d); // aload_3
0783: dos.write(0xb7); // invokespecial
0784: dos.writeShort(cp.lookupMethod(wrappedRemote, "<init>",
0785: constructorDescriptor));
0786: dos.write(0xb1); // return
0787: // The rest of the code attribute:
0788: dos.writeShort(0); // exception_table_length
0789: dos.writeShort(0); // attribute_count
0790: }
0791: // Next, the com_sun_xlet_init static initialization method:
0792: int invokeMethod = cp.lookupMethod("java/lang/reflect/Method",
0793: "invoke", invokeDescriptor);
0794: {
0795: dos.writeShort(0x1 | 0x8); // PUBLIC | STATIC
0796: dos.writeShort(cp.lookupString("com_sun_xlet_init"));
0797: dos.writeShort(cp
0798: .lookupString("(Ljava/lang/reflect/Method;)V"));
0799: dos.writeShort(2); // 2 attributes, Code and Exceptions
0800: dos.writeShort(cp.lookupString("Code"));
0801: int codeLen = 7;
0802: for (int i = 0; i < methods.length; i++) {
0803: Class[] params = methods[i].getParameterTypes();
0804: codeLen += 25 + (7 * params.length) + 10;
0805: }
0806: codeLen += 1;
0807: dos.writeInt(12 + codeLen); // attribute_length
0808: dos.writeShort(20); // max_stack; be conservative
0809: dos.writeShort(20); // max_locals; be conservative
0810: dos.writeInt(codeLen);
0811: // The code:
0812:
0813: dos.write(0xb2); // getstatic
0814: dos.writeShort(cp.lookupField(stubName,
0815: "com_sun_xlet_method0",
0816: "Ljava/lang/reflect/Method;"));
0817: dos.write(0xc6); // ifnull
0818: dos.writeShort(4);
0819: dos.write(0xb1); // return
0820: for (int i = 0; i < methods.length; i++) {
0821: Method m = methods[i];
0822: Class[] params = m.getParameterTypes();
0823: String from = m.getDeclaringClass().getName();
0824: dos.write(0x2a); // aload_0
0825: dos.write(0x1); // aconst_null
0826: dos.write(0x6); // iconst_3
0827: dos.write(0xbd); // anewarray
0828: dos.writeShort(cp.lookupClass("java/lang/Object"));
0829: dos.write(0x59); // dup
0830: dos.write(0x3); // iconst_0
0831: dos.write(0x13); // ldc_2
0832: dos.writeShort(cp.lookupStringConstant(from));
0833: dos.write(0x53); // aastore
0834: dos.write(0x59); // dup
0835: dos.write(0x4); // iconst_1
0836: dos.write(0x13); // ldc_w
0837: dos.writeShort(cp.lookupStringConstant(m.getName()));
0838: dos.write(0x53); // aastore
0839: dos.write(0x59); // dup
0840: dos.write(0x5); // iconst_2
0841: dos.write(0x10); // bipush
0842: dos.write(params.length);
0843: dos.write(0xbd); // anewarray
0844: dos.writeShort(cp.lookupClass("java/lang/Object"));
0845: for (int j = 0; j < params.length; j++) {
0846: Class p = params[j];
0847: dos.write(0x59); // dup
0848: dos.write(0x10); // bipush
0849: dos.write(j);
0850: if (p.isPrimitive()) {
0851: p = TypeInfo.get(p).primitiveWrapper;
0852: String nm = p.getName().replace('.', '/');
0853: dos.write(0xb2); // getstatic
0854: dos.writeShort(cp.lookupField(nm, "TYPE",
0855: "Ljava/lang/Class;"));
0856: } else {
0857: dos.write(0x13); // ldc_w
0858: dos.writeShort(cp.lookupStringConstant(p
0859: .getName()));
0860: }
0861: dos.write(0x53); // aastore
0862: }
0863: dos.write(0x53); // aastore
0864: dos.write(0xb6); // invokevirtual
0865: dos.writeShort(invokeMethod);
0866: dos.write(0xc0); // checkcast
0867: dos.writeShort(cp
0868: .lookupClass("java/lang/reflect/Method"));
0869: dos.write(0xb3); // putstatic
0870: dos.writeShort(cp.lookupField(stubName,
0871: "com_sun_xlet_method" + i,
0872: "Ljava/lang/reflect/Method;"));
0873: }
0874: dos.write(0xb1); // return
0875: // The rest of the code attribute:
0876: dos.writeShort(0); // exception_table_length
0877: dos.writeShort(0); // attribute_count
0878: // Now the second attribute of the method
0879: dos.writeShort(cp.lookupString("Exceptions"));
0880: dos.writeInt(4);
0881: dos.writeShort(1);
0882: dos.writeShort(cp.lookupClass("java/lang/Exception"));
0883: } // Next, the com_sun_xlet_destroy static method. cf.
0884: // forgetStubsFor(XletClassLoader l).
0885: {
0886: dos.writeShort(0x1 | 0x8); // PUBLIC | STATIC
0887: dos.writeShort(cp.lookupString("com_sun_xlet_destroy"));
0888: dos.writeShort(cp.lookupString("()V"));
0889: dos.writeShort(1); // 1 attribute, Code
0890: dos.writeShort(cp.lookupString("Code"));
0891: int codeLen = (4 * methods.length) + 1;
0892: dos.writeInt(12 + codeLen); // attribute_length
0893: dos.writeShort(5); // max_stack; be conservative
0894: dos.writeShort(5); // max_locals; be conservative
0895: dos.writeInt(codeLen);
0896: // The code:
0897:
0898: for (int i = 0; i < methods.length; i++) {
0899: Method m = methods[i];
0900: dos.write(0x1); // aconst_null
0901: dos.write(0xb3); // putstatic
0902: dos.writeShort(cp.lookupField(stubName,
0903: "com_sun_xlet_method" + i,
0904: "Ljava/lang/reflect/Method;"));
0905: }
0906: dos.write(0xb1); // return
0907: // The rest of the code attribute:
0908: dos.writeShort(0); // exception_table_length
0909: dos.writeShort(0); // attribute_count
0910: }
0911: int executeMethod = cp.lookupMethod(wrappedRemote,
0912: "com_sun_xlet_execute", executeDescriptor);
0913: // Now the stub methods:
0914: for (int i = 0; i < methods.length; i++) {
0915: Method m = methods[i];
0916: Class[] args = m.getParameterTypes();
0917: int maxLocals = 1; // 1 for "this" parameter
0918: for (int j = 0; j < args.length; j++) {
0919: maxLocals += TypeInfo.localSlotsFor(args[j]);
0920: }
0921: int codeLen = 9;
0922: for (int j = 0; j < args.length; j++) {
0923: if (args[j].isPrimitive()) {
0924: codeLen += 9 + 4;
0925: } else {
0926: codeLen += 2 + 4;
0927: }
0928: }
0929: codeLen += 3;
0930: if (Void.TYPE.equals(m.getReturnType())) {
0931: codeLen += 2;
0932: } else if (m.getReturnType().isPrimitive()) {
0933: codeLen += 7;
0934: } else {
0935: codeLen += 4;
0936: }
0937: dos.writeShort(0x1 | 0x10); // PUBLIC | FINAL
0938: dos.writeShort(cp.lookupString(m.getName()));
0939: dos.writeShort(cp.lookupString(descriptorFor(methods[i])));
0940: dos.writeShort(2); // attributes_count
0941: dos.writeShort(cp.lookupString("Code"));
0942: dos.writeInt(12 + codeLen);
0943: dos.writeShort(10); // max_stack; be conservative
0944: dos.writeShort(maxLocals);
0945: dos.writeInt(codeLen);
0946: // Now the code
0947: dos.write(0x2a); // aload_0
0948: dos.write(0xb2); // getstatic
0949: dos.writeShort(cp.lookupField(stubName,
0950: "com_sun_xlet_method" + i,
0951: "Ljava/lang/reflect/Method;"));
0952: dos.write(0x10); // bipush
0953: dos.write(args.length);
0954: dos.write(0xbd); // anewarray java.lang.Object
0955: dos.writeShort(cp.lookupClass("java/lang/Object"));
0956: int slot = 1;
0957: for (int j = 0; j < args.length; j++) {
0958: dos.write(0x59); // dup
0959: dos.write(0x10); // bipush
0960: dos.write(j);
0961: if (args[j].isPrimitive()) {
0962: TypeInfo info = TypeInfo.get(args[j]);
0963: Class p = info.primitiveWrapper;
0964: String pName = p.getName().replace('.', '/');
0965: dos.write(0xbb); // new
0966: dos.writeShort(cp.lookupClass(pName));
0967: dos.write(0x59); // dup
0968: dos.write(info.loadInstruction);
0969: dos.write(slot);
0970: // Invoke constructor of primitive wrapper type:
0971: dos.write(0xb7); // invokespecial
0972: String d = "(" + info.typeDescriptor + ")V";
0973: dos.writeShort(cp.lookupMethod(pName, "<init>", d));
0974: slot += info.localSlots;
0975: } else {
0976: dos.write(0x19);
0977: dos.write(slot);
0978: slot++;
0979: }
0980: dos.write(0x53); // aastore
0981: }
0982: dos.write(0xb6); // invokevirtual
0983: dos.writeShort(executeMethod);
0984: Class ret = m.getReturnType();
0985: if (Void.TYPE.equals(ret)) {
0986: dos.write(0x57); // pop
0987: dos.write(0xb1); // return
0988: } else if (ret.isPrimitive()) {
0989: TypeInfo info = TypeInfo.get(ret);
0990: Class wr = info.primitiveWrapper;
0991: String wrNm = wr.getName().replace('.', '/');
0992: dos.write(0xc0); // checkcast
0993: dos.writeShort(cp.lookupClass(wrNm));
0994: dos.write(0xb6); // invokevirtual
0995: dos.writeShort(cp.lookupMethod(wrNm, info.valueMethod,
0996: "()" + info.typeDescriptor));
0997: dos.write(info.returnInstruction);
0998: } else {
0999: dos.write(0xc0); // checkcast
1000: dos.writeShort(cp.lookupClass(ret.getName().replace(
1001: '.', '/')));
1002: dos.write(0xb0); // areturn
1003: }
1004: // The rest of the code attribute:
1005: dos.writeShort(0); // exception_table_length
1006: dos.writeShort(0); // attribute_count
1007: // Now the second attribute of the method
1008: dos.writeShort(cp.lookupString("Exceptions"));
1009: dos.writeInt(4);
1010: dos.writeShort(1);
1011: dos.writeShort(cp.lookupClass("java/rmi/RemoteException"));
1012: // Class[] exceptions = m.getExceptionTypes();
1013: // number of description (2) + exception index table
1014: //dos.writeInt(2 + exceptions.length*2);
1015: //dos.writeShort(exceptions.length);
1016: // assume RemoteException is already declared in the method
1017: //dos.writeShort(cp.lookupClass("java/rmi/RemoteException"));
1018: //for (int j = 0; j < exceptions.length; j++) {
1019: // dos.writeShort(cp.lookupClass(exceptions[j].getName().replace('.', '/')));
1020: //}
1021: }
1022: // Attributes (of ClassFile):
1023: dos.writeShort(0);
1024: // And we're done!
1025: dos.close();
1026: // debug
1027: //System.out.println("@@ dumping class " + stubName
1028: // + " to .class file for debug");
1029:
1030: /**
1031: ** uncomment this part to dump the stub object in the current dir
1032: ** try {
1033: ** // dumping the stub class to the current dir.
1034: ** dos = new DataOutputStream(new java.io.FileOutputStream(stubName + ".class"));
1035: ** dos.write(bos.toByteArray());
1036: ** dos.close();
1037: ** } catch (Exception e) {
1038: ** // The output is for debugging - if it can't be done,
1039: ** // just notify the user and move on.
1040: ** System.out.println("@@ cannot write " + stubName
1041: ** + " to .class file to this file system: " + e);
1042: ** }
1043: **/
1044: return bos.toByteArray();
1045: }
1046:
1047: private synchronized void loadUtilsClass() throws RemoteException {
1048: if (utilsClass == null) {
1049: try {
1050: // fix for 4977190
1051: utilsClass = defineClass("com.sun.xlet.Utils",
1052: utilsClassBody, 0, utilsClassBody.length);
1053: } catch (Exception ex) {
1054: //throw new RemoteException("Failed to load a util class", ex);
1055: throw new StubException("Failed to load a util class",
1056: ex);
1057: }
1058: }
1059: }
1060:
1061: synchronized Method getDeserializeMethod() throws RemoteException {
1062: if (deserializeMethod == null) {
1063: loadUtilsClass();
1064: try {
1065: Class byteA = (Array.newInstance(Byte.TYPE, 0))
1066: .getClass();
1067: deserializeMethod = utilsClass.getMethod("deserialize",
1068: new Class[] { byteA });
1069: } catch (Exception ex) {
1070: //throw new RemoteException("Can't deserialize", ex);
1071: throw new StubException("Can't deserialize", ex);
1072: }
1073: }
1074: return deserializeMethod;
1075: }
1076:
1077: synchronized Method getFindMethodMethod() throws RemoteException {
1078: if (findMethodMethod == null) {
1079: loadUtilsClass();
1080: try {
1081: Class sc = String.class;
1082: Class oa = (Array.newInstance(Object.class, 0))
1083: .getClass();
1084: findMethodMethod = utilsClass.getMethod("findMethod",
1085: new Class[] { sc, sc, oa });
1086: } catch (Exception ex) {
1087: //throw new RemoteException("Can't find the method", ex);
1088: throw new StubException("Can't find the method", ex);
1089: }
1090: }
1091: return findMethodMethod;
1092: }
1093:
1094: private void verifyRemoteMethods(Method[] methods)
1095: throws RemoteException {
1096: // To check if the methods declared in Remote Interfaces are valid.
1097: // From the PBP spec:
1098: // ---
1099: // Methods declared in a remote interface must be defined as follows:
1100: // 1. Each method must declare java.rmi.RemoteException in its throws
1101: // clause, in addition to any application-specific exceptions.
1102: // 2. A remote object passed by remote reference as an argument or
1103: // return value must be declared as an interface that extends
1104: // java.rmi.Remote , and not as an application class that
1105: // implements this remote interface.
1106: // 3. The type of each method argument must either be a remote
1107: // interface, a class or interface that implements
1108: // java.io.Serializable, or a primitive type.
1109: // 4. Each return value must either be a remote interface, a class or
1110: // interface that implements java.io.Serializable, a primitive type,
1111: // or void.
1112:
1113: boolean doesExceptionThrown;
1114: int count;
1115: String errorMsg = "";
1116: int i = 0;
1117: next: for (; i < methods.length; i++) {
1118: doesExceptionThrown = false;
1119: Class[] exceptions = methods[i].getExceptionTypes();
1120: for (count = 0; count < exceptions.length; count++) {
1121: if (exceptions[count].equals(RemoteException.class)) {
1122: doesExceptionThrown = true;
1123: break;
1124: }
1125: }
1126: if (doesExceptionThrown == false) {
1127: errorMsg += "Method does not declare java.rmi.RemoteException "
1128: + "in it's throws clause : "
1129: + methods[i].toString() + "\n";
1130: continue next;
1131: }
1132: Class[] parameters = methods[i].getParameterTypes();
1133: for (count = 0; count < parameters.length; count++) {
1134: Class param = parameters[count];
1135: if ((param.isPrimitive())
1136: || ((java.io.Serializable.class)
1137: .isAssignableFrom(param))
1138: || (param.isInterface() && theRemoteIF
1139: .isAssignableFrom(param))) {
1140: ;
1141: } else {
1142: errorMsg += "Method parameter type is not primitive, "
1143: + "remote interface, or Serializable : \n"
1144: + methods[i].toString() + "\n";
1145: continue next;
1146: }
1147: }
1148: Class rt = methods[i].getReturnType();
1149: if ((rt.isPrimitive())
1150: || (Void.TYPE.equals(rt))
1151: || ((java.io.Serializable.class)
1152: .isAssignableFrom(rt))
1153: || (rt.isInterface() && theRemoteIF
1154: .isAssignableFrom(rt))) {
1155: ;
1156: } else {
1157: errorMsg += "Method return type is not primitive, "
1158: + "remote interface, Serializable, or void : \n"
1159: + methods[i].toString() + "\n";
1160: }
1161: }
1162: if (!errorMsg.equals("")) {
1163: throw new StubException(errorMsg);
1164: }
1165: }
1166:
1167: private void log(String s) {
1168: System.err.println("IxcClassLoader: " + s);
1169: }
1170: }
|