Button error in gradle build

Hope its ok I post my findings, just trying to learn :slight_smile: I get this when I gradle build Lemur:

21:36:38.058 [INFO] [org.gradle.api.internal.tasks.compile.JdkJavaCompiler] Compiling with JDK Java compiler API.
21:36:38.372 [ERROR] [system.err] E:\Development\GitHub\jMonkeyEngine-Contribution\Lemur\src\main\java\com\simsilica\lemur\Button.java:410: error: no suitable method found for click(no arguments)
21:36:38.372 [ERROR] [system.err]                     click();
21:36:38.372 [ERROR] [system.err]                     ^
21:36:38.372 [ERROR] [system.err]     method DefaultMouseListener.click(MouseButtonEvent,Spatial,Spatial) is not applicable
21:36:38.372 [ERROR] [system.err]       (actual and formal argument lists differ in length)
21:36:38.373 [ERROR] [system.err]     method Button.ButtonMouseHandler.click(MouseButtonEvent,Spatial,Spatial) is not applicable
21:36:38.373 [ERROR] [system.err]       (actual and formal argument lists differ in length)
21:36:38.517 [ERROR] [system.err] Note: Some input files use or override a deprecated API.
21:36:38.517 [ERROR] [system.err] Note: Recompile with -Xlint:deprecation for details.
21:36:38.517 [ERROR] [system.err] Note: Some input files use unchecked or unsafe operations.
21:36:38.517 [ERROR] [system.err] Note: Recompile with -Xlint:unchecked for details.
21:36:38.517 [ERROR] [system.err] 1 error
21:36:38.518 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':compileJava'
21:36:38.518 [LIFECYCLE] [class org.gradle.internal.buildevents.TaskExecutionLogger] :compileJava FAILED
21:36:38.518 [INFO] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] :compileJava (Thread[Daemon worker Thread 9,5,main]) completed. Took 0.497 secs.
21:36:38.518 [DEBUG] [org.gradle.internal.operations.DefaultBuildOperationWorkerRegistry] Worker root.1 completed (0 in use)
21:36:38.518 [DEBUG] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] Task worker [Thread[Daemon worker Thread 9,5,main]] finished, busy: 0.497 secs, idle: 0.0 secs
21:36:38.519 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]
21:36:38.519 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] FAILURE: Build failed with an exception.
21:36:38.519 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]
21:36:38.519 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] * What went wrong:
21:36:38.519 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] Execution failed for task ':compileJava'.
21:36:38.519 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] > Compilation failed; see the compiler error output for details.
21:36:38.519 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter]
21:36:38.519 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] * Try:
21:36:38.519 [ERROR] [org.gradle.internal.buildevents.BuildExceptionReporter] Run with --stacktrace option to get the stack trace.
21:36:38.519 [LIFECYCLE] [org.gradle.internal.buildevents.BuildResultLogger]
21:36:38.519 [LIFECYCLE] [org.gradle.internal.buildevents.BuildResultLogger] BUILD FAILED
21:36:38.519 [LIFECYCLE] [org.gradle.internal.buildevents.BuildResultLogger]
21:36:38.519 [LIFECYCLE] [org.gradle.internal.buildevents.BuildResultLogger] Total time: 2.137 secs

What Java compiler are you using? It seems to not be able to find methods in the outer class for some reason.

I am using JDK 8 - perhaps I should revert to JDK 7 - I’ll try that. Will report back :slight_smile:

I meant… you are using Oracle’s java or?

It’s just really strange that it can’t find the protected click() method in the outer class. That’s perfectly legal and there is no ambiguity.

Yea, Oracle’s Java JDK 8

Got the same issue, fixed right away :slight_smile:

Same fix I did locally. I haven’t gotten into the whole fork/fix/pull mechanics yet - but will try it in the future when I have a proposed fix for something :slight_smile:

Your fix is calling the wrong method. The whole point is to call the method in the outer class as the one in the inner class doesn’t do the right thing anymore.

…with your change, the click events won’t be fired.

The real question is why isn’t Java 8 finding the click() method that is perfectly in scope for the inner class:

If Java 8 changed to the scoping rules then it’s really stupid… because protected should be available to both inner classes as well as friendly access to everything else in the package.

But the call you’ve changed it do does nothing:

…and so breaks a bunch of stuff. It’s only there to override the superclass’s method.

I’ve just checked Button.java with a fix that hopefully works around this bug in the Java 8 compiler. (I can’t see how it’s not a javac bug, anyway.)

I hope this is the proper fix

Or try my fix… because it seems to work fine for the other inner class that doesn’t have its own click() method. So I renamed the outer class click() method to runClick() to work around the bug in the Java 8 compiler.

My commit:

Thanks.

Well I can’t fid any hint whether this is desired or not, but the easier solution woud have been:
Button.this.click();

Except it’s ugly and if you’ve ever looked at the byte code, it’s often more instructions.

Easier to work around a compiler bug with a method name change.

More bytecode does not necessarily means that it takes longer.

BTW

for (int i = 0; i < 10; i++) {}
needs 10 bytecodes per iteration whereas

for (int i = 10; --i >= 0; ) {}
needs only 7 :wink:

Or do you care about the huge more disk place

Edit: Are you even sure about that; I think you have to push this on the stack for every (non-static) method you are using; therefore you have to push the Outerclass’ this on the stack anyway, which is what a button.this does.

Anyway, it’s cleaner and avoids future issues to just rename the method. Since the Java 7 compiler that I use doesn’t have the bug but the Java 8 compiler does have the bug… we’d hit this again the next time I refactored and forgot to put the extra garbage at the beginning.

I’ll just make a mental note that Java 8’s method resolution code is broken and try to avoid using the same names for inner/outer class methods in the future.

I might be wrong, but I think that Outerclass.this is the intended way of referencing methods from the outer class (and by intended I mean by James Gosling). My guess is that the ‘bug’ is on Java7 :smiley:

It’s the intended way yes, but only for methods with the same signature; so same name and same parameters, so normally click() should work (Don’t know what they changed, that it once worked and not now)

Me either. That has worked since Java 1.2 at least (from personal experience) and Java 8 is the first time I’ve seen it not work.

I’d claim it worked in Java 1.1 but my experience with 1.1 is not extensive enough to be sure that I did that with an inner class. In 1.2 with Swing, I 100% did. So common.