From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from MTA-09-3.privateemail.com (mta-09-3.privateemail.com [68.65.122.19]) by sourceware.org (Postfix) with ESMTPS id 636E5385842D for ; Tue, 7 Sep 2021 13:02:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 636E5385842D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=eatonphil.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=eatonphil.com Received: from mta-09.privateemail.com (localhost [127.0.0.1]) by mta-09.privateemail.com (Postfix) with ESMTP id 2AB221800222 for ; Tue, 7 Sep 2021 09:02:45 -0400 (EDT) Received: from mail-ua1-f46.google.com (unknown [10.20.151.220]) by mta-09.privateemail.com (Postfix) with ESMTPA id 047B6180021F for ; Tue, 7 Sep 2021 09:02:44 -0400 (EDT) Received: by mail-ua1-f46.google.com with SMTP id a14so5515444uao.0 for ; Tue, 07 Sep 2021 06:02:44 -0700 (PDT) X-Gm-Message-State: AOAM531s9Zbcep9Bgl9gaojiNBYUTkjvTGQoZR8339mQcwfCzCPYjUDF NJIWAxDqRaWYfnIylvKGR1rKYzeH8ykObJzcsaY= X-Google-Smtp-Source: ABdhPJwd2wX/zsw52zwBTGWWMSsSkcPxtgFOoXajwYaJgrHDisgA/vVPRQiNVOi5arA5hpCOcHKExTV93eD4Vqkeh40= X-Received: by 2002:ab0:6598:: with SMTP id v24mr2179974uam.142.1631019763910; Tue, 07 Sep 2021 06:02:43 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Phil Eaton Date: Tue, 7 Sep 2021 09:02:31 -0400 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: Receiver class does not define or inherit an implementation of the resolved method To: spellcard199 Cc: Per Bothner , kawa mailing list X-Virus-Scanned: ClamAV using ClamSMTP X-Spam-Status: No, score=-0.2 required=5.0 tests=BAYES_00, BODY_8BITS, HTML_MESSAGE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: kawa@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Kawa mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 07 Sep 2021 13:02:49 -0000 Good question! I don't know how to get the ABCL-emitted bytecode otherwise I would have just posted that. But I can describe to you the behavior that makes me say it emits two functions with the same name. Here is my ABCL code: https://github.com/eatonphil/jvm-lisp-examples/blob/main/abcl/main.lisp#L22= . In this code I define two methods of the same name. The "fake" method comes first. This is found when the jooby library does reflection! But it is not the one called by Jooby. The second method that returns an Object (the one that actually implements the interface) is the one that is called. Separately, I was messing around in Kawa trying to understand where this $X suffix is generated on duplicate methods. I did find fixParamNames in gnu/bytecode/Scope.java:110. It has a note saying that $X suffix was required because of _Android_/dex. I commented this method out and recompiled and ran my example but it still generated the $X suffix. So I guess that's not the place where the method name is generated for bytecode compilation. If anyone could point me at where that happens that would help= . Thanks! On Tue, Sep 7, 2021 at 6:59 AM spellcard199 wrote: > Hello. > > > For what it's worth this kind of redefinition of the same method > worked for me in ABCL lisp. So I know it's definitely possible to > express in Java. > > I know nothing about ABCL so I trust you on the fact ABCL handles > this differently from Kawa, but I don't think in Java you do it. > > If I try to write the following class in plain Java... > > public class Main { > public static void main(String[] args) { > Main main =3D new Main(); > System.out.println(main.apply("x")); > } > public java.lang.CharSequence apply(String s) { > return s.concat(s); > } > public java.lang.Object apply(String s) { > return s.concat(s).concat(s); > } > } > > ... it gives a compile time error: > > apply(String) is already defined in 'Main' > > And the same thing happens when the methods are static. > > I suppose in plain Java you can't have more than one method with both > the same: > - name > - input types > > I remember being confused by this the first time I saw it, but in > hindsight it makes sense: if there were 2 methods with the same name > and input types, how could Java know which one should be called when > applied to arguments? > > So my question is: does ABCL really let you have both methods at the > same time or just the lastly defined one? > > > =E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90 Original = Message =E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90=E2=80=90 > > On Tuesday, August 31st, 2021 at 1:18 AM, Phil Eaton > wrote: > > > I spoke too soon. The issue is that I truly do need both of these metho= ds > > > > to be called `apply` not `apply` and `apply$1`. > > > > For what it's worth this kind of redefinition of the same method worked > for > > > > me in ABCL lisp. So I know it's definitely possible to express in Java. > > > > On Mon, Aug 30, 2021 at 7:09 PM Phil Eaton phil@eatonphil.com wrote: > > > > > Aha! It gave my second apply method a different suffix. By reordering > > > > > > these two methods the whole thing somehow works. > > > > > > $ javap main\$0.class > > > > > > Compiled from "main.scm" > > > > > > public class main$0 implements io.jooby.Route$Handler { > > > > > > main$frame this$0; > > > > > > public java.lang.CharSequence apply(io.jooby.Context); > > > > > > public java.lang.Object apply$1(io.jooby.Context); > > > > > > public main$0(main$frame); > > > > > > } > > > > > > It's weird but I'll take it. > > > > > > On Mon, Aug 30, 2021 at 12:40 PM Per Bothner per@bothner.com wrote: > > > > > > > On 8/29/21 12:03 PM, Phil Eaton wrote:> Still new to Kawa. I'm > trying to > > > > > > > > implement an interface ( > > > > > > > > > io.jooby.Route$Handler > > > > > > > > > > < > > > > > > > > > > > https://github.com/jooby-project/jooby/blob/2.x/jooby/src/main/java/io/jo= oby/Route.java#L247 > > > > > > > > > > ). > > > > > > > > > > It only has a single non-default method, apply. > > > > > > > > > > Here's what I've got > > > > > > > > > > (define (route app method path handler) > > > > > > > > > > (let ((handler (object (io.jooby.Route$Handler) > > > > > > > > > > #| This method exists just to stop Jooby from > > > > > > > > > > trying to introspect Java code that doesn't exist because this > isn't > > > > > > > > > > written in Java. |# > > > > > > > > > > ((apply (ctx ::io.jooby.Context)) ::string > > > > > > > > > > #!null) > > > > > > > > > > ((apply (ctx ::io.jooby.Context)) > > > > > > > > > > ::java.lang.Object > > > > > > > > > > (handler ctx))))) > > > > > > > > > > (app:route method path handler))) > > > > > > > > > > But when this gets exercised, I get: > > > > > > > > > > [worker-1-3] ERROR io.jooby.Jooby - GET /hello-world 500 Server > Error > > > > > > > > > > java.lang.AbstractMethodError: Receiver class main$0 does not > define or > > > > > > > > > > inherit an implementation of the resolved method 'abstract > > > > > > > > > > java.lang.Object > > > > > > > > > > apply(io.jooby.Context)' of interface io.jooby.Route$Handler. > > > > > > > > I don't see anything obviously wrong. One thing to try is instead o= f > an > > > > > > > > anonymous class (with object) use a named class (with > > > > > > > > define-simple-class). > > > > > > > > The anonymous class is more convenient of course there is some extr= a > > > > > > > > "magic" > > > > > > > > (such as invisible fields) that might complicate things. > > > > > > > > > Also on a tangent, I was excited about the lambda shorthand for > single > > > > > > > > > > method objects. Like I said this interface only has a single > non-default > > > > > > > > > > method: apply. But I tried just calling `(app:route method > handler)` > > > > > > > > > > without wrapping it in the io.jooby.Route$Handler object but it > still > > > > > > > > > > failed. I guess it couldn't figure out this one method. > > > > > > > > Kawa has to be able to figure out at compile time that a specific > > > > > > > > class/interface > > > > > > > > is required before it can convert the lambda to an object. (As far > as I > > > > > > > > can > > > > > > > > remember, doing this conversion at run-time isn't implemented, and > would > > > > > > > > be > > > > > > > > fairly complicated.) So you may need to add some more > type-specifiers. > > > > > > > > I suggest using javap to look at the generated classes, to see what > is > > > > > > > > going on. > > > > > -------------------------------------------------------------------------= -------- > > > > > > > > --Per Bothner > > > > > > > > > > > > per@bothner.com http://per.bothner.com/ >