2 Copyright (c) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006
3 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
40 package gnu.java.rmi.rmic;
42 import gnu.java.rmi.server.RMIHashes;
45 import java.io.FileWriter;
46 import java.io.IOException;
47 import java.io.PrintWriter;
48 import java.lang.reflect.Method;
49 import java.net.MalformedURLException;
51 import java.net.URLClassLoader;
52 import java.rmi.Remote;
53 import java.rmi.RemoteException;
54 import java.util.ArrayList;
55 import java.util.Arrays;
56 import java.util.HashSet;
57 import java.util.Iterator;
58 import java.util.List;
60 import java.util.StringTokenizer;
65 private String[] args;
67 private Exception exception;
68 private boolean keep = false;
69 private boolean need11Stubs = true;
70 private boolean need12Stubs = true;
71 private boolean compile = true;
72 private boolean verbose;
73 private String destination;
74 private PrintWriter out;
75 private TabbedWriter ctrl;
77 private String classname;
78 private String fullclassname;
79 private String fullstubname;
80 private String fullskelname;
81 private MethodRef[] remotemethods;
82 private String stubname;
83 private String skelname;
84 private ClassLoader loader;
85 private String classpath;
86 private int errorCount = 0;
87 private List mRemoteInterfaces;
89 public RMIC(String[] a)
94 public static void main(String[] args)
96 RMIC r = new RMIC(args);
99 Exception e = r.getException();
110 if (next >= args.length)
111 error("no class names found");
112 for (int i = next; i < args.length; i++)
117 System.out.println("[Processing class " + args[i] + ".class]");
118 processClass(args[i].replace(File.separatorChar, '.'));
129 private boolean processClass(String cls) throws Exception
131 // reset class specific vars
134 fullclassname = null;
135 remotemethods = null;
140 mRemoteInterfaces = new ArrayList();
153 compile(fullstubname);
155 compile(fullskelname);
159 (new File(fullstubname)).delete();
161 (new File(fullskelname)).delete();
166 private void analyzeClass(String cname) throws Exception
169 System.out.println("[analyze class " + cname + "]");
170 int p = cname.lastIndexOf('.');
172 classname = cname.substring(p + 1);
175 fullclassname = cname;
181 public Exception getException()
186 private void findClass() throws ClassNotFoundException
190 ClassLoader cl = (loader == null
191 ? ClassLoader.getSystemClassLoader()
193 clazz = Class.forName(fullclassname, false, cl);
195 catch (ClassNotFoundException cnfe)
197 System.err.println(fullclassname + " not found in " + classpath);
198 throw new RuntimeException(cnfe);
201 if (! Remote.class.isAssignableFrom(clazz))
203 logError("Class " + clazz.getName() + " is not a remote object. "
204 + "It does not implement an interface that is a "
205 + "java.rmi.Remote-interface.");
206 throw new RuntimeException
207 ("Class " + clazz.getName() + " is not a remote object. "
208 + "It does not implement an interface that is a "
209 + "java.rmi.Remote-interface.");
213 private void generateStub() throws IOException
215 stubname = fullclassname + "_Stub";
216 String stubclassname = classname + "_Stub";
217 fullstubname = (destination == null ? "" : destination + File.separator)
218 + stubname.replace('.', File.separatorChar) + ".java";
219 File file = new File(fullstubname);
220 if (file.getParentFile() != null)
221 file.getParentFile().mkdirs();
223 new TabbedWriter(new FileWriter(file));
224 out = new PrintWriter(ctrl);
227 System.out.println("[Generating class " + stubname + ".java]");
229 out.println("// Stub class generated by rmic - DO NOT EDIT!");
231 if (fullclassname != classname)
234 fullclassname.substring(0, fullclassname.lastIndexOf('.'));
235 out.println("package " + pname + ";");
239 out.print("public final class " + stubclassname);
241 out.println("extends java.rmi.server.RemoteStub");
243 // Output interfaces we implement
244 out.print("implements ");
245 Iterator iter = mRemoteInterfaces.iterator();
246 while (iter.hasNext())
248 /* Print remote interface. */
249 Class iface = (Class) iter.next();
250 out.print(iface.getName());
252 /* Print ", " if more remote interfaces follow. */
263 out.println("private static final long serialVersionUID = 2L;");
267 // InterfaceHash - don't know how to calculate this - XXX
270 out.println("private static final long interfaceHash = "
271 + RMIHashes.getInterfaceHash(clazz) + "L;");
275 out.println("private static boolean useNewInvoke;");
280 out.print("private static final java.rmi.server.Operation[] operations = {");
283 for (int i = 0; i < remotemethods.length; i++)
285 Method m = remotemethods[i].meth;
286 out.print("new java.rmi.server.Operation(\"");
287 out.print(getPrettyName(m.getReturnType()) + " ");
288 out.print(m.getName() + "(");
290 Class[] sig = m.getParameterTypes();
291 for (int j = 0; j < sig.length; j++)
293 out.print(getPrettyName(sig[j]));
294 if (j + 1 < sig.length)
298 if (i + 1 < remotemethods.length)
306 // Set of method references.
309 for (int i = 0; i < remotemethods.length; i++)
311 Method m = remotemethods[i].meth;
312 out.println("private static java.lang.reflect.Method $method_"
313 + m.getName() + "_" + i + ";");
316 // Initialize the methods references.
318 out.print("static {");
326 out.println("java.rmi.server.RemoteRef.class.getMethod(\"invoke\", new java.lang.Class[] { java.rmi.Remote.class, java.lang.reflect.Method.class, java.lang.Object[].class, long.class });");
327 out.println("useNewInvoke = true;");
330 for (int i = 0; i < remotemethods.length; i++)
332 Method m = remotemethods[i].meth;
333 out.print("$method_" + m.getName() + "_" + i + " = ");
334 out.print(m.getDeclaringClass().getName() + ".class.getMethod(\""
335 + m.getName() + "\"");
336 out.print(", new java.lang.Class[] {");
338 Class[] sig = m.getParameterTypes();
339 for (int j = 0; j < sig.length; j++)
341 out.print(getPrettyName(sig[j]) + ".class");
342 if (j + 1 < sig.length)
349 out.print("catch (java.lang.NoSuchMethodException e) {");
352 out.print("useNewInvoke = false;");
354 out.print("throw new java.lang.NoSuchMethodError(\"stub class initialization failed\");");
367 out.print("public " + stubclassname + "() {");
369 out.print("super();");
376 out.print("public " + stubclassname
377 + "(java.rmi.server.RemoteRef ref) {");
379 out.print("super(ref);");
384 // Method implementations
385 for (int i = 0; i < remotemethods.length; i++)
387 Method m = remotemethods[i].meth;
388 Class[] sig = m.getParameterTypes();
389 Class returntype = m.getReturnType();
390 Class[] except = sortExceptions(m.getExceptionTypes());
393 out.print("public " + getPrettyName(returntype) + " " + m.getName()
395 for (int j = 0; j < sig.length; j++)
397 out.print(getPrettyName(sig[j]));
398 out.print(" $param_" + j);
399 if (j + 1 < sig.length)
403 out.print("throws ");
404 for (int j = 0; j < except.length; j++)
406 out.print(getPrettyName(except[j]));
407 if (j + 1 < except.length)
420 out.print("if (useNewInvoke) {");
423 if (returntype != Void.TYPE)
424 out.print("java.lang.Object $result = ");
425 out.print("ref.invoke(this, $method_" + m.getName() + "_" + i
431 out.print("new java.lang.Object[] {");
432 for (int j = 0; j < sig.length; j++)
434 if (sig[j] == Boolean.TYPE)
435 out.print("new java.lang.Boolean($param_" + j + ")");
436 else if (sig[j] == Byte.TYPE)
437 out.print("new java.lang.Byte($param_" + j + ")");
438 else if (sig[j] == Character.TYPE)
439 out.print("new java.lang.Character($param_" + j + ")");
440 else if (sig[j] == Short.TYPE)
441 out.print("new java.lang.Short($param_" + j + ")");
442 else if (sig[j] == Integer.TYPE)
443 out.print("new java.lang.Integer($param_" + j + ")");
444 else if (sig[j] == Long.TYPE)
445 out.print("new java.lang.Long($param_" + j + ")");
446 else if (sig[j] == Float.TYPE)
447 out.print("new java.lang.Float($param_" + j + ")");
448 else if (sig[j] == Double.TYPE)
449 out.print("new java.lang.Double($param_" + j + ")");
451 out.print("$param_" + j);
452 if (j + 1 < sig.length)
457 out.print(Long.toString(remotemethods[i].hash) + "L");
460 if (returntype != Void.TYPE)
463 out.print("return (");
464 if (returntype == Boolean.TYPE)
465 out.print("((java.lang.Boolean)$result).booleanValue()");
466 else if (returntype == Byte.TYPE)
467 out.print("((java.lang.Byte)$result).byteValue()");
468 else if (returntype == Character.TYPE)
469 out.print("((java.lang.Character)$result).charValue()");
470 else if (returntype == Short.TYPE)
471 out.print("((java.lang.Short)$result).shortValue()");
472 else if (returntype == Integer.TYPE)
473 out.print("((java.lang.Integer)$result).intValue()");
474 else if (returntype == Long.TYPE)
475 out.print("((java.lang.Long)$result).longValue()");
476 else if (returntype == Float.TYPE)
477 out.print("((java.lang.Float)$result).floatValue()");
478 else if (returntype == Double.TYPE)
479 out.print("((java.lang.Double)$result).doubleValue()");
481 out.print("(" + getPrettyName(returntype) + ")$result");
496 out.println("java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, "
497 + i + ", interfaceHash);");
500 out.print("java.io.ObjectOutput out = call.getOutputStream();");
501 for (int j = 0; j < sig.length; j++)
504 if (sig[j] == Boolean.TYPE)
505 out.print("out.writeBoolean(");
506 else if (sig[j] == Byte.TYPE)
507 out.print("out.writeByte(");
508 else if (sig[j] == Character.TYPE)
509 out.print("out.writeChar(");
510 else if (sig[j] == Short.TYPE)
511 out.print("out.writeShort(");
512 else if (sig[j] == Integer.TYPE)
513 out.print("out.writeInt(");
514 else if (sig[j] == Long.TYPE)
515 out.print("out.writeLong(");
516 else if (sig[j] == Float.TYPE)
517 out.print("out.writeFloat(");
518 else if (sig[j] == Double.TYPE)
519 out.print("out.writeDouble(");
521 out.print("out.writeObject(");
522 out.print("$param_" + j + ");");
526 out.print("catch (java.io.IOException e) {");
528 out.print("throw new java.rmi.MarshalException(\"error marshalling arguments\", e);");
531 out.println("ref.invoke(call);");
532 if (returntype != Void.TYPE)
533 out.println(getPrettyName(returntype) + " $result;");
536 out.print("java.io.ObjectInput in = call.getInputStream();");
537 boolean needcastcheck = false;
538 if (returntype != Void.TYPE)
541 out.print("$result = ");
542 if (returntype == Boolean.TYPE)
543 out.print("in.readBoolean();");
544 else if (returntype == Byte.TYPE)
545 out.print("in.readByte();");
546 else if (returntype == Character.TYPE)
547 out.print("in.readChar();");
548 else if (returntype == Short.TYPE)
549 out.print("in.readShort();");
550 else if (returntype == Integer.TYPE)
551 out.print("in.readInt();");
552 else if (returntype == Long.TYPE)
553 out.print("in.readLong();");
554 else if (returntype == Float.TYPE)
555 out.print("in.readFloat();");
556 else if (returntype == Double.TYPE)
557 out.print("in.readDouble();");
560 if (returntype != Object.class)
561 out.print("(" + getPrettyName(returntype) + ")");
563 needcastcheck = true;
564 out.print("in.readObject();");
567 out.print("return ($result);");
571 out.print("catch (java.io.IOException e) {");
573 out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling return\", e);");
578 out.print("catch (java.lang.ClassNotFoundException e) {");
580 out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling return\", e);");
584 out.print("finally {");
586 out.print("ref.done(call);");
590 if (need12Stubs && need11Stubs)
600 boolean needgeneral = true;
601 for (int j = 0; j < except.length; j++)
604 out.print("catch (" + getPrettyName(except[j]) + " e) {");
606 out.print("throw e;");
609 if (except[j] == Exception.class)
615 out.print("catch (java.lang.Exception e) {");
617 out.print("throw new java.rmi.UnexpectedException(\"undeclared checked exception\", e);");
633 private void generateSkel() throws IOException
635 skelname = fullclassname + "_Skel";
636 String skelclassname = classname + "_Skel";
637 fullskelname = (destination == null ? "" : destination + File.separator)
638 + skelname.replace('.', File.separatorChar) + ".java";
639 File file = new File(fullskelname);
640 if (file.getParentFile() != null)
641 file.getParentFile().mkdirs();
643 new TabbedWriter(new FileWriter(file));
644 out = new PrintWriter(ctrl);
647 System.out.println("[Generating class " + skelname + ".java]");
649 out.println("// Skel class generated by rmic - DO NOT EDIT!");
651 if (fullclassname != classname)
654 fullclassname.substring(0, fullclassname.lastIndexOf('.'));
655 out.println("package " + pname + ";");
659 out.print("public final class " + skelclassname);
662 // Output interfaces we implement
663 out.print("implements java.rmi.server.Skeleton");
669 // Interface hash - don't know how to calculate this - XXX
670 out.println("private static final long interfaceHash = "
671 + RMIHashes.getInterfaceHash(clazz) + "L;");
675 out.print("private static final java.rmi.server.Operation[] operations = {");
678 for (int i = 0; i < remotemethods.length; i++)
680 Method m = remotemethods[i].meth;
681 out.print("new java.rmi.server.Operation(\"");
682 out.print(getPrettyName(m.getReturnType()) + " ");
683 out.print(m.getName() + "(");
685 Class[] sig = m.getParameterTypes();
686 for (int j = 0; j < sig.length; j++)
688 out.print(getPrettyName(sig[j]));
689 if (j + 1 < sig.length)
693 if (i + 1 < remotemethods.length)
701 // getOperations method
702 out.print("public java.rmi.server.Operation[] getOperations() {");
704 out.print("return ((java.rmi.server.Operation[]) operations.clone());");
711 out.print("public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash) throws java.lang.Exception {");
714 out.print("if (opnum < 0) {");
717 for (int i = 0; i < remotemethods.length; i++)
719 out.print("if (hash == " + Long.toString(remotemethods[i].hash)
722 out.print("opnum = " + i + ";");
729 out.print("throw new java.rmi.server.SkeletonMismatchException(\"interface hash mismatch\");");
735 out.print("else if (hash != interfaceHash) {");
737 out.print("throw new java.rmi.server.SkeletonMismatchException(\"interface hash mismatch\");");
743 out.println(fullclassname + " server = (" + fullclassname + ")obj;");
744 out.println("switch (opnum) {");
747 for (int i = 0; i < remotemethods.length; i++)
749 Method m = remotemethods[i].meth;
750 out.println("case " + i + ":");
754 Class[] sig = m.getParameterTypes();
755 for (int j = 0; j < sig.length; j++)
757 out.print(getPrettyName(sig[j]));
758 out.println(" $param_" + j + ";");
762 boolean needcastcheck = false;
764 out.println("java.io.ObjectInput in = call.getInputStream();");
765 for (int j = 0; j < sig.length; j++)
767 out.print("$param_" + j + " = ");
768 if (sig[j] == Boolean.TYPE)
769 out.print("in.readBoolean();");
770 else if (sig[j] == Byte.TYPE)
771 out.print("in.readByte();");
772 else if (sig[j] == Character.TYPE)
773 out.print("in.readChar();");
774 else if (sig[j] == Short.TYPE)
775 out.print("in.readShort();");
776 else if (sig[j] == Integer.TYPE)
777 out.print("in.readInt();");
778 else if (sig[j] == Long.TYPE)
779 out.print("in.readLong();");
780 else if (sig[j] == Float.TYPE)
781 out.print("in.readFloat();");
782 else if (sig[j] == Double.TYPE)
783 out.print("in.readDouble();");
786 if (sig[j] != Object.class)
788 out.print("(" + getPrettyName(sig[j]) + ")");
789 needcastcheck = true;
791 out.print("in.readObject();");
797 out.print("catch (java.io.IOException e) {");
799 out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling arguments\", e);");
804 out.print("catch (java.lang.ClassCastException e) {");
806 out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling arguments\", e);");
810 out.print("finally {");
812 out.print("call.releaseInputStream();");
816 Class returntype = m.getReturnType();
817 if (returntype != Void.TYPE)
818 out.print(getPrettyName(returntype) + " $result = ");
819 out.print("server." + m.getName() + "(");
820 for (int j = 0; j < sig.length; j++)
822 out.print("$param_" + j);
823 if (j + 1 < sig.length)
830 out.print("java.io.ObjectOutput out = call.getResultStream(true);");
831 if (returntype != Void.TYPE)
834 if (returntype == Boolean.TYPE)
835 out.print("out.writeBoolean($result);");
836 else if (returntype == Byte.TYPE)
837 out.print("out.writeByte($result);");
838 else if (returntype == Character.TYPE)
839 out.print("out.writeChar($result);");
840 else if (returntype == Short.TYPE)
841 out.print("out.writeShort($result);");
842 else if (returntype == Integer.TYPE)
843 out.print("out.writeInt($result);");
844 else if (returntype == Long.TYPE)
845 out.print("out.writeLong($result);");
846 else if (returntype == Float.TYPE)
847 out.print("out.writeFloat($result);");
848 else if (returntype == Double.TYPE)
849 out.print("out.writeDouble($result);");
851 out.print("out.writeObject($result);");
855 out.print("catch (java.io.IOException e) {");
857 out.print("throw new java.rmi.MarshalException(\"error marshalling return\", e);");
867 out.print("default:");
869 out.print("throw new java.rmi.UnmarshalException(\"invalid method number\");");
882 private void compile(String name) throws Exception
884 Compiler comp = Compiler.getInstance();
886 System.out.println("[Compiling class " + name + "]");
887 comp.setDestination(destination);
888 if (classpath != null)
889 comp.setClasspath(classpath);
893 private static String getPrettyName(Class cls)
895 StringBuffer str = new StringBuffer();
896 for (int count = 0;; count++)
900 str.append(cls.getName());
901 for (; count > 0; count--)
903 return (str.toString());
905 cls = cls.getComponentType();
910 * Sort exceptions so the most general go last.
912 private Class[] sortExceptions(Class[] except)
914 for (int i = 0; i < except.length; i++)
916 for (int j = i + 1; j < except.length; j++)
918 if (except[i].isAssignableFrom(except[j]))
920 Class tmp = except[i];
921 except[i] = except[j];
930 * Process the options until we find the first argument.
932 private void parseOptions()
936 if (next >= args.length || args[next].charAt(0) != '-')
938 String arg = args[next];
941 // Accept `--' options if they look long enough.
942 if (arg.length() > 3 && arg.charAt(0) == '-' && arg.charAt(1) == '-')
943 arg = arg.substring(1);
945 if (arg.equals("-keep"))
947 else if (arg.equals("-keepgenerated"))
949 else if (arg.equals("-v1.1"))
954 else if (arg.equals("-vcompat"))
959 else if (arg.equals("-v1.2"))
964 else if (arg.equals("-g"))
967 else if (arg.equals("-depend"))
970 else if (arg.equals("-nowarn"))
973 else if (arg.equals("-verbose"))
975 else if (arg.equals("-nocompile"))
977 else if (arg.equals("-classpath"))
979 classpath = args[next];
982 new StringTokenizer(classpath, File.pathSeparator);
983 URL[] u = new URL[st.countTokens()];
984 for (int i = 0; i < u.length; i++)
986 String path = st.nextToken();
987 File f = new File(path);
992 catch (MalformedURLException mue)
994 error("malformed classpath component " + path);
997 loader = new URLClassLoader(u);
999 else if (arg.equals("-help"))
1001 else if (arg.equals("-version"))
1003 System.out.println("rmic (" + System.getProperty("java.vm.name")
1004 + ") " + System.getProperty("java.vm.version"));
1005 System.out.println();
1006 System.out.println("Copyright 2006 Free Software Foundation, Inc.");
1007 System.out.println("This is free software; see the source for copying conditions. There is NO");
1008 System.out.println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
1011 else if (arg.equals("-d"))
1013 destination = args[next];
1016 else if (arg.charAt(1) == 'J')
1020 error("unrecognized option `" + arg + "'");
1024 private void findRemoteMethods() {
1025 List rmeths = new ArrayList();
1026 for (Class cur = clazz; cur != null; cur = cur.getSuperclass())
1028 Class[] interfaces = cur.getInterfaces();
1029 for (int i = 0; i < interfaces.length; i++)
1031 if (java.rmi.Remote.class.isAssignableFrom(interfaces[i]))
1033 Class remoteInterface = interfaces[i];
1036 ("[implements " + remoteInterface.getName() + "]");
1038 // check if the methods declare RemoteExceptions
1039 Method[] meths = remoteInterface.getMethods();
1040 for (int j = 0; j < meths.length; j++)
1042 Method m = meths[j];
1043 Class[] exs = m.getExceptionTypes();
1045 boolean throwsRemote = false;
1046 for (int k = 0; k < exs.length; k++)
1048 if (exs[k].isAssignableFrom(RemoteException.class))
1049 throwsRemote = true;
1054 logError("Method " + m
1055 + " does not throw a RemoteException");
1062 mRemoteInterfaces.add(remoteInterface);
1067 // intersect exceptions for doubly inherited methods
1068 boolean[] skip = new boolean[rmeths.size()];
1069 for (int i = 0; i < skip.length; i++)
1071 List methrefs = new ArrayList();
1072 for (int i = 0; i < rmeths.size(); i++)
1074 if (skip[i]) continue;
1075 Method current = (Method) rmeths.get(i);
1076 MethodRef ref = new MethodRef(current);
1077 for (int j = i+1; j < rmeths.size(); j++)
1079 Method other = (Method) rmeths.get(j);
1080 if (ref.isMatch(other))
1082 ref.intersectExceptions(other);
1089 // Convert into a MethodRef array and sort them
1090 remotemethods = (MethodRef[])
1091 methrefs.toArray(new MethodRef[methrefs.size()]);
1092 Arrays.sort(remotemethods);
1096 * Prints an error to System.err and increases the error count.
1099 private void logError(String theError)
1102 System.err.println("error:" + theError);
1105 private static void error(String message)
1107 System.err.println("rmic: " + message);
1108 System.err.println("Try `rmic --help' for more information.");
1112 private static void usage()
1114 System.out.println("Usage: rmic [OPTION]... CLASS...\n" + "\n"
1115 + " -keep Don't delete any intermediate files\n"
1116 + " -keepgenerated Same as -keep\n"
1117 + " -v1.1 Java 1.1 style stubs only\n"
1118 + " -vcompat Java 1.1 & Java 1.2 stubs\n"
1119 + " -v1.2 Java 1.2 style stubs only\n"
1120 + " -g * Generated debugging information\n"
1121 + " -depend * Recompile out-of-date files\n"
1122 + " -nowarn * Suppress warning messages\n"
1123 + " -nocompile Don't compile the generated files\n"
1124 + " -verbose Output what's going on\n"
1125 + " -classpath <path> * Use given path as classpath\n"
1126 + " -d <directory> Specify where to place generated classes\n"
1127 + " -J<flag> * Pass flag to Java\n"
1128 + " -help Print this help, then exit\n"
1129 + " -version Print version number, then exit\n" + "\n"
1130 + " * Option currently ignored\n"
1131 + "Long options can be used with `--option' form as well.");
1135 private static class MethodRef
1136 implements Comparable
1146 sig = m.getName(); // XXX should be full signature used to compute hash
1147 hash = RMIHashes.getMethodHash(m);
1148 // add exceptions removing subclasses
1149 exceptions = removeSubclasses(m.getExceptionTypes());
1152 public int compareTo(Object obj)
1154 MethodRef that = (MethodRef) obj;
1155 int name = this.meth.getName().compareTo(that.meth.getName());
1157 return this.sig.compareTo(that.sig);
1162 public boolean isMatch(Method m)
1164 if (!meth.getName().equals(m.getName()))
1167 Class[] params1 = meth.getParameterTypes();
1168 Class[] params2 = m.getParameterTypes();
1169 if (params1.length != params2.length)
1172 for (int i = 0; i < params1.length; i++)
1173 if (!params1[i].equals(params2[i])) return false;
1178 private static List removeSubclasses(Class[] classes)
1180 List list = new ArrayList();
1181 for (int i = 0; i < classes.length; i++)
1183 Class candidate = classes[i];
1185 for (int j = 0; j < classes.length; j++)
1187 if (classes[j].equals(candidate))
1189 else if (classes[j].isAssignableFrom(candidate))
1192 if (add) list.add(candidate);
1198 public void intersectExceptions(Method m)
1200 List incoming = removeSubclasses(m.getExceptionTypes());
1202 List updated = new ArrayList();
1204 for (int i = 0; i < exceptions.size(); i++)
1206 Class outer = (Class) exceptions.get(i);
1207 boolean addOuter = false;
1208 for (int j = 0; j < incoming.size(); j++)
1210 Class inner = (Class) incoming.get(j);
1212 if (inner.equals(outer) || inner.isAssignableFrom(outer))
1214 else if (outer.isAssignableFrom(inner))
1222 exceptions = updated;