31 import java.lang.invoke.MethodHandles;
32 import java.lang.invoke.MethodHandles.Lookup;
33 import java.lang.invoke.MethodType;
34 import java.lang.reflect.Modifier;
35 import java.security.AccessControlContext;
36 import java.security.AccessController;
37 import java.security.CodeSigner;
38 import java.security.CodeSource;
39 import java.security.Permissions;
40 import java.security.PrivilegedAction;
41 import java.security.ProtectionDomain;
42 import java.util.ArrayList;
43 import java.util.Arrays;
44 import java.util.Collections;
45 import java.util.HashMap;
46 import java.util.List;
47 import java.util.Map;
48 import java.util.concurrent.ConcurrentHashMap;
49 import jdk.internal.dynalink.beans.StaticClass;
50 import jdk.internal.dynalink.support.LinkRequestImpl;
51 import jdk.nashorn.internal.objects.NativeJava;
52 import jdk.nashorn.internal.runtime.Context;
53 import jdk.nashorn.internal.runtime.ECMAException;
54 import jdk.nashorn.internal.runtime.ScriptFunction;
55 import jdk.nashorn.internal.runtime.ScriptObject;
56
57 /**
58 * <p>A factory class that generates adapter classes. Adapter classes allow implementation of Java interfaces and
59 * extending of Java classes from JavaScript. For every combination of a superclass to extend and interfaces to
60 * implement (collectively: "original types"), exactly one adapter class is generated that extends the specified
61 * superclass and implements the specified interfaces. (But see the discussion of class-based overrides for exceptions.)
62 * </p><p>
63 * The adapter class is generated in a new secure class loader that inherits Nashorn's protection domain, and has either
64 * one of the original types' class loader or the Nashorn's class loader as its parent - the parent class loader
65 * is chosen so that all the original types and the Nashorn core classes are visible from it (as the adapter will have
66 * constant pool references to ScriptObject and ScriptFunction classes). In case none of the candidate class loaders has
67 * visibility of all the required types, an error is thrown. The class uses {@link JavaAdapterBytecodeGenerator} to
68 * generate the adapter class itself; see its documentation for details about the generated class.
69 * </p><p>
70 * You normally don't use this class directly, but rather either create adapters from script using
71 * {@link NativeJava#extend(Object, Object...)}, using the {@code new} operator on abstract classes and interfaces (see
72 * {@link NativeJava#type(Object, Object)}), or implicitly when passing script functions to Java methods expecting SAM
73 * types.
74 * </p>
75 */
76
77 @SuppressWarnings("javadoc")
78 public final class JavaAdapterFactory {
79 private static final ProtectionDomain MINIMAL_PERMISSION_DOMAIN = createMinimalPermissionDomain();
80
81 // context with permissions needs for AdapterInfo creation
82 private static final AccessControlContext CREATE_ADAPTER_INFO_ACC_CTXT =
83 ClassAndLoader.createPermAccCtxt("createClassLoader", "getClassLoader",
84 "accessDeclaredMembers", "accessClassInPackage.jdk.nashorn.internal.runtime");
85
86 /**
87 * A mapping from an original Class object to AdapterInfo representing the adapter for the class it represents.
88 */
89 private static final ClassValue<Map<List<Class<?>>, AdapterInfo>> ADAPTER_INFO_MAPS = new ClassValue<Map<List<Class<?>>, AdapterInfo>>() {
90 @Override
91 protected Map<List<Class<?>>, AdapterInfo> computeValue(final Class<?> type) {
92 return new HashMap<>();
320 * @param classAndLoader the loader and a representative class from it that will be used to add the generated
321 * adapter to its ADAPTER_INFO_MAPS.
322 * @return the class loader that sees both the specified class and Nashorn classes.
323 * @throws IllegalStateException if no such class loader is found.
324 */
325 private static ClassLoader findCommonLoader(final ClassAndLoader classAndLoader) throws AdaptationException {
326 if(classAndLoader.canSee(SCRIPT_OBJECT_LOADER)) {
327 return classAndLoader.getLoader();
328 }
329 if (SCRIPT_OBJECT_LOADER.canSee(classAndLoader)) {
330 return SCRIPT_OBJECT_LOADER.getLoader();
331 }
332
333 throw new AdaptationException(AdaptationResult.Outcome.ERROR_NO_COMMON_LOADER, classAndLoader.getRepresentativeClass().getCanonicalName());
334 }
335 }
336
337 private static ProtectionDomain createMinimalPermissionDomain() {
338 // Generated classes need to have at least the permission to access Nashorn runtime and runtime.linker packages.
339 final Permissions permissions = new Permissions();
340 permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime"));
341 permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime.linker"));
342 return new ProtectionDomain(new CodeSource(null, (CodeSigner[])null), permissions);
343 }
344 }
|
31 import java.lang.invoke.MethodHandles;
32 import java.lang.invoke.MethodHandles.Lookup;
33 import java.lang.invoke.MethodType;
34 import java.lang.reflect.Modifier;
35 import java.security.AccessControlContext;
36 import java.security.AccessController;
37 import java.security.CodeSigner;
38 import java.security.CodeSource;
39 import java.security.Permissions;
40 import java.security.PrivilegedAction;
41 import java.security.ProtectionDomain;
42 import java.util.ArrayList;
43 import java.util.Arrays;
44 import java.util.Collections;
45 import java.util.HashMap;
46 import java.util.List;
47 import java.util.Map;
48 import java.util.concurrent.ConcurrentHashMap;
49 import jdk.internal.dynalink.beans.StaticClass;
50 import jdk.internal.dynalink.support.LinkRequestImpl;
51 import jdk.nashorn.internal.runtime.Context;
52 import jdk.nashorn.internal.runtime.ECMAException;
53 import jdk.nashorn.internal.runtime.ScriptFunction;
54 import jdk.nashorn.internal.runtime.ScriptObject;
55
56 /**
57 * <p>A factory class that generates adapter classes. Adapter classes allow implementation of Java interfaces and
58 * extending of Java classes from JavaScript. For every combination of a superclass to extend and interfaces to
59 * implement (collectively: "original types"), exactly one adapter class is generated that extends the specified
60 * superclass and implements the specified interfaces. (But see the discussion of class-based overrides for exceptions.)
61 * </p><p>
62 * The adapter class is generated in a new secure class loader that inherits Nashorn's protection domain, and has either
63 * one of the original types' class loader or the Nashorn's class loader as its parent - the parent class loader
64 * is chosen so that all the original types and the Nashorn core classes are visible from it (as the adapter will have
65 * constant pool references to ScriptObject and ScriptFunction classes). In case none of the candidate class loaders has
66 * visibility of all the required types, an error is thrown. The class uses {@link JavaAdapterBytecodeGenerator} to
67 * generate the adapter class itself; see its documentation for details about the generated class.
68 * </p><p>
69 * You normally don't use this class directly, but rather either create adapters from script using
70 * {@link jdk.nashorn.internal.objects.NativeJava#extend(Object, Object...)}, using the {@code new} operator on abstract classes and interfaces (see
71 * {@link jdk.nashorn.internal.objects.NativeJava#type(Object, Object)}), or implicitly when passing script functions to Java methods expecting SAM
72 * types.
73 * </p>
74 */
75
76 @SuppressWarnings("javadoc")
77 public final class JavaAdapterFactory {
78 private static final ProtectionDomain MINIMAL_PERMISSION_DOMAIN = createMinimalPermissionDomain();
79
80 // context with permissions needs for AdapterInfo creation
81 private static final AccessControlContext CREATE_ADAPTER_INFO_ACC_CTXT =
82 ClassAndLoader.createPermAccCtxt("createClassLoader", "getClassLoader",
83 "accessDeclaredMembers", "accessClassInPackage.jdk.nashorn.internal.runtime");
84
85 /**
86 * A mapping from an original Class object to AdapterInfo representing the adapter for the class it represents.
87 */
88 private static final ClassValue<Map<List<Class<?>>, AdapterInfo>> ADAPTER_INFO_MAPS = new ClassValue<Map<List<Class<?>>, AdapterInfo>>() {
89 @Override
90 protected Map<List<Class<?>>, AdapterInfo> computeValue(final Class<?> type) {
91 return new HashMap<>();
319 * @param classAndLoader the loader and a representative class from it that will be used to add the generated
320 * adapter to its ADAPTER_INFO_MAPS.
321 * @return the class loader that sees both the specified class and Nashorn classes.
322 * @throws IllegalStateException if no such class loader is found.
323 */
324 private static ClassLoader findCommonLoader(final ClassAndLoader classAndLoader) throws AdaptationException {
325 if(classAndLoader.canSee(SCRIPT_OBJECT_LOADER)) {
326 return classAndLoader.getLoader();
327 }
328 if (SCRIPT_OBJECT_LOADER.canSee(classAndLoader)) {
329 return SCRIPT_OBJECT_LOADER.getLoader();
330 }
331
332 throw new AdaptationException(AdaptationResult.Outcome.ERROR_NO_COMMON_LOADER, classAndLoader.getRepresentativeClass().getCanonicalName());
333 }
334 }
335
336 private static ProtectionDomain createMinimalPermissionDomain() {
337 // Generated classes need to have at least the permission to access Nashorn runtime and runtime.linker packages.
338 final Permissions permissions = new Permissions();
339 permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.objects"));
340 permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime"));
341 permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime.linker"));
342 return new ProtectionDomain(new CodeSource(null, (CodeSigner[])null), permissions);
343 }
344 }
|