📄 rmic.java
字号:
/* RMIC.java -- Copyright (c) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.This file is part of GNU Classpath.GNU Classpath is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU Classpath is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Classpath; see the file COPYING. If not, write to theFree Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307 USA. */package gnu.classpath.tools.rmi.rmic;import gnu.java.rmi.server.RMIHashes;import java.io.ByteArrayOutputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.FileWriter;import java.io.IOException;import java.io.ObjectInput;import java.io.ObjectOutput;import java.io.PrintWriter;import java.lang.reflect.Method;import java.net.URL;import java.net.URLClassLoader;import java.rmi.MarshalException;import java.rmi.Remote;import java.rmi.RemoteException;import java.rmi.UnexpectedException;import java.rmi.UnmarshalException;import java.rmi.server.Operation;import java.rmi.server.RemoteCall;import java.rmi.server.RemoteObject;import java.rmi.server.RemoteRef;import java.rmi.server.RemoteStub;import java.rmi.server.Skeleton;import java.rmi.server.SkeletonMismatchException;import java.security.MessageDigest;import java.util.ArrayList;import java.util.Arrays;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Set;import java.util.StringTokenizer;import org.objectweb.asm153.ClassVisitor;import org.objectweb.asm153.ClassWriter;import org.objectweb.asm153.CodeVisitor;import org.objectweb.asm153.Constants;import org.objectweb.asm153.Label;import org.objectweb.asm153.Type;public class RMIC{ private String[] args; private int next; private List errors = new ArrayList(); private boolean keep = false; private boolean need11Stubs = true; private boolean need12Stubs = true; private boolean compile = true; private boolean verbose; private String destination; private String classpath; private ClassLoader loader; private int errorCount = 0; private Class clazz; private String classname; private String classInternalName; private String fullclassname; private MethodRef[] remotemethods; private String stubname; private String skelname; private List mRemoteInterfaces; private static class C implements Constants { } public RMIC(String[] a) { args = a; } public static void main(String[] args) { if (rmic(args)) System.exit(0); else System.exit(1); } /** * @return true if compilation was successful */ public static boolean rmic(String[] args) { RMIC r = new RMIC(args); return r.run(); } /** * @return true if run was successful */ private boolean run() { boolean done = parseOptions(); if (done) return errorCount == 0; if (next >= args.length) { usage(); return false; } for (int i = next; i < args.length; i++) { try { if (verbose) System.out.println("[Processing class " + args[i] + ".class]"); processClass(args[i].replace(File.separatorChar, '.')); } catch (IOException e) { errors.add(e); } catch (RMICException e) { errors.add(e); } } if (errors.size() > 0) { for (Iterator it = errors.iterator(); it.hasNext(); ) { Exception ex = (Exception) it.next(); logError(ex); } } return errorCount == 0; } private void processClass(String cls) throws IOException, RMICException { // reset class specific vars clazz = null; classname = null; classInternalName = null; fullclassname = null; remotemethods = null; stubname = null; skelname = null; mRemoteInterfaces = new ArrayList(); analyzeClass(cls); generateStub(); if (need11Stubs) generateSkel(); } private void analyzeClass(String cname) throws RMICException { if (verbose) System.out.println("[analyze class " + cname + "]"); int p = cname.lastIndexOf('.'); if (p != -1) classname = cname.substring(p + 1); else classname = cname; fullclassname = cname; findClass(); findRemoteMethods(); } /** * @deprecated */ public Exception getException() { return errors.size() == 0 ? null : (Exception) errors.get(0); } private void findClass() throws RMICException { ClassLoader cl = (loader == null ? ClassLoader.getSystemClassLoader() : loader); try { clazz = Class.forName(fullclassname, false, cl); } catch (ClassNotFoundException cnfe) { throw new RMICException ("Class " + fullclassname + " not found in classpath", cnfe); } if (! Remote.class.isAssignableFrom(clazz)) { throw new RMICException ("Class " + clazz.getName() + " does not implement a remote interface."); } } private static Type[] typeArray(Class[] cls) { Type[] t = new Type[cls.length]; for (int i = 0; i < cls.length; i++) { t[i] = Type.getType(cls[i]); } return t; } private static String[] internalNameArray(Type[] t) { String[] s = new String[t.length]; for (int i = 0; i < t.length; i++) { s[i] = t[i].getInternalName(); } return s; } private static String[] internalNameArray(Class[] c) { return internalNameArray(typeArray(c)); } private static final String forName = "class$"; private static Object param(Method m, int argIndex) { List l = new ArrayList(); l.add(m); l.add(new Integer(argIndex)); return l; } private static void generateClassForNamer(ClassVisitor cls) { CodeVisitor cv = cls.visitMethod (C.ACC_PRIVATE + C.ACC_STATIC + C.ACC_SYNTHETIC, forName, Type.getMethodDescriptor (Type.getType(Class.class), new Type[] { Type.getType(String.class) }), null, null); Label start = new Label(); cv.visitLabel(start); cv.visitVarInsn(C.ALOAD, 0); cv.visitMethodInsn (C.INVOKESTATIC, Type.getInternalName(Class.class), "forName", Type.getMethodDescriptor (Type.getType(Class.class), new Type[] { Type.getType(String.class) })); cv.visitInsn(C.ARETURN); Label handler = new Label(); cv.visitLabel(handler); cv.visitVarInsn(C.ASTORE, 1); cv.visitTypeInsn(C.NEW, typeArg(NoClassDefFoundError.class)); cv.visitInsn(C.DUP); cv.visitVarInsn(C.ALOAD, 1); cv.visitMethodInsn (C.INVOKEVIRTUAL, Type.getInternalName(ClassNotFoundException.class), "getMessage", Type.getMethodDescriptor(Type.getType(String.class), new Type[] {})); cv.visitMethodInsn (C.INVOKESPECIAL, Type.getInternalName(NoClassDefFoundError.class), "<init>", Type.getMethodDescriptor (Type.VOID_TYPE, new Type[] { Type.getType(String.class) })); cv.visitInsn(C.ATHROW); cv.visitTryCatchBlock (start, handler, handler, Type.getInternalName(ClassNotFoundException.class)); cv.visitMaxs(-1, -1); } private void generateClassConstant(CodeVisitor cv, Class cls) { if (cls.isPrimitive()) { Class boxCls; if (cls.equals(Boolean.TYPE)) boxCls = Boolean.class; else if (cls.equals(Character.TYPE)) boxCls = Character.class; else if (cls.equals(Byte.TYPE)) boxCls = Byte.class; else if (cls.equals(Short.TYPE)) boxCls = Short.class; else if (cls.equals(Integer.TYPE)) boxCls = Integer.class; else if (cls.equals(Long.TYPE)) boxCls = Long.class; else if (cls.equals(Float.TYPE)) boxCls = Float.class; else if (cls.equals(Double.TYPE)) boxCls = Double.class; else if (cls.equals(Void.TYPE)) boxCls = Void.class; else throw new IllegalArgumentException("unknown primitive type " + cls); cv.visitFieldInsn (C.GETSTATIC, Type.getInternalName(boxCls), "TYPE", Type.getDescriptor(Class.class)); return; } cv.visitLdcInsn(cls.getName()); cv.visitMethodInsn (C.INVOKESTATIC, classInternalName, forName, Type.getMethodDescriptor (Type.getType(Class.class), new Type[] { Type.getType(String.class) })); } private void generateClassArray(CodeVisitor code, Class[] classes) { code.visitLdcInsn(new Integer(classes.length)); code.visitTypeInsn(C.ANEWARRAY, typeArg(Class.class)); for (int i = 0; i < classes.length; i++) { code.visitInsn(C.DUP); code.visitLdcInsn(new Integer(i)); generateClassConstant(code, classes[i]); code.visitInsn(C.AASTORE); } } private void fillOperationArray(CodeVisitor clinit) { // Operations array clinit.visitLdcInsn(new Integer(remotemethods.length)); clinit.visitTypeInsn(C.ANEWARRAY, typeArg(Operation.class)); clinit.visitFieldInsn (C.PUTSTATIC, classInternalName, "operations", Type.getDescriptor(Operation[].class)); for (int i = 0; i < remotemethods.length; i++) { Method m = remotemethods[i].meth; StringBuffer desc = new StringBuffer(); desc.append(getPrettyName(m.getReturnType()) + " "); desc.append(m.getName() + "("); // signature Class[] sig = m.getParameterTypes(); for (int j = 0; j < sig.length; j++) { desc.append(getPrettyName(sig[j])); if (j + 1 < sig.length) desc.append(", "); } // push operations array clinit.visitFieldInsn (C.GETSTATIC, classInternalName, "operations", Type.getDescriptor(Operation[].class)); // push array index clinit.visitLdcInsn(new Integer(i));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -