need little help for class loading & invokeDynamics
Rémi Forax
forax at univ-mlv.fr
Thu Jan 13 23:59:48 PST 2011
On 01/14/2011 06:15 AM, Marvin Hansen wrote:
> Hi Folks,
>
> I've started to work on invokeDynamics but I need a little help to
> understand how to use it right. For learning purpose, I've written a
> little class, that loads another class, does the method look-up and
> (should) execute the located method. The example in the methodHandle
> JavaDoc was my starting point but as usual it's not that easy since it
> works well for JDK classes but not with loading my own class which
> causes a “NoAccessException”.
>
> I suppose that I need to deal with CallSite& Bootstraping but I've
> not yet figured out how to patch class-loading, methodHandle,
> Bootstraping& invocation together in order to make it work. The
> JavaDoc says, that before an invokedynamic instruction can be executed
> a CallSite must be linked via boostrap method that produces a
> methodHandle. That makes sense for me.
>
> However, the CallSite JavaDoc is a little bit short on illustrating
> how to use it together with class-loading.
> The given example bootstrap Method:
>
> private static CallSite bootstrapDynamic(MethodHandles.Lookup caller,
> String name, MethodType type) {
> // ignore caller and name, but match the type:
> return new ConstantCallSite(MethodHandles.collectArguments(printArgs, type));
> }
>
> looks fine but this method is neither used nor linked or registered
> in the sample code of the JavaDoc so here are my related questions:
>
> 1) What is needed in a bootstrap method to produce a working callSite
> for a loaded class?
>
> 2) How is the bootstrap method linked to an invokedynamic instruction?
> The spec does not have the @BootstrapMethod anymore so what's the
> current way of linking?
>
> 3) Should the class-loading be done by the bootstrap method or is it
> fine to do it before?
>
>
> I really appriciate any input, since I'm new to InvokeDynamics and not
> familiar with all concepts.
>
> marvin
>
>
> JDK is b123
> JVM Parameter: -Xbootclasspath/main -XX:+UnlockExperimentalVMOptions
> -XX:+EnableInvokeDynamic -XX:+EnableMethodHandles
>
> The class file (without any boostraping):
>
> package main;
> import java.dyn.*;
> public class DynInvoker {
> public static void main(String[] args) throws Throwable {
>
> String cName = "algorithms.SimpleMath";
>
> //variable for invokeDynamic
> MethodType methodType;
> MethodHandle methodHandle;
> MethodHandles.Lookup lookup = MethodHandles.lookup();
>
> //(1) load the class
> Class<?> loadedClaZZ = Class.forName(cName);
>
> String runMethodName = "run";
> Class retType = int.class;
>
> // (2) get methodType
> // signature is: public int run(int a, int b, String op)
> methodType = MethodType.methodType(retType, int.class,
> String.class, int.class);
>
> // (3) look-up the method
> methodHandle = lookup.findVirtual(loadedClaZZ, runMethodName,
> methodType);
> /* causes:
> * java.dyn.NoAccessException: cannot access:
> *.algorithms.SimpleMath.run(int,String,int)int, from main.DynInvoker
> */
>
> // (4) do the invokation
> Object o = methodHandle.invokeWithArguments(21, "+", 21);
> System.out.println(o.toString());
> } }
>
> The full Error msg:
>
> Exception in thread "main" java.dyn.NoAccessException: cannot access:
> *.algorithms.SimpleMath.run(int,String,int)int, from main.DynInvoker
> at sun.dyn.MemberName.newNoAccessException(MemberName.java:522)
> at sun.dyn.MemberName.newNoAccessException(MemberName.java:516)
> at sun.dyn.MemberName$Factory.resolveOrFail(MemberName.java:653)
> at java.dyn.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:688)
> at java.dyn.MethodHandles$Lookup.findVirtual(MethodHandles.java:413)
> at main.DynInvoker.main(DynInvoker.java:46)
> Java Result: 1
lookup enforces the same access rules as Java.
Is SimpleMath.run is visible from main.DynInvoker ?
The usual mistake is to forget to declare class SimpleMath public.
Rémi
More information about the mlvm-dev
mailing list