module-info.java revision 1914:7b100002e7ae
1/* 2 * Copyright (c) 2015, 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 23 * questions. 24 */ 25 26/** 27 * Defines the API for dynamic linking of high-level operations on objects. 28 * <p> 29 * Dynalink is a library for dynamic linking of high-level operations on objects. 30 * These operations include "read a property", 31 * "write a property", "invoke a function" and so on. Dynalink is primarily 32 * useful for implementing programming languages where at least some expressions 33 * have dynamic types (that is, types that can not be decided statically), and 34 * the operations on dynamic types are expressed as 35 * {@link java.lang.invoke.CallSite call sites}. These call sites will be 36 * linked to appropriate target {@link java.lang.invoke.MethodHandle method handles} 37 * at run time based on actual types of the values the expressions evaluated to. 38 * These can change between invocations, necessitating relinking the call site 39 * multiple times to accommodate new types; Dynalink handles all that and more. 40 * <p> 41 * Dynalink supports implementation of programming languages with object models 42 * that differ (even radically) from the JVM's class-based model and have their 43 * custom type conversions. 44 * <p> 45 * Dynalink is closely related to, and relies on, the {@link java.lang.invoke} 46 * package. 47 * <p> 48 * 49 * While {@link java.lang.invoke} provides a low level API for dynamic linking 50 * of {@code invokedynamic} call sites, it does not provide a way to express 51 * higher level operations on objects, nor methods that implement them. These 52 * operations are the usual ones in object-oriented environments: property 53 * access, access of elements of collections, invocation of methods and 54 * constructors (potentially with multiple dispatch, e.g. link- and run-time 55 * equivalents of Java overloaded method resolution). These are all functions 56 * that are normally desired in a language on the JVM. If a language is 57 * statically typed and its type system matches that of the JVM, it can 58 * accomplish this with use of the usual invocation, field access, etc. 59 * instructions (e.g. {@code invokevirtual}, {@code getfield}). However, if the 60 * language is dynamic (hence, types of some expressions are not known until 61 * evaluated at run time), or its object model or type system don't match 62 * closely that of the JVM, then it should use {@code invokedynamic} call sites 63 * instead and let Dynalink manage them. 64 * <h2>Example</h2> 65 * Dynalink is probably best explained by an example showing its use. Let's 66 * suppose you have a program in a language where you don't have to declare the 67 * type of an object and you want to access a property on it: 68 * <pre> 69 * var color = obj.color; 70 * </pre> 71 * If you generated a Java class to represent the above one-line program, its 72 * bytecode would look something like this: 73 * <pre> 74 * aload 2 // load "obj" on stack 75 * invokedynamic "GET:PROPERTY:color"(Object)Object // invoke property getter on object of unknown type 76 * astore 3 // store the return value into local variable "color" 77 * </pre> 78 * In order to link the {@code invokedynamic} instruction, we need a bootstrap 79 * method. A minimalist bootstrap method with Dynalink could look like this: 80 * <pre> 81 * import java.lang.invoke.*; 82 * import jdk.dynalink.*; 83 * import jdk.dynalink.support.*; 84 * 85 * class MyLanguageRuntime { 86 * private static final DynamicLinker dynamicLinker = new DynamicLinkerFactory().createLinker(); 87 * 88 * public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type) { 89 * return dynamicLinker.link( 90 * new SimpleRelinkableCallSite( 91 * new CallSiteDescriptor(lookup, parseOperation(name), type))); 92 * } 93 * 94 * private static Operation parseOperation(String name) { 95 * ... 96 * } 97 * } 98 * </pre> 99 * There are several objects of significance in the above code snippet: 100 * <ul> 101 * <li>{@link jdk.dynalink.DynamicLinker} is the main object in Dynalink, it 102 * coordinates the linking of call sites to method handles that implement the 103 * operations named in them. It is configured and created using a 104 * {@link jdk.dynalink.DynamicLinkerFactory}.</li> 105 * <li>When the bootstrap method is invoked, it needs to create a 106 * {@link java.lang.invoke.CallSite} object. In Dynalink, these call sites need 107 * to additionally implement the {@link jdk.dynalink.RelinkableCallSite} 108 * interface. "Relinkable" here alludes to the fact that if the call site 109 * encounters objects of different types at run time, its target will be changed 110 * to a method handle that can perform the operation on the newly encountered 111 * type. {@link jdk.dynalink.support.SimpleRelinkableCallSite} and 112 * {@link jdk.dynalink.support.ChainedCallSite} (not used in the above example) 113 * are two implementations already provided by the library.</li> 114 * <li>Dynalink uses {@link jdk.dynalink.CallSiteDescriptor} objects to 115 * preserve the parameters to the bootstrap method: the lookup and the method type, 116 * as it will need them whenever it needs to relink a call site.</li> 117 * <li>Dynalink uses {@link jdk.dynalink.Operation} objects to express 118 * dynamic operations. It does not prescribe how would you encode the operations 119 * in your call site, though. That is why in the above example the 120 * {@code parseOperation} function is left empty, and you would be expected to 121 * provide the code to parse the string {@code "GET:PROPERTY:color"} 122 * in the call site's name into a named property getter operation object as 123 * {@code StandardOperation.GET.withNamespace(StandardNamespace.PROPERTY).named("color")}. 124 * </ul> 125 * <p>What can you already do with the above setup? {@code DynamicLinkerFactory} 126 * by default creates a {@code DynamicLinker} that can link Java objects with the 127 * usual Java semantics. If you have these three simple classes: 128 * <pre> 129 * public class A { 130 * public String color; 131 * public A(String color) { this.color = color; } 132 * } 133 * 134 * public class B { 135 * private String color; 136 * public B(String color) { this.color = color; } 137 * public String getColor() { return color; } 138 * } 139 * 140 * public class C { 141 * private int color; 142 * public C(int color) { this.color = color; } 143 * public int getColor() { return color; } 144 * } 145 * </pre> 146 * and you somehow create their instances and pass them to your call site in your 147 * programming language: 148 * <pre> 149 * for each(var obj in [new A("red"), new B("green"), new C(0x0000ff)]) { 150 * print(obj.color); 151 * } 152 * </pre> 153 * then on first invocation, Dynalink will link the {@code .color} getter 154 * operation to a field getter for {@code A.color}, on second invocation it will 155 * relink it to {@code B.getColor()} returning a {@code String}, and finally on 156 * third invocation it will relink it to {@code C.getColor()} returning an {@code int}. 157 * The {@code SimpleRelinkableCallSite} we used above only remembers the linkage 158 * for the last encountered type (it implements what is known as a <i>monomorphic 159 * inline cache</i>). Another already provided implementation, 160 * {@link jdk.dynalink.support.ChainedCallSite} will remember linkages for 161 * several different types (it is a <i>polymorphic inline cache</i>) and is 162 * probably a better choice in serious applications. 163 * <h2>Dynalink and bytecode creation</h2> 164 * {@code CallSite} objects are usually created as part of bootstrapping 165 * {@code invokedynamic} instructions in bytecode. Hence, Dynalink is typically 166 * used as part of language runtimes that compile programs into Java 167 * {@code .class} bytecode format. Dynalink does not address the aspects of 168 * either creating bytecode classes or loading them into the JVM. That said, 169 * Dynalink can also be used without bytecode compilation (e.g. in language 170 * interpreters) by creating {@code CallSite} objects explicitly and associating 171 * them with representations of dynamic operations in the interpreted program 172 * (e.g. a typical representation would be some node objects in a syntax tree). 173 * <h2>Available operations</h2> 174 * Dynalink defines several standard operations in its 175 * {@link jdk.dynalink.StandardOperation} class. The linker for Java 176 * objects can link all of these operations, and you are encouraged to at 177 * minimum support and use these operations in your language too. The 178 * standard operations {@code GET} and {@code SET} need to be combined with 179 * at least one {@link jdk.dynalink.Namespace} to be useful, e.g. to express a 180 * property getter, you'd use {@code StandardOperation.GET.withNamespace(StandardNamespace.PROPERTY)}. 181 * Dynalink defines three standard namespaces in the {@link jdk.dynalink.StandardNamespace} class. 182 * To associate a fixed name with an operation, you can use 183 * {@link jdk.dynalink.NamedOperation} as in the previous example: 184 * {@code StandardOperation.GET.withNamespace(StandardNamespace.PROPERTY).named("color")} 185 * expresses a getter for the property named "color". 186 * <h2>Operations on multiple namespaces</h2> 187 * Some languages might not have separate namespaces on objects for 188 * properties, elements, and methods, and a source language construct might 189 * address several of them at once. Dynalink supports specifying multiple 190 * {@link jdk.dynalink.Namespace} objects with {@link jdk.dynalink.NamespaceOperation}. 191 * <h2>Language-specific linkers</h2> 192 * Languages that define their own object model different than the JVM 193 * class-based model and/or use their own type conversions will need to create 194 * their own language-specific linkers. See the {@link jdk.dynalink.linker} 195 * package and specifically the {@link jdk.dynalink.linker.GuardingDynamicLinker} 196 * interface to get started. 197 * <h2>Dynalink and Java objects</h2> 198 * The {@code DynamicLinker} objects created by {@code DynamicLinkerFactory} by 199 * default contain an internal instance of 200 * {@code BeansLinker}, which is a language-specific linker 201 * that implements the usual Java semantics for all of the above operations and 202 * can link any Java object that no other language-specific linker has managed 203 * to link. This way, all language runtimes have built-in interoperability with 204 * ordinary Java objects. See {@link jdk.dynalink.beans.BeansLinker} for details 205 * on how it links the various operations. 206 * <h2>Cross-language interoperability</h2> 207 * A {@code DynamicLinkerFactory} can be configured with a 208 * {@link jdk.dynalink.DynamicLinkerFactory#setClassLoader(ClassLoader) class 209 * loader}. It will try to instantiate all 210 * {@link jdk.dynalink.linker.GuardingDynamicLinkerExporter} classes visible to 211 * that class loader and compose the linkers they provide into the 212 * {@code DynamicLinker} it creates. This allows for interoperability between 213 * languages: if you have two language runtimes A and B deployed in your JVM and 214 * they export their linkers through the above mechanism, language runtime A 215 * will have a language-specific linker instance from B and vice versa inside 216 * their {@code DynamicLinker} objects. This means that if an object from 217 * language runtime B gets passed to code from language runtime A, the linker 218 * from B will get a chance to link the call site in A when it encounters the 219 * object from B. 220 * 221 * @uses jdk.dynalink.linker.GuardingDynamicLinkerExporter 222 * 223 * @moduleGraph 224 * @since 9 225 */ 226module jdk.dynalink { 227 requires java.logging; 228 229 exports jdk.dynalink; 230 exports jdk.dynalink.beans; 231 exports jdk.dynalink.linker; 232 exports jdk.dynalink.linker.support; 233 exports jdk.dynalink.support; 234 235 uses jdk.dynalink.linker.GuardingDynamicLinkerExporter; 236} 237 238