Skip to content

Commit

Permalink
Introduce an API exposing some OpenJDK internals
Browse files Browse the repository at this point in the history
  • Loading branch information
mpfaff committed Aug 10, 2024
1 parent fc8dc71 commit ddd2344
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 0 deletions.
90 changes: 90 additions & 0 deletions src/java.base/share/classes/dev/pfaff/jdk/JavaInternalAccess.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package dev.pfaff.jdk;

import jdk.internal.access.SharedSecrets;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.CallerSensitiveAdapter;
import jdk.internal.reflect.Reflection;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.Stable;

import java.lang.invoke.MethodHandles.Lookup;

/**
* Provides access to internal OpenJDK APIs.
*/
public final class JavaInternalAccess {
@Stable
private static volatile boolean RESTRICTED;

private static final JavaInternalAccess INSTANCE = new JavaInternalAccess();

private JavaInternalAccess() {}

/**
* @return the instance
* @throws SecurityException if access has been restricted by a call to {@link #restrictAccess()}
*/
public static JavaInternalAccess getInstance() {
if (RESTRICTED) {
throw new SecurityException("Access is restricted");
}
return INSTANCE;
}

/**
* Restricts access to {@link JavaInternalAccess} by blocking future calls to {@link #getInstance()}.
*/
public void restrictAccess() {
if (!RESTRICTED) RESTRICTED = true;
}

/**
* Creates a new {@link Lookup lookup object} with trusted access, which
* reports the specified class as its {@link Lookup#lookupClass() lookupClass}.
*
* @return the new {@link Lookup lookup object}
*/
@CallerSensitive
@ForceInline // to ensure Reflection.getCallerClass optimization
public Lookup trustedLookup() {
final Class<?> c = Reflection.getCallerClass();
if (c == null) {
throw new IllegalCallerException("no caller frame");
}
return SharedSecrets.getJavaLangInvokeAccess().makeTrustedLookup(c);
}

// Caller-sensitive adapter method for reflective invocation
@CallerSensitiveAdapter
private Lookup trustedLookup(Class<?> caller) {
if (caller.getClassLoader() == null) {
throw new InternalError("calling trustedLookup() reflectively is not supported: "+caller);
}
return SharedSecrets.getJavaLangInvokeAccess().makeTrustedLookup(caller);
}

/**
* Updates module m1 to export a package to module m2. If m1 already
* exports or opens the package to m2, this operation has no effect.
*
* @param m1 the module to update
* @param pkg the package to export or open
* @param m2 the module export or open to
*/
public void addExports(Module m1, String pkg, Module m2) {
SharedSecrets.getJavaLangAccess().addExports(m1, pkg, m2);
}

/**
* Updates module m1 to open a package to module m2. If m1 already opens
* the package to m2, this operation has no effect. If m1 already exports
* the package to m2, the export will be promoted to an open.
*
* @param m1 the module to update
* @param pkg the package to export or open
* @param m2 the module export or open to
*/
public void addOpens(Module m1, String pkg, Module m2) {
SharedSecrets.getJavaLangAccess().addOpens(m1, pkg, m2);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,13 @@ public interface JavaLangInvokeAccess {
* This method should only be used by ReflectionFactory::newConstructorForSerialization.
*/
MethodHandle serializableConstructor(Class<?> decl, Constructor<?> ctorToCall) throws IllegalAccessException;

/**
* Creates a new {@link Lookup lookup object} with trusted access, which
* reports the specified class as its {@link Lookup#lookupClass() lookupClass}.
*
* @param lookupClass lookup class
* @return the new {@link Lookup lookup object}
*/
Lookup makeTrustedLookup(Class<?> lookupClass);
}
2 changes: 2 additions & 0 deletions src/java.base/share/classes/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@
exports sun.util.resources to
jdk.localedata;

exports dev.pfaff.jdk;

// the service types defined by the APIs in this module

uses java.lang.System.LoggerFinder;
Expand Down

0 comments on commit ddd2344

Please sign in to comment.