2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 package java.security;
20 import java.nio.ByteBuffer;
21 import java.util.HashMap;
24 * {@code SecureClassLoader} represents a {@code ClassLoader} which associates
25 * the classes it loads with a code source and provide mechanisms to allow the
26 * relevant permissions to be retrieved.
28 public class SecureClassLoader extends ClassLoader {
30 // A cache of ProtectionDomains for a given CodeSource
31 private HashMap<CodeSource, ProtectionDomain> pds = new HashMap<CodeSource, ProtectionDomain>();
34 * Constructs a new instance of {@code SecureClassLoader}. The default
35 * parent {@code ClassLoader} is used.
37 * If a {@code SecurityManager} is installed, code calling this constructor
38 * needs the {@code SecurityPermission} {@code checkCreateClassLoader} to be
39 * granted, otherwise a {@code SecurityException} will be thrown.
41 * @throws SecurityException
42 * if a {@code SecurityManager} is installed and the caller does
43 * not have permission to invoke this constructor.
45 protected SecureClassLoader() {
50 * Constructs a new instance of {@code SecureClassLoader} with the specified
51 * parent {@code ClassLoader}.
53 * If a {@code SecurityManager} is installed, code calling this constructor
54 * needs the {@code SecurityPermission} {@code checkCreateClassLoader} to be
55 * granted, otherwise a {@code SecurityException} will be thrown.
58 * the parent {@code ClassLoader}.
59 * @throws SecurityException
60 * if a {@code SecurityManager} is installed and the caller does
61 * not have permission to invoke this constructor.
63 protected SecureClassLoader(ClassLoader parent) {
68 * Returns the {@code PermissionCollection} for the specified {@code
73 * @return the {@code PermissionCollection} for the specified {@code
76 protected PermissionCollection getPermissions(CodeSource codesource) {
77 // Do nothing by default, ProtectionDomain will take care about
78 // permissions in dynamic
79 return new Permissions();
83 * Constructs a new class from an array of bytes containing a class
84 * definition in class file format with an optional {@code CodeSource}.
87 * the name of the new class.
89 * a memory image of a class file.
91 * the start offset in b of the class data.
93 * the length of the class data.
95 * the {@code CodeSource}, or {@code null}.
96 * @return a new class.
97 * @throws IndexOutOfBoundsException
98 * if {@code off} or {@code len} are not valid in respect to
100 * @throws ClassFormatError
101 * if the specified data is not valid class data.
102 * @throws SecurityException
103 * if the package to which this class is to be added, already
104 * contains classes which were signed by different certificates,
105 * or if the class name begins with "java."
107 protected final Class<?> defineClass(String name, byte[] b, int off, int len,
109 return cs == null ? defineClass(name, b, off, len) : defineClass(name,
110 b, off, len, getPD(cs));
114 * Constructs a new class from an array of bytes containing a class
115 * definition in class file format with an optional {@code CodeSource}.
118 * the name of the new class.
120 * a memory image of a class file.
122 * the {@code CodeSource}, or {@code null}.
123 * @return a new class.
124 * @throws ClassFormatError
125 * if the specified data is not valid class data.
126 * @throws SecurityException
127 * if the package to which this class is to be added, already
128 * contains classes which were signed by different certificates,
129 * or if the class name begins with "java."
131 protected final Class<?> defineClass(String name, ByteBuffer b, CodeSource cs) {
132 //FIXME 1.5 - remove b.array(), call super.defineClass(,ByteBuffer,)
134 byte[] data = b.array();
135 return cs == null ? defineClass(name, data, 0, data.length)
136 : defineClass(name, data, 0, data.length, getPD(cs));
139 // Constructs and caches ProtectionDomain for the given CodeSource
141 // It calls {@link getPermissions()} to get a set of permissions.
143 // @param cs CodeSource object
144 // @return ProtectionDomain for the passed CodeSource object
145 private ProtectionDomain getPD(CodeSource cs) {
149 // need to cache PDs, otherwise every class from a given CodeSource
150 // will have it's own ProtectionDomain, which does not look right.
153 if ((pd = pds.get(cs)) != null) {
156 PermissionCollection perms = getPermissions(cs);
157 pd = new ProtectionDomain(cs, perms, this, null);