History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/rmi/server/MarshalInputStream.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/rmi/server/MarshalInputStream.java+321−0
@@ -0,0 +1,321 @@
1+/*
2+ * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.rmi.server;
27+
28+import java.io.IOException;
29+import java.io.InputStream;
30+import java.io.ObjectInputStream;
31+import java.io.ObjectStreamClass;
32+import java.io.StreamCorruptedException;
33+import java.net.URL;
34+import java.util.*;
35+import java.security.AccessControlException;
36+import java.security.Permission;
37+
38+import java.rmi.server.RMIClassLoader;
39+
40+/**
41+ * MarshalInputStream is an extension of ObjectInputStream. When resolving
42+ * a class, it reads an object from the stream written by a corresponding
43+ * MarshalOutputStream. If the class to be resolved is not available
44+ * locally, from the first class loader on the execution stack, or from the
45+ * context class loader of the current thread, it will attempt to load the
46+ * class from the location annotated by the sending MarshalOutputStream.
47+ * This location object must be a string representing a path of URLs.
48+ *
49+ * A new MarshalInputStream should be created to deserialize remote objects or
50+ * graphs containing remote objects. Objects are created from the stream
51+ * using the ObjectInputStream.readObject method.
52+ *
53+ * @author Peter Jones
54+ */
55+public class MarshalInputStream extends ObjectInputStream {
56+
57+ /**
58+ * value of "java.rmi.server.useCodebaseOnly" property,
59+ * as cached at class initialization time.
60+ */
61+ private static final boolean useCodebaseOnlyProperty =
62+ java.security.AccessController.doPrivileged(
63+ new sun.security.action.GetBooleanAction(
64+ "java.rmi.server.useCodebaseOnly")).booleanValue();
65+
66+ /** table to hold sun classes to which access is explicitly permitted */
67+ protected static Map<String, Class<?>> permittedSunClasses
68+ = new HashMap<String, Class<?>>(3);
69+
70+ /** if true, don't try superclass first in resolveClass() */
71+ private boolean skipDefaultResolveClass = false;
72+
73+ /** callbacks to make when done() called: maps Object to Runnable */
74+ private final Map<Object, Runnable> doneCallbacks
75+ = new HashMap<Object, Runnable>(3);
76+
77+ /**
78+ * if true, load classes (if not available locally) only from the
79+ * URL specified by the "java.rmi.server.codebase" property.
80+ */
81+ private boolean useCodebaseOnly = useCodebaseOnlyProperty;
82+
83+ /*
84+ * Fix for 4179055: The remote object services inside the
85+ * activation daemon use stubs that are in the package
86+ * sun.rmi.server. Classes for these stubs should be loaded from
87+ * the classpath by RMI system code and not by the normal
88+ * unmarshalling process as applications should not need to have
89+ * permission to access the sun implementation classes.
90+ *
91+ * Note: this fix should be redone when API changes may be
92+ * integrated
93+ *
94+ * During parameter unmarshalling RMI needs to explicitly permit
95+ * access to three sun.* stub classes
96+ */
97+ static {
98+ try {
99+ String system =
100+ "sun.rmi.server.Activation$ActivationSystemImpl_Stub";
101+ String registry = "sun.rmi.registry.RegistryImpl_Stub";
102+
103+ permittedSunClasses.put(system, Class.forName(system));
104+ permittedSunClasses.put(registry, Class.forName(registry));
105+
106+ } catch (ClassNotFoundException e) {
107+ throw new NoClassDefFoundError("Missing system class: " +
108+ e.getMessage());
109+ }
110+ }
111+
112+ /**
113+ * Load the "rmi" native library.
114+ */
115+ static {
116+ java.security.AccessController.doPrivileged(
117+ new sun.security.action.LoadLibraryAction("rmi"));
118+ }
119+
120+ /**
121+ * Create a new MarshalInputStream object.
122+ */
123+ public MarshalInputStream(InputStream in)
124+ throws IOException, StreamCorruptedException
125+ {
126+ super(in);
127+ }
128+
129+ /**
130+ * Returns a callback previously registered via the setDoneCallback
131+ * method with given key, or null if no callback has yet been registered
132+ * with that key.
133+ */
134+ public Runnable getDoneCallback(Object key) {
135+ return doneCallbacks.get(key); // not thread-safe
136+ }
137+
138+ /**
139+ * Registers a callback to make when this stream's done() method is
140+ * invoked, along with a key for retrieving the same callback instance
141+ * subsequently from the getDoneCallback method.
142+ */
143+ public void setDoneCallback(Object key, Runnable callback) {
144+ //assert(!doneCallbacks.contains(key));
145+ doneCallbacks.put(key, callback); // not thread-safe
146+ }
147+
148+ /**
149+ * Indicates that the user of this MarshalInputStream is done reading
150+ * objects from it, so all callbacks registered with the setDoneCallback
151+ * method should now be (synchronously) executed. When this method
152+ * returns, there are no more callbacks registered.
153+ *
154+ * This method is implicitly invoked by close() before it delegates to
155+ * the superclass's close method.
156+ */
157+ public void done() {
158+ Iterator<Runnable> iter = doneCallbacks.values().iterator();
159+ while (iter.hasNext()) { // not thread-safe
160+ Runnable callback = iter.next();
161+ callback.run();
162+ }
163+ doneCallbacks.clear();
164+ }
165+
166+ /**
167+ * Closes this stream, implicitly invoking done() first.
168+ */
169+ public void close() throws IOException {
170+ done();
171+ super.close();
172+ }
173+
174+ /**
175+ * resolveClass is extended to acquire (if present) the location
176+ * from which to load the specified class.
177+ * It will find, load, and return the class.
178+ */
179+ protected Class resolveClass(ObjectStreamClass classDesc)
180+ throws IOException, ClassNotFoundException
181+ {
182+ /*
183+ * Always read annotation written by MarshalOutputStream
184+ * describing where to load class from.
185+ */
186+ Object annotation = readLocation();
187+
188+ String className = classDesc.getName();
189+
190+ /*
191+ * Unless we were told to skip this consideration, choose the
192+ * "default loader" to simulate the default ObjectInputStream
193+ * resolveClass mechanism (that is, choose the first non-null
194+ * loader on the execution stack) to maximize the likelihood of
195+ * type compatibility with calling code. (This consideration
196+ * is skipped during server parameter unmarshalling using the 1.2
197+ * stub protocol, because there would never be a non-null class
198+ * loader on the stack in that situation anyway.)
199+ */
200+ ClassLoader defaultLoader =
201+ skipDefaultResolveClass ? null : latestUserDefinedLoader();
202+
203+ /*
204+ * If the "java.rmi.server.useCodebaseOnly" property was true or
205+ * useCodebaseOnly() was called or the annotation is not a String,
206+ * load from the local loader using the "java.rmi.server.codebase"
207+ * URL. Otherwise, load from a loader using the codebase URL in
208+ * the annotation.
209+ */
210+ String codebase = null;
211+ if (!useCodebaseOnly && annotation instanceof String) {
212+ codebase = (String) annotation;
213+ }
214+
215+ try {
216+ return RMIClassLoader.loadClass(codebase, className,
217+ defaultLoader);
218+ } catch (AccessControlException e) {
219+ return checkSunClass(className, e);
220+ } catch (ClassNotFoundException e) {
221+ /*
222+ * Fix for 4442373: delegate to ObjectInputStream.resolveClass()
223+ * to resolve primitive classes.
224+ */
225+ try {
226+ if (Character.isLowerCase(className.charAt(0)) &&
227+ className.indexOf('.') == -1)
228+ {
229+ return super.resolveClass(classDesc);
230+ }
231+ } catch (ClassNotFoundException e2) {
232+ }
233+ throw e;
234+ }
235+ }
236+
237+ /**
238+ * resolveProxyClass is extended to acquire (if present) the location
239+ * to determine the class loader to define the proxy class in.
240+ */
241+ protected Class resolveProxyClass(String[] interfaces)
242+ throws IOException, ClassNotFoundException
243+ {
244+ /*
245+ * Always read annotation written by MarshalOutputStream.
246+ */
247+ Object annotation = readLocation();
248+
249+ ClassLoader defaultLoader =
250+ skipDefaultResolveClass ? null : latestUserDefinedLoader();
251+
252+ String codebase = null;
253+ if (!useCodebaseOnly && annotation instanceof String) {
254+ codebase = (String) annotation;
255+ }
256+
257+ return RMIClassLoader.loadProxyClass(codebase, interfaces,
258+ defaultLoader);
259+ }
260+
261+ /*
262+ * Returns the first non-null class loader up the execution stack, or null
263+ * if only code from the null class loader is on the stack.
264+ */
265+ private static native ClassLoader latestUserDefinedLoader();
266+
267+ /**
268+ * Fix for 4179055: Need to assist resolving sun stubs; resolve
269+ * class locally if it is a "permitted" sun class
270+ */
271+ private Class checkSunClass(String className, AccessControlException e)
272+ throws AccessControlException
273+ {
274+ // ensure that we are giving out a stub for the correct reason
275+ Permission perm = e.getPermission();
276+ String name = null;
277+ if (perm != null) {
278+ name = perm.getName();
279+ }
280+
281+ Class<?> resolvedClass = permittedSunClasses.get(className);
282+
283+ // if class not permitted, throw the SecurityException
284+ if ((name == null) ||
285+ (resolvedClass == null) ||
286+ ((!name.equals("accessClassInPackage.sun.rmi.server")) &&
287+ (!name.equals("accessClassInPackage.sun.rmi.registry"))))
288+ {
289+ throw e;
290+ }
291+
292+ return resolvedClass;
293+ }
294+
295+ /**
296+ * Return the location for the class in the stream. This method can
297+ * be overridden by subclasses that store this annotation somewhere
298+ * else than as the next object in the stream, as is done by this class.
299+ */
300+ protected Object readLocation()
301+ throws IOException, ClassNotFoundException
302+ {
303+ return readObject();
304+ }
305+
306+ /**
307+ * Set a flag to indicate that the superclass's default resolveClass()
308+ * implementation should not be invoked by our resolveClass().
309+ */
310+ void skipDefaultResolveClass() {
311+ skipDefaultResolveClass = true;
312+ }
313+
314+ /**
315+ * Disable code downloading except from the URL specified by the
316+ * "java.rmi.server.codebase" property.
317+ */
318+ void useCodebaseOnly() {
319+ useCodebaseOnly = true;
320+ }
321+}