gudzpoz / luajava

Lua for Java on Windows, Mac OS X, Linux, Android. 5.1, 5.2, 5.3, 5.4, LuaJ or LuaJIT.
https://gudzpoz.github.io/luajava/
Other
154 stars 21 forks source link

`java.proxy` does not default calls to `default` methods #22

Closed leasses closed 2 years ago

leasses commented 2 years ago

For example, I create a interface Test in java.

// Test.java
 public interface Test{
        default String test() {
            return "Success";
        }
}

And implement it in Lua with java.proxy.

// Main.java
// Import and init the class.
LuaJit L = new LuaJit()
... // Init the LuaState.
Test test = L.run('java.proxy("Test", {})
System.out.printIn("The result is: " + test.test())

The output should be The result is: Success, but when I run this, it throws an Exception:

It looks like java.proxy didnt't implement the test method. All in all, thanks for your contribution!

gudzpoz commented 2 years ago

Thanks for reporting! And nice to see you again :-)

This should be working in the latest snapshot (see the default-proxy branch). However, the current implementation is really nasty due to Java's own limitation (Spring, jOOR). #invokeDefault​ is only available after Java 16, and one will have to live with these warning messages for Java 9 and on:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access using Lookup on party.iroiro.luajava.LuaProxy (file:...) to interface ...
WARNING: Please consider reporting this to the maintainers of party.iroiro.luajava.LuaProxy
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

I will create a new release after adding more tests and some documentation. Thanks again!

leasses commented 2 years ago

Emm, I added asm library to my project, and set luajava_lookup to asm. But I got this Exception:

W/System.err: java.lang.RuntimeException: java.io.IOException: Class not found
W/System.err:     at party.iroiro.luajava.util.AsmLookupProvider.lookupExtender(AsmLookupProvider.java:51)
W/System.err:     at party.iroiro.luajava.util.AsmLookupProvider.wrap(AsmLookupProvider.java:71)
W/System.err:     at party.iroiro.luajava.util.ClassUtils.wrap(ClassUtils.java:320)
W/System.err:     at party.iroiro.luajava.AbstractLua$$ExternalSyntheticLambda1.apply(Unknown Source:2)
W/System.err:     at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:194)
W/System.err:     at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
W/System.err:     at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
W/System.err:     at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
W/System.err:     at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:546)
W/System.err:     at java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:261)
W/System.err:     at java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:440)
W/System.err:     at party.iroiro.luajava.AbstractLua.createProxy(AbstractLua.java:678)
W/System.err:     at party.iroiro.luajava.JuaAPI.proxy(JuaAPI.java:62)
W/System.err:     at party.iroiro.luajava.LuaJitNatives.luaL_dostring(Native Method)
W/System.err:     at party.iroiro.luajava.AbstractLua.run(AbstractLua.java:490)

What should I do?

leasses commented 2 years ago

I use java.import to import the class, it can goes successfully, but when I import an interface, it tells me the class not found. I also tried java.proxy("example.Interface").

gudzpoz commented 2 years ago

It is very likely a problem with Android. We use SampleExtender as a template to extend the target interfaces, and require that SampleExtender.class be readable as a resource. However, Android aggregates the .class files into .dex, and therefore ASM complains that it cannot find SampleExtender.class anymore.

Hmm, actually it is possible to manipulate Java byte code directly without using ASM. I shall experiment with storing the template elsewhere first, hopefully ridding the ASM dependency as well.

leasses commented 2 years ago

Thanks and I am waitting for a new version! I think it's an ASM problem, too. There is other tests: There is an interface example.Interface. It has a default method. Import java.lang.Class with java.import, and use Class:forName("example.Interface"), print the result, it can successfully print the interface. But then I use java.proxy(, ...), it throws an RuntimeException, just like the above comments. I deleted the default method, it also can't work. I tried the Console, it works. I tried to package the interface into .jar file and run it, It works. If you need more tests, free to comment!

gudzpoz commented 2 years ago

This should have been fixed by #32 in the latest snapshot. You are welcome to re-open this issue if the trouble persists though.