1

I'm trying to figure out how to pass my Javascript function to my Java method so that I can call it at runtime.

I have the following Java Method Signature:

public static void createBlock(String domain, String name, String eventType, EventFunction eventHandler)

I am calling this from Javascript like this:

function main() {
    BlockManager.createBlock('sarah-egg', 'enderBlock', 'breakBlock', func);
}

function func (event) { 
    event.world.createExplosion(null, event.pos.getX(), event.pos.getY(), event.pos.getZ, 10, true); 
}

And I have made my Java Functional Interface, EventFunction, like this:

package com.learntomod.event;

@FunctionalInterface
public interface EventFunction<T> {
    void fun(T t);
}

When I run it, I'm getting this error:

Cannot cast jdk.nashorn.internal.objects.ScriptFunctionImpl to com.learntomod.event.EventFunction

I tried changing EventFunction to Runnable and getting rid of the parameter, and it worked.

Any ideas on what I might be doing wrong?

6
  • 1
    That's not how functional interfaces work. They are no function references. If I understand docs.oracle.com/javase/8/docs/technotes/guides/scripting/… right you'd pass an Invocable to your Java method. Commented Dec 4, 2015 at 22:36
  • I have also tried passing an invocable instead of doing it this way - and that didn't work either. My understanding is that both "should" work and the way I'm trying to do it is the way that people recommend with Java 8? But I'm not sure. I will re-read that doc and try it again though! :) Thanks! Commented Dec 4, 2015 at 22:38
  • 1
    Could you post a full, yet concise, reproducing example? Commented Dec 4, 2015 at 22:57
  • 1
    Oh, I see, you're trying to do what's described under [ Lambdas, SAM types and Script functions](wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions): Implement the Java EventFunction interface in JavaScript as function func(event). That's possible (compare ideone.com/amHsPp ) but I think you'll have to get rid of the generic <T>. Commented Dec 4, 2015 at 23:42
  • @Tunaki - my co-dev is working on a reproducing example now Commented Dec 4, 2015 at 23:49

1 Answer 1

2

OK - so it turns out that Forge might have been the culprit all along.

Forge does some wonky things with changing the class loader, and so Java might have just not auto-changed my JS function to my EventFunction Functional Interface type (or something like that).

In any case - I found a "solution" - I used https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html - which is a part of Java Util, and since Runnable worked, we decided to try Function (which takes in a parameter) and...it worked!

Now my custom blocks will explode when you break them ;) https://www.youtube.com/watch?v=7IJVeC48z6I&feature=youtu.be

Thanks for your help guys!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.