diff options
Diffstat (limited to 'libjava/gnu/java')
-rw-r--r-- | libjava/gnu/java/rmi/rmic/Compile_gcj.java | 25 | ||||
-rw-r--r-- | libjava/gnu/java/rmi/rmic/Compile_jikes.java | 56 | ||||
-rw-r--r-- | libjava/gnu/java/rmi/rmic/Compile_kjc.java | 56 | ||||
-rw-r--r-- | libjava/gnu/java/rmi/rmic/Compiler.java | 14 | ||||
-rw-r--r-- | libjava/gnu/java/rmi/rmic/CompilerProcess.java | 65 | ||||
-rw-r--r-- | libjava/gnu/java/rmi/rmic/RMIC.java | 139 | ||||
-rw-r--r-- | libjava/gnu/java/rmi/rmic/RMICException.java | 66 |
7 files changed, 361 insertions, 60 deletions
diff --git a/libjava/gnu/java/rmi/rmic/Compile_gcj.java b/libjava/gnu/java/rmi/rmic/Compile_gcj.java index 4a35b85..ff7924e 100644 --- a/libjava/gnu/java/rmi/rmic/Compile_gcj.java +++ b/libjava/gnu/java/rmi/rmic/Compile_gcj.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2001 Free Software Foundation, Inc. + Copyright (c) 2001, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,21 +40,16 @@ package gnu.java.rmi.rmic; /** Subclass of Compiler that can be used to invoke gcj. */ public class Compile_gcj extends CompilerProcess { + private static final String [] COMPILER_ARGS = + { + "gcj", + "-C" + }; + public String[] computeArguments (String filename) { - int len = 3 + (dest == null ? 0 : 2); - String[] result = new String[len]; - int i = 0; - - result[i++] = "gcj"; - result[i++] = "-C"; - if (dest != null) - { - result[i++] = "-d"; - result[i++] = dest; - } - result[i++] = filename; - - return result; + return computeTypicalArguments(COMPILER_ARGS, + getDestination(), + filename); } } diff --git a/libjava/gnu/java/rmi/rmic/Compile_jikes.java b/libjava/gnu/java/rmi/rmic/Compile_jikes.java new file mode 100644 index 0000000..fd5534b --- /dev/null +++ b/libjava/gnu/java/rmi/rmic/Compile_jikes.java @@ -0,0 +1,56 @@ +/*
+ Copyright (c) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the 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, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.rmi.rmic;
+
+/** Subclass of Compiler that can be used to invoke jikes. */
+public class Compile_jikes extends CompilerProcess
+{
+ /** Compiler arguments to invoke jikes */
+ private static final String [] COMPILER_ARGS =
+ {
+ "jikes"
+ };
+
+ /** Compute the command line for the process. */
+ public String[] computeArguments (String filename)
+ {
+ return computeTypicalArguments(COMPILER_ARGS,
+ getDestination(),
+ filename);
+ }
+}
diff --git a/libjava/gnu/java/rmi/rmic/Compile_kjc.java b/libjava/gnu/java/rmi/rmic/Compile_kjc.java new file mode 100644 index 0000000..cbb27bd --- /dev/null +++ b/libjava/gnu/java/rmi/rmic/Compile_kjc.java @@ -0,0 +1,56 @@ +/*
+ Copyright (c) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the 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, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.rmi.rmic;
+
+/** Subclass of Compiler that can be used to invoke kjc. */
+public class Compile_kjc extends CompilerProcess
+{
+ /** Compiler arguments to invoke kjc */
+ private static final String [] COMPILER_ARGS =
+ {
+ "kjc"
+ };
+
+ /** Compute the command line for the process. */
+ public String[] computeArguments (String filename)
+ {
+ return computeTypicalArguments(COMPILER_ARGS,
+ getDestination(),
+ filename);
+ }
+}
diff --git a/libjava/gnu/java/rmi/rmic/Compiler.java b/libjava/gnu/java/rmi/rmic/Compiler.java index d8856d2..9040c6d 100644 --- a/libjava/gnu/java/rmi/rmic/Compiler.java +++ b/libjava/gnu/java/rmi/rmic/Compiler.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2001 Free Software Foundation, Inc. + Copyright (c) 2001, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,10 +37,12 @@ exception statement from your version. */ package gnu.java.rmi.rmic; -/** A Compiler object can be used to compile a .java file into a +/** + * A Compiler object can be used to compile a .java file into a * .class file. This is an abstract class; the * <code>getInstance()</code> method is used to obtain the actual - * compiler object. */ + * compiler object. + */ public abstract class Compiler { // Can't directly instantiate. @@ -68,6 +70,12 @@ public abstract class Compiler return null; } + /** Get the directory where output files will be put. */ + public String getDestination () + { + return dest; + } + /** Set the directory where output files will be put. */ public void setDestination (String dest) { diff --git a/libjava/gnu/java/rmi/rmic/CompilerProcess.java b/libjava/gnu/java/rmi/rmic/CompilerProcess.java index b3db08d..0de36b6 100644 --- a/libjava/gnu/java/rmi/rmic/CompilerProcess.java +++ b/libjava/gnu/java/rmi/rmic/CompilerProcess.java @@ -1,5 +1,5 @@ /* - Copyright (c) 2001 Free Software Foundation, Inc. + Copyright (c) 2001, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,19 +37,71 @@ exception statement from your version. */ package gnu.java.rmi.rmic; -/** Subclass of Compiler that can be subclassed to invoke a process to - * do its work. */ +import java.io.InputStream; + +/** + * Subclass of Compiler that can be subclassed to invoke a process to + * do its work. + */ public abstract class CompilerProcess extends Compiler { /** This is used to compute the command line for the process. */ public abstract String[] computeArguments (String filename); + /** + * This is used to compute the command line for the process. + * Most compilers typically arrange their arguments as in + * <compiler name and arguments> <optional destination> <filename>. + * This method builds an argument array out that. It should be used + * to define computeArguments for those compilers that follow the + * argument convention described above. + */ + public static String[] computeTypicalArguments(String[] compilerArgs, + String destination, String filename) + { + /* length of compiler specific arguments */ + final int len = compilerArgs.length; + + /* length of returned array of arguments */ + final int arglen = len + (destination == null ? 0 : 2) + 1; + + /* Allocate String array for computed arguments. */ + String [] args = new String[arglen]; + + /* Fill in compiler arguments. */ + System.arraycopy(compilerArgs, 0, args, 0, len); + + /* Fill in destination argument if necessary. */ + if (destination != null) + { + args[len] = "-d"; + args[len + 1] = destination; + } + + /* Fill in filename */ + args[arglen - 1] = filename; + + return args; + } + public void compile (String name) throws Exception { String[] args = computeArguments (name); Process p = Runtime.getRuntime ().exec (args); - // FIXME: probably should collect compiler output here and then - // put it into the exception message. + + /* Print compiler output to System.out. */ + InputStream procin = p.getInputStream(); + for (int ch = procin.read(); ch != -1; ch = procin.read()) + System.out.print((char) ch); + + /* Collect compiler error output in a buffer. + * If compilation fails, it will be used for an error message. + */ + StringBuffer stderr = new StringBuffer(); + InputStream procerr = p.getErrorStream(); + for (int ch = procerr.read(); ch != -1; ch = procerr.read()) + stderr.append((char) ch); + int result; while (true) { @@ -65,7 +117,8 @@ public abstract class CompilerProcess extends Compiler if (result != 0) { // FIXME: wrong exception class. - throw new Exception ("compiler exited with status: " + result); + throw new Exception ("compiler exited with status: " + result, + new RMICException(stderr.toString())); } } } diff --git a/libjava/gnu/java/rmi/rmic/RMIC.java b/libjava/gnu/java/rmi/rmic/RMIC.java index ef44732..82bb37e 100644 --- a/libjava/gnu/java/rmi/rmic/RMIC.java +++ b/libjava/gnu/java/rmi/rmic/RMIC.java @@ -1,5 +1,5 @@ /* - Copyright (c) 1996, 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc. + Copyright (c) 1996, 1997, 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -43,10 +43,12 @@ import java.io.PrintWriter; import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.rmi.RemoteException; import java.util.HashSet; import java.util.Iterator; import java.util.Arrays; -import java.lang.Comparable; +import java.util.Set; + import gnu.java.rmi.server.RMIHashes; public class RMIC { @@ -71,7 +73,9 @@ private String fullclassname; private MethodRef[] remotemethods; private String stubname; private String skelname; +private int errorCount = 0; +private Class mRemoteInterface; public RMIC(String[] a) { args = a; } @@ -99,7 +103,7 @@ public boolean run() { if (verbose) { System.out.println("[Processing class " + args[i] + ".class]"); } - processClass(args[i]); + processClass(args[i].replace(File.separatorChar, '.')); } catch (Exception e) { exception = e; @@ -110,27 +114,34 @@ public boolean run() { } private boolean processClass(String classname) throws Exception { + errorCount = 0; analyzeClass(classname); + if(errorCount > 0) { + System.exit(1); + } generateStub(); if (need11Stubs) { generateSkel(); } if (compile) { - compile(stubname + ".java"); + compile(stubname.replace('.', File.separatorChar) + ".java"); if (need11Stubs) { - compile(skelname + ".java"); + compile(skelname.replace('.', File.separatorChar) + ".java"); } } if (!keep) { - (new File(stubname + ".java")).delete(); + (new File(stubname.replace('.', File.separatorChar) + ".java")).delete(); if (need11Stubs) { - (new File(skelname + ".java")).delete(); + (new File(skelname.replace('.', File.separatorChar) + ".java")).delete(); } } return (true); } private void analyzeClass(String cname) throws Exception { + if(verbose){ + System.out.println("[analyze class "+cname+"]"); + } int p = cname.lastIndexOf('.'); if (p != -1) { classname = cname.substring(p+1); @@ -140,27 +151,36 @@ private void analyzeClass(String cname) throws Exception { } fullclassname = cname; + HashSet rmeths = new HashSet(); findClass(); - for (Class cls = clazz; cls != null; cls = cls.getSuperclass()) { - // Keep going down the inheritence tree until we hit the system - if (cls.getName().startsWith("java.")) { - break; - } - - Method[] meths = cls.getDeclaredMethods(); - for (int i = 0; i < meths.length; i++) { - // Only include public methods - int mods = meths[i].getModifiers(); - if (Modifier.isPublic(mods) && !Modifier.isStatic(mods)) { - // Should check exceptions here. - XXX + + // get the remote interface + mRemoteInterface = getRemoteInterface(clazz); + if(mRemoteInterface == null) + return; + if(verbose){ + System.out.println("[implements "+mRemoteInterface.getName()+"]"); + } - // Add this one in. - rmeths.add(meths[i]); + // check if the methods of the remote interface declare RemoteExceptions + Method[] meths = mRemoteInterface.getDeclaredMethods(); + for (int i = 0; i < meths.length; i++) { + Class[] exceptions = meths[i].getExceptionTypes(); + int index = 0; + for(;index < exceptions.length; index++){ + if(exceptions[index].equals(RemoteException.class)){ + break; } } + if (index < exceptions.length) { + rmeths.add(meths[i]); + } else { + logError("Method "+meths[i]+" does not throw a java.rmi.RemoteException"); + } } + // Convert into a MethodRef array and sort them remotemethods = new MethodRef[rmeths.size()]; int c = 0; @@ -175,12 +195,15 @@ public Exception getException() { } private void findClass() throws ClassNotFoundException { - clazz = Class.forName(fullclassname); + clazz = Class.forName(fullclassname, true, ClassLoader.getSystemClassLoader()); } private void generateStub() throws IOException { - stubname = classname + "_Stub"; - ctrl = new TabbedWriter(new FileWriter(stubname + ".java")); + stubname = fullclassname + "_Stub"; + String stubclassname = classname + "_Stub"; + ctrl = new TabbedWriter(new FileWriter((destination == null ? "" : destination + File.separator) + + stubname.replace('.', File.separatorChar) + + ".java")); out = new PrintWriter(ctrl); if (verbose) { @@ -195,20 +218,32 @@ private void generateStub() throws IOException { out.println(); } - out.print("public final class " + stubname); + out.print("public final class " + stubclassname); ctrl.indent(); out.println("extends java.rmi.server.RemoteStub"); // Output interfaces we implement out.print("implements "); - Class[] ifaces = clazz.getInterfaces(); - for (int i = 0; i < ifaces.length; i++) { - out.print(ifaces[i].getName()); - if (i+1 < ifaces.length) { + /* Scan implemented interfaces, and only print remote interfaces. */ + Class[] ifaces = clazz.getInterfaces(); + Set remoteIfaces = new HashSet(); + for (int i = 0; i < ifaces.length; i++) { + Class iface = ifaces[i]; + if (java.rmi.Remote.class.isAssignableFrom(iface)) { + remoteIfaces.add(iface); + } + } + Iterator iter = remoteIfaces.iterator(); + while (iter.hasNext()) { + /* Print remote interface. */ + Class iface = (Class) iter.next(); + out.print(iface.getName()); + + /* Print ", " if more remote interfaces follow. */ + if (iter.hasNext()) { out.print(", "); } } - ctrl.unindent(); out.print("{"); ctrl.indent(); @@ -278,7 +313,7 @@ private void generateStub() throws IOException { for (int i = 0; i < remotemethods.length; i++) { Method m = remotemethods[i].meth; out.print("$method_" + m.getName() + "_" + i + " = "); - out.print(fullclassname + ".class.getMethod(\"" + m.getName() + "\""); + out.print(mRemoteInterface.getName() + ".class.getMethod(\"" + m.getName() + "\""); out.print(", new java.lang.Class[] {"); // Output signature Class[] sig = m.getParameterTypes(); @@ -311,7 +346,7 @@ private void generateStub() throws IOException { // Constructors if (need11Stubs) { - out.print("public " + stubname + "() {"); + out.print("public " + stubclassname + "() {"); ctrl.indent(); out.print("super();"); ctrl.unindent(); @@ -319,7 +354,7 @@ private void generateStub() throws IOException { } if (need12Stubs) { - out.print("public " + stubname + "(java.rmi.server.RemoteRef ref) {"); + out.print("public " + stubclassname + "(java.rmi.server.RemoteRef ref) {"); ctrl.indent(); out.print("super(ref);"); ctrl.unindent(); @@ -600,8 +635,11 @@ private void generateStub() throws IOException { } private void generateSkel() throws IOException { - skelname = classname + "_Skel"; - ctrl = new TabbedWriter(new FileWriter(skelname + ".java")); + skelname = fullclassname + "_Skel"; + String skelclassname = classname + "_Skel"; + ctrl = new TabbedWriter(new FileWriter((destination == null ? "" : destination + File.separator) + + skelname.replace('.', File.separatorChar) + + ".java")); out = new PrintWriter(ctrl); if (verbose) { @@ -616,7 +654,7 @@ private void generateSkel() throws IOException { out.println(); } - out.print("public final class " + skelname); + out.print("public final class " + skelclassname); ctrl.indent(); // Output interfaces we implement @@ -961,6 +999,35 @@ private void parseOptions() { } } +/** + * Looks for the java.rmi.Remote interface that that is implemented by theClazz. + * @param theClazz the class to look in + * @return the Remote interface of theClazz or null if theClazz does not implement a Remote interface + */ +private Class getRemoteInterface(Class theClazz) +{ + Class[] interfaces = theClazz.getInterfaces(); + for (int i = 0; i < interfaces.length; i++) + { + if (java.rmi.Remote.class.isAssignableFrom(interfaces[i])) + { + return interfaces[i]; + } + } + logError("Class "+ theClazz.getName() + + " is not a remote object. It does not implement an interface that is a java.rmi.Remote-interface."); + return null; +} + +/** + * Prints an error to System.err and increases the error count. + * @param theError + */ +private void logError(String theError){ + errorCount++; + System.err.println("error:"+theError); +} + private static void error(String message) { System.err.println("rmic: " + message); System.err.println("Try `rmic --help' for more information."); diff --git a/libjava/gnu/java/rmi/rmic/RMICException.java b/libjava/gnu/java/rmi/rmic/RMICException.java new file mode 100644 index 0000000..c048d9e --- /dev/null +++ b/libjava/gnu/java/rmi/rmic/RMICException.java @@ -0,0 +1,66 @@ +/*
+ Copyright (c) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the 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, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.rmi.rmic;
+
+/**
+ * Thrown by the underlying compiler used by RMIC when it fails to compile a file.
+ *
+ * @author Dalibor Topic <robilad@kaffe.org>
+ */
+
+public class RMICException extends Exception {
+ /**
+ * Create an exception with a message. The cause remains uninitialized.
+ *
+ * @param s the message string
+ * @see #initCause(Throwable)
+ */
+ public RMICException(String message) {
+ super(message);
+ }
+
+ /**
+ * Create an exception with a message and a cause.
+ *
+ * @param s the message string
+ * @param cause the cause of this exception
+ */
+ public RMICException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
|