1 /*
2 * Copyright (c) 2001, 2013, 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
194
195 return true;
196 }
197
198 /**
199 * Returns {@code true} if memberClass's's module exports memberClass's
200 * package to currentClass's module.
201 */
202 public static boolean verifyModuleAccess(Class<?> currentClass,
203 Class<?> memberClass) {
204 return verifyModuleAccess(currentClass.getModule(), memberClass);
205 }
206
207 public static boolean verifyModuleAccess(Module currentModule, Class<?> memberClass) {
208 Module memberModule = memberClass.getModule();
209
210 // module may be null during startup (initLevel 0)
211 if (currentModule == memberModule)
212 return true; // same module (named or unnamed)
213
214 // memberClass may be primitive or array class
215 Class<?> c = memberClass;
216 while (c.isArray()) {
217 c = c.getComponentType();
218 }
219 if (c.isPrimitive())
220 return true;
221
222 String pkg = c.getPackageName();
223 boolean allowed = memberModule.isExported(pkg, currentModule);
224 if (allowed && memberModule.isNamed() && printStackTraceWhenAccessSucceeds()) {
225 if (!SharedSecrets.getJavaLangReflectModuleAccess()
226 .isStaticallyExported(memberModule, pkg, currentModule)) {
227 String msg = currentModule + " allowed access to member of " + memberClass;
228 new Exception(msg).printStackTrace(System.err);
229 }
230 }
231 return allowed;
232 }
233
234 /**
235 * Returns true if two classes in the same package.
236 */
237 private static boolean isSameClassPackage(Class<?> c1, Class<?> c2) {
238 if (c1.getClassLoader() != c2.getClassLoader())
239 return false;
240 while (c1.isArray())
241 c1 = c1.getComponentType();
242 while (c2.isArray())
243 c2 = c2.getComponentType();
244 return Objects.equals(c1.getPackageName(), c2.getPackageName());
245 }
246
247 static boolean isSubclassOf(Class<?> queryClass,
248 Class<?> ofClass)
249 {
250 while (queryClass != null) {
251 if (queryClass == ofClass) {
252 return true;
253 }
254 queryClass = queryClass.getSuperclass();
255 }
256 return false;
257 }
258
259 // fieldNames must contain only interned Strings
260 public static synchronized void registerFieldsToFilter(Class<?> containingClass,
261 String ... fieldNames) {
262 fieldFilterMap =
263 registerFilter(fieldFilterMap, containingClass, fieldNames);
361 private static volatile boolean printStackWhenAccessFails;
362
363 // true to print a stack trace when access succeeds
364 private static volatile boolean printStackWhenAccessSucceeds;
365
366 // true if printStack* values are initialized
367 private static volatile boolean printStackPropertiesSet;
368
369 private static void ensurePrintStackPropertiesSet() {
370 if (!printStackPropertiesSet && VM.initLevel() >= 1) {
371 String s = GetPropertyAction.privilegedGetProperty(
372 "sun.reflect.debugModuleAccessChecks");
373 if (s != null) {
374 printStackWhenAccessFails = !s.equalsIgnoreCase("false");
375 printStackWhenAccessSucceeds = s.equalsIgnoreCase("access");
376 }
377 printStackPropertiesSet = true;
378 }
379 }
380
381 public static void enableStackTraces() {
382 printStackWhenAccessFails = true;
383 printStackWhenAccessSucceeds = true;
384 printStackPropertiesSet = true;
385 }
386
387 public static boolean printStackTraceWhenAccessFails() {
388 ensurePrintStackPropertiesSet();
389 return printStackWhenAccessFails;
390 }
391
392 public static boolean printStackTraceWhenAccessSucceeds() {
393 ensurePrintStackPropertiesSet();
394 return printStackWhenAccessSucceeds;
395 }
396
397 /**
398 * Throws IllegalAccessException with the an exception message based on
399 * the access that is denied.
400 */
401 private static void throwIllegalAccessException(Class<?> currentClass,
402 Class<?> memberClass,
403 Object target,
404 int modifiers)
405 throws IllegalAccessException
406 {
407 String currentSuffix = "";
408 String memberSuffix = "";
409 Module m1 = currentClass.getModule();
410 if (m1.isNamed())
411 currentSuffix = " (in " + m1 + ")";
412 Module m2 = memberClass.getModule();
413 if (m2.isNamed())
414 memberSuffix = " (in " + m2 + ")";
415
416 Class<?> c = memberClass;
417 while (c.isArray()) {
418 c = c.getComponentType();
419 }
420 String memberPackageName = c.getPackageName();
421
422 String msg = currentClass + currentSuffix + " cannot access ";
423 if (m2.isExported(memberPackageName, m1)) {
424
425 // module access okay so include the modifiers in the message
426 msg += "a member of " + memberClass + memberSuffix +
427 " with modifiers \"" + Modifier.toString(modifiers) + "\"";
428
429 } else {
430 // module access failed
431 msg += memberClass + memberSuffix+ " because "
432 + m2 + " does not export " + memberPackageName;
433 if (m2.isNamed()) msg += " to " + m1;
434 }
435
436 throwIllegalAccessException(msg);
437 }
438
439 /**
440 * Throws IllegalAccessException with the given exception message.
|
1 /*
2 * Copyright (c) 2001, 2017, 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
194
195 return true;
196 }
197
198 /**
199 * Returns {@code true} if memberClass's's module exports memberClass's
200 * package to currentClass's module.
201 */
202 public static boolean verifyModuleAccess(Class<?> currentClass,
203 Class<?> memberClass) {
204 return verifyModuleAccess(currentClass.getModule(), memberClass);
205 }
206
207 public static boolean verifyModuleAccess(Module currentModule, Class<?> memberClass) {
208 Module memberModule = memberClass.getModule();
209
210 // module may be null during startup (initLevel 0)
211 if (currentModule == memberModule)
212 return true; // same module (named or unnamed)
213
214 String pkg = memberClass.getPackageName();
215 boolean allowed = memberModule.isExported(pkg, currentModule);
216 if (allowed && memberModule.isNamed() && printStackTraceWhenAccessSucceeds()) {
217 if (!SharedSecrets.getJavaLangReflectModuleAccess()
218 .isStaticallyExported(memberModule, pkg, currentModule)) {
219 String msg = currentModule + " allowed access to member of " + memberClass;
220 new Exception(msg).printStackTrace(System.err);
221 }
222 }
223 return allowed;
224 }
225
226 /**
227 * Returns true if two classes in the same package.
228 */
229 private static boolean isSameClassPackage(Class<?> c1, Class<?> c2) {
230 if (c1.getClassLoader() != c2.getClassLoader())
231 return false;
232 return Objects.equals(c1.getPackageName(), c2.getPackageName());
233 }
234
235 static boolean isSubclassOf(Class<?> queryClass,
236 Class<?> ofClass)
237 {
238 while (queryClass != null) {
239 if (queryClass == ofClass) {
240 return true;
241 }
242 queryClass = queryClass.getSuperclass();
243 }
244 return false;
245 }
246
247 // fieldNames must contain only interned Strings
248 public static synchronized void registerFieldsToFilter(Class<?> containingClass,
249 String ... fieldNames) {
250 fieldFilterMap =
251 registerFilter(fieldFilterMap, containingClass, fieldNames);
349 private static volatile boolean printStackWhenAccessFails;
350
351 // true to print a stack trace when access succeeds
352 private static volatile boolean printStackWhenAccessSucceeds;
353
354 // true if printStack* values are initialized
355 private static volatile boolean printStackPropertiesSet;
356
357 private static void ensurePrintStackPropertiesSet() {
358 if (!printStackPropertiesSet && VM.initLevel() >= 1) {
359 String s = GetPropertyAction.privilegedGetProperty(
360 "sun.reflect.debugModuleAccessChecks");
361 if (s != null) {
362 printStackWhenAccessFails = !s.equalsIgnoreCase("false");
363 printStackWhenAccessSucceeds = s.equalsIgnoreCase("access");
364 }
365 printStackPropertiesSet = true;
366 }
367 }
368
369 public static boolean printStackTraceWhenAccessFails() {
370 ensurePrintStackPropertiesSet();
371 return printStackWhenAccessFails;
372 }
373
374 public static boolean printStackTraceWhenAccessSucceeds() {
375 ensurePrintStackPropertiesSet();
376 return printStackWhenAccessSucceeds;
377 }
378
379 /**
380 * Throws IllegalAccessException with the an exception message based on
381 * the access that is denied.
382 */
383 private static void throwIllegalAccessException(Class<?> currentClass,
384 Class<?> memberClass,
385 Object target,
386 int modifiers)
387 throws IllegalAccessException
388 {
389 String currentSuffix = "";
390 String memberSuffix = "";
391 Module m1 = currentClass.getModule();
392 if (m1.isNamed())
393 currentSuffix = " (in " + m1 + ")";
394 Module m2 = memberClass.getModule();
395 if (m2.isNamed())
396 memberSuffix = " (in " + m2 + ")";
397
398 String memberPackageName = memberClass.getPackageName();
399
400 String msg = currentClass + currentSuffix + " cannot access ";
401 if (m2.isExported(memberPackageName, m1)) {
402
403 // module access okay so include the modifiers in the message
404 msg += "a member of " + memberClass + memberSuffix +
405 " with modifiers \"" + Modifier.toString(modifiers) + "\"";
406
407 } else {
408 // module access failed
409 msg += memberClass + memberSuffix+ " because "
410 + m2 + " does not export " + memberPackageName;
411 if (m2.isNamed()) msg += " to " + m1;
412 }
413
414 throwIllegalAccessException(msg);
415 }
416
417 /**
418 * Throws IllegalAccessException with the given exception message.
|