WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by EvilClassLoader.evilByteClassloader (file:/D:/java_local/Temp/target/classes/) to method java.lang.ClassLoader.defineClass(byte[],int,int) WARNING: Please consider reporting this to the maintainers of EvilClassLoader.evilByteClassloader WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release
Some tools and libraries use reflection to access parts of the JDK that are meant for internal use only. This use of reflection negatively impacts the security and maintainability of the JDK. To aid migration, JDK 9 through JDK 16 allowed this reflection to continue, but emitted warnings about illegal reflective access. However, JDK 17 is strongly encapsulated, so this reflection is no longer permitted by default.
Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make protectedfinal java.lang.Class java.lang.ClassLoader.defineClass(byte[],int,int) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @404b9385 at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199) at java.base/java.lang.reflect.Method.setAccessible(Method.java:193) at EvilClassLoader.evilByteClassloader.main(evilByteClassloader.java:13)
if (callerModule == declaringModule) returntrue; if (callerModule == Object.class.getModule()) returntrue; if (!declaringModule.isNamed()) returntrue;
Stringpn= declaringClass.getPackageName(); int modifiers; if (thisinstanceof Executable) { modifiers = ((Executable) this).getModifiers(); } else { modifiers = ((Field) this).getModifiers(); }
// class is public and package is exported to caller booleanisClassPublic= Modifier.isPublic(declaringClass.getModifiers()); if (isClassPublic && declaringModule.isExported(pn, callerModule)) { // member is public if (Modifier.isPublic(modifiers)) { returntrue; }
// member is protected-static if (Modifier.isProtected(modifiers) && Modifier.isStatic(modifiers) && isSubclassOf(caller, declaringClass)) { returntrue; } }
// package is open to caller if (declaringModule.isOpen(pn, callerModule)) { returntrue; }
if (throwExceptionIfDenied) { // not accessible Stringmsg="Unable to make "; if (thisinstanceof Field) msg += "field "; msg += this + " accessible: " + declaringModule + " does not \""; if (isClassPublic && Modifier.isPublic(modifiers)) msg += "exports"; else msg += "opens"; msg += " " + pn + "\" to " + callerModule; InaccessibleObjectExceptione=newInaccessibleObjectException(msg); if (printStackTraceWhenAccessFails()) { e.printStackTrace(System.err); } throw e; } returnfalse; }
publiclongobjectFieldOffset(Field f) { if (f == null) { thrownewNullPointerException(); } Class<?> declaringClass = f.getDeclaringClass(); if (declaringClass.isHidden()) { thrownewUnsupportedOperationException("can't get field offset on a hidden class: " + f); } if (declaringClass.isRecord()) { thrownewUnsupportedOperationException("can't get field offset on a record class: " + f); } return theInternalUnsafe.objectFieldOffset(f); }
getAndSetObject
获取一个对象在特定内存偏移量上的当前值,并将其替换为一个新值。
1 2 3
publicfinal Object getAndSetObject(Object o, long offset, Object newValue) { return theInternalUnsafe.getAndSetReference(o, offset, newValue); }
putObject
用于将一个对象(或引用)写入到指定对象的内存偏移量
1 2 3
publicvoid putObject(Object o, long offset, Object x) { theInternalUnsafe.putReference(o, offset, x); }