/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Encapsulates RMI-specific information about a remote implementation
* class (a class that implements one or more remote interfaces).
*
* WARNING: The contents of this source file are not part of any
* supported API. Code that depends on them does so at its own risk:
* they are subject to change or removal without notice.
*
* @author Peter Jones
**/
final class RemoteClass {
/** rmic environment for this object */
/** the remote implementation class this object represents */
/** remote interfaces implemented by this class */
/** the remote methods of this class */
private long interfaceHash;
/**
* Creates a RemoteClass instance that represents the RMI-specific
* information about the specified remote implementation class.
*
* If the class is not a valid remote implementation class or if
* some other error occurs, the return value will be null, and
* errors will have been reported to the supplied
* BatchEnvironment.
**/
if (remoteClass.init()) {
return remoteClass;
} else {
return null;
}
}
/**
* Creates a RemoteClass instance for the specified class. The
* resulting object is not yet initialized.
**/
}
/**
* Returns the ClassDoc for this remote implementation class.
**/
return implClass;
}
/**
* Returns the remote interfaces implemented by this remote
* implementation class.
*
* A remote interface is an interface that is a subinterface of
* java.rmi.Remote. The remote interfaces of a class are the
* direct superinterfaces of the class and all of its superclasses
* that are remote interfaces.
*
* The order of the array returned is arbitrary, and some elements
* may be superfluous (i.e., superinterfaces of other interfaces
* in the array).
**/
return remoteInterfaces.clone();
}
/**
* Returns an array of RemoteClass.Method objects representing all
* of the remote methods of this remote implementation class (all
* of the member methods of the class's remote interfaces).
*
* The methods in the array are ordered according to a comparison
* of strings consisting of their name followed by their
* descriptor, so each method's index in the array corresponds to
* its "operation number" in the JDK 1.1 version of the JRMP
**/
return remoteMethods.clone();
}
/**
* for this remote implementation class in the JDK 1.1 version of
**/
long interfaceHash() {
return interfaceHash;
}
/**
* Validates this remote implementation class and computes the
* RMI-specific information. Returns true if successful, or false
* if an error occurred.
**/
private boolean init() {
/*
* Verify that it is really a class, not an interface.
*/
if (implClass.isInterface()) {
return false;
}
/*
* Find all of the remote interfaces of our remote
* implementation class-- for each class up the superclass
* chain, add each directly-implemented interface that somehow
* extends Remote to a list.
*/
/*
* Add interface to the list if it extends Remote and
* it is not already there.
*/
{
}
}
}
/*
* Verify that the candidate remote implementation class
* implements at least one remote interface directly.
*/
/*
* This error message is used if the class does
* implement a remote interface through one of its
* superclasses, but not directly.
*/
} else {
/*
* This error message is used if the class does
* not implement a remote interface at all.
*/
}
return false;
}
}
/*
* Convert list of remote interfaces to an array
* (order is not important for this array).
*/
/*
* Collect the methods from all of the remote interfaces into
* a table, which maps from method name-and-descriptor string
* to Method object.
*/
boolean errors = false;
/*
* Continue iterating despite errors in order to
* generate more complete error report.
*/
errors = true;
}
}
if (errors) {
return false;
}
/*
* Sort table of remote methods into an array. The elements
* are sorted in ascending order of the string of the method's
* name and descriptor, so that each elements index is equal
* to its operation number in the JDK 1.1 version of the JRMP
*/
String[] orderedKeys =
remoteMethods[i].operationString();
msg += " throws ";
if (j > 0) {
msg += ", ";
}
}
}
msg += "\n\tname and descriptor = \"" +
msg += "\n\tmethod hash = " +
}
}
/*
* Finally, pre-compute the interface hash to be used by
*/
return true;
}
/**
* Collects and validates all methods from the specified interface
* and all of its superinterfaces as remote methods. Remote
* methods are added to the supplied table. Returns true if
* successful, or false if an error occurred.
**/
{
if (!intf.isInterface()) {
throw new AssertionError(
}
boolean errors = false;
/*
* Search interface's declared methods.
*/
/*
* Verify that each method throws RemoteException (or a
* superclass of RemoteException).
*/
boolean hasRemoteException = false;
hasRemoteException = true;
break;
}
}
/*
* If this method did not throw RemoteException as required,
* generate the error but continue, so that multiple such
* errors can be reported.
*/
if (!hasRemoteException) {
errors = true;
continue nextMethod;
}
/*
* Verify that the implementation of this method throws only
* java.lang.Exception or its subclasses (fix bugid 4092486).
* JRMP does not support remote methods throwing
* java.lang.Throwable or other subclasses.
*/
ex.qualifiedName());
errors = true;
continue nextMethod;
}
}
}
/*
* Create RemoteClass.Method object to represent this method
* found in a remote interface.
*/
/*
* Store remote method's representation in the table of
* remote methods found, keyed by its name and descriptor.
*
* If the table already contains an entry with the same
* method name and descriptor, then we must replace the
* old entry with a Method object that represents a legal
* combination of the old and the new methods;
* specifically, the combined method must have a throws
* clause that contains (only) all of the checked
* exceptions that can be thrown by both the old and the
* new method (see bugid 4070653).
*/
}
}
/*
* Recursively collect methods for all superinterfaces.
*/
errors = true;
}
}
return !errors;
}
/**
* Returns the MethodDoc for the method of this remote
* implementation class that implements the specified remote
* method of a remote interface. Returns null if no matching
* method was found in this remote implementation class.
**/
{
return implMethod;
}
}
return null;
}
/**
* this remote implementation class. This is the 64-bit value
* used to enforce compatibility between a stub class and a
* protocol.
*
* It is calculated using the first 64 bits of an SHA digest. The
* digest is of a stream consisting of the following data:
* (int) stub version number, always 1
* for each remote method, in order of operation number:
* (UTF-8) method name
* (UTF-8) method descriptor
* for each declared exception, in alphabetical name order:
* (UTF-8) name of exception class
* (where "UTF-8" includes a 16-bit length prefix as written by
* java.io.DataOutput.writeUTF).
**/
private long computeInterfaceHash() {
long hash = 0;
try {
// descriptors already use binary names
}
}
// use only the first 64 bits of the digest for the hash
}
} catch (IOException e) {
throw new AssertionError(e);
} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
}
return hash;
}
/**
* Compares ClassDoc instances according to the lexicographic
* order of their binary names.
**/
}
}
/**
* Encapsulates RMI-specific information about a particular remote
* method in the remote implementation class represented by the
* enclosing RemoteClass.
**/
/**
* MethodDoc for this remove method, from one of the remote
* interfaces that this method was found in.
*
* Note that this MethodDoc may be only one of multiple that
* correspond to this remote method object, if multiple of
* this class's remote interfaces contain methods with the
* same name and descriptor. Therefore, this MethodDoc may
* declare more exceptions thrown that this remote method
* does.
**/
/** java.rmi.server.Operation string for this remote method */
/** name and descriptor of this remote method */
/** JRMP "method hash" for this remote method */
private final long methodHash;
/**
* Exceptions declared to be thrown by this remote method.
*
* This list may include superfluous entries, such as
* unchecked exceptions and subclasses of other entries.
**/
/**
* Creates a new Method instance for the specified method.
**/
/*
* Sort exception types to improve consistency with
* previous implementations.
*/
}
/**
* Returns the MethodDoc object corresponding to this method
* of a remote interface.
**/
return methodDoc;
}
/**
* Returns the parameter types declared by this method.
**/
}
return paramTypes;
}
/**
* Returns the exception types declared to be thrown by this
* remote method.
*
* For methods with the same name and descriptor inherited
* from multiple remote interfaces, the array will contain the
* set of exceptions declared in all of the interfaces'
* methods that can be legally thrown by all of them.
**/
return exceptionTypes.clone();
}
/**
* Returns the JRMP "method hash" used to identify this remote
* method in the JDK 1.2 version of the stub protocol.
**/
long methodHash() {
return methodHash;
}
/**
* Returns the string representation of this method
* appropriate for the construction of a
* java.rmi.server.Operation object.
**/
return operationString;
}
/**
* Returns a string consisting of this method's name followed
* by its descriptor.
**/
return nameAndDescriptor;
}
/**
* Returns a new Method object that is a legal combination of
* this Method object and another one.
*
* Doing this requires determining the exceptions declared by
* the combined method, which must be (only) all of the
* exceptions declared in both old Methods that may thrown in
* either of them.
**/
throw new AssertionError(
"attempt to merge method \"" +
}
return merged;
}
/**
* Cloning is supported by returning a shallow copy of this
* object.
**/
try {
} catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
}
/**
* Adds to the supplied list all exceptions in the "froms"
* array that are subclasses of an exception in the "withs"
* array.
**/
{
break;
}
}
}
}
}
/**
* Computes the JRMP "method hash" of this remote method. The
* method hash is a long containing the first 64 bits of the
* SHA digest from the UTF-8 encoded string of the method name
* and descriptor.
**/
private long computeMethodHash() {
long hash = 0;
try {
// use only the first 64 bits of the digest for the hash
}
} catch (IOException e) {
throw new AssertionError(e);
} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
}
return hash;
}
/**
* Computes the string representation of this method
* appropriate for the construction of a
* java.rmi.server.Operation object.
**/
/*
* To be consistent with previous implementations, we use
* the deprecated style of placing the "[]" for the return
* type (if any) after the parameter list.
*/
if (i > 0) {
op += ", ";
}
}
return op;
}
}
}