Help, writing kawa equivalent of java program

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Help, writing kawa equivalent of java program

Vasantha Ganesh
Hello all,

Take this Java program:

public class Notworking{
    public interface kittens {
    public int a();
    }

    public static void main(String[] args) {
    System.out.println(kittens.class);
    }
}

and this Kawa program:

(define-simple-class kittens ()
  (make-interface #t)
  (a::long))

(display kittens:class)

I think both are equivalent, but kawa seems to think that I'm doing a
type cast and throws this error message:

Argument #1 'class kittens' to 'gnu.bytecode.Type.getReflectClass()'
has wrong type (class) (java.lang.Class cannot be cast to
gnu.bytecode.Type)
    at not_working.run(not_working.scm:5)
    at gnu.expr.ModuleExp.evalModule2(ModuleExp.java:317)
    at gnu.expr.CompiledModule.evalModule(CompiledModule.java:42)
    at gnu.expr.CompiledModule.evalModule(CompiledModule.java:61)
    at kawa.Shell.runFile(Shell.java:538)
    at kawa.Shell.runFileOrClass(Shell.java:447)
    at kawa.repl.main(repl.java:881)
Caused by: java.lang.ClassCastException: java.lang.Class cannot be
cast to gnu.bytecode.Type
    ... 7 more

but if I do this in repl, I think its working:

#|kawa:1|# (define-simple-class kittens ()
#|(---:2|#   (make-interface #t)
#|(---:3|#   (a::long))
#|kawa:4|# (display kittens:class)
class kittens

Thank you,
Vasantha Ganesh K.
Reply | Threaded
Open this post in threaded view
|

Re: Help, writing kawa equivalent of java program

Per Bothner
On 04/01/2017 08:54 AM, Vasantha Ganesh wrote:

>
> and this Kawa program:
>
> (define-simple-class kittens ()
>   (make-interface #t)
>   (a::long))
>
> (display kittens:class)
>
> I think both are equivalent, but kawa seems to think that I'm doing a
> type cast and throws this error message:
>
> Argument #1 'class kittens' to 'gnu.bytecode.Type.getReflectClass()'
> has wrong type (class) (java.lang.Class cannot be cast to
> gnu.bytecode.Type)
>     at not_working.run(not_working.scm:5)
>     at gnu.expr.ModuleExp.evalModule2(ModuleExp.java:317)
>     at gnu.expr.CompiledModule.evalModule(CompiledModule.java:42)
>     at gnu.expr.CompiledModule.evalModule(CompiledModule.java:61)
>     at kawa.Shell.runFile(Shell.java:538)
>     at kawa.Shell.runFileOrClass(Shell.java:447)
>     at kawa.repl.main(repl.java:881)
> Caused by: java.lang.ClassCastException: java.lang.Class cannot be
> cast to gnu.bytecode.Type
>     ... 7 more

That looks like a bug.  I'll take a look.

It does work if you use the -f flag:

kawa -f /tmp/not_working.scm
class kittens
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: Help, writing kawa equivalent of java program

Vasantha Ganesh
Hello Mr. Bothner,
  Thank you, that did work. Kawa complains that the interface that I
created in kawa is not an interface. Could you please help with
debugging in convert the following java code to equivalent scheme
code?

Java code:

import com.sun.jna.Library;
import com.sun.jna.Native;

public class jnaGetpid {
    public interface libc extends Library{
    public long getpid();
    }

    public static void main(String[] args) {
    libc ntv = (libc) Native.loadLibrary("c", libc.class);
    System.out.println(ntv.getpid());
    }
}


Kawa equivalent:

(define-alias library com.sun.jna.Library)
(define-alias native com.sun.jna.Native)

(define-simple-class libc (library)
  (make-interface #t)
  (getpid::long))

(define inst::libc (native:loadLibrary "c" libc:class))
(display (inst:getpid))

While running this code I get the following error (Its complaing that
the scheme interface is not an interface):

[homonculus@alchemist kawa-scheme]$ kawa -J-cp
-J/usr/share/java/jna.jar:.:/usr/share/java/kawa-2.0.jar -f
jnagetpid.scm
java.lang.IllegalArgumentException: libc is not an interface
    at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:590)
    at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:557)
    at java.lang.reflect.WeakCache$Factory.get(WeakCache.java:230)
    at java.lang.reflect.WeakCache.get(WeakCache.java:127)
    at java.lang.reflect.Proxy.getProxyClass0(Proxy.java:419)
    at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:719)
    at com.sun.jna.Native.loadLibrary(Native.java:506)
    at com.sun.jna.Native.loadLibrary(Native.java:481)
    at atInteractiveLevel$4.run(jnagetpid.scm:8)
    at gnu.expr.ModuleExp.evalModule2(ModuleExp.java:317)
    at gnu.expr.ModuleExp.evalModule(ModuleExp.java:219)
    at kawa.Shell.run(Shell.java:291)
    at kawa.Shell.runFile(Shell.java:524)
    at kawa.Shell.runFileOrClass(Shell.java:447)
    at kawa.repl.processArgs(repl.java:260)
    at kawa.repl.main(repl.java:871)
java.lang.NullPointerException
    at atInteractiveLevel$5.run(jnagetpid.scm:9)
    at gnu.expr.ModuleExp.evalModule2(ModuleExp.java:317)
    at gnu.expr.ModuleExp.evalModule(ModuleExp.java:219)
    at kawa.Shell.run(Shell.java:291)
    at kawa.Shell.runFile(Shell.java:524)
    at kawa.Shell.runFileOrClass(Shell.java:447)
    at kawa.repl.processArgs(repl.java:260)
    at kawa.repl.main(repl.java:871)

Thank you,
Vasantha Ganesh K.
Reply | Threaded
Open this post in threaded view
|

Re: Help, writing kawa equivalent of java program

Per Bothner
On 04/01/2017 12:44 PM, Vasantha Ganesh wrote:
>   Thank you, that did work. Kawa complains that the interface that I
> created in kawa is not an interface.

(define-simple-class libc (library)
   (make-interface #t)
   (getpid::long))

- defines a field named make-interface.
You probably want:

(define-simple-class libc (library)
   interface: #t
   (getpid::long))
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: Help, writing kawa equivalent of java program

Vasantha Ganesh
Hello Mr. Bothner,
  I still get this error:

[homonculus@alchemist kawa-scheme]$ kawa -J-cp
-J/usr/share/java/jna.jar:.:/usr/share/java/kawa-2.0.jar -f
jnagetpid.scm
Exception in thread "main" java.lang.ClassFormatError: Illegal field
modifiers in class libc: 0x1
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
    at gnu.bytecode.ArrayClassLoader.loadClass(ArrayClassLoader.java:125)
    at gnu.expr.ModuleExp.evalToClass(ModuleExp.java:135)
    at gnu.expr.ModuleExp.evalModule1(ModuleExp.java:259)
    at gnu.expr.ModuleExp.evalModule(ModuleExp.java:214)
    at kawa.Shell.run(Shell.java:291)
    at kawa.Shell.runFile(Shell.java:524)
    at kawa.Shell.runFileOrClass(Shell.java:447)
    at kawa.repl.processArgs(repl.java:260)
    at kawa.repl.main(repl.java:871)

Thank you,
Vasantha Ganesh K.

On Sun, Apr 2, 2017 at 1:22 AM, Per Bothner <[hidden email]> wrote:

> On 04/01/2017 12:44 PM, Vasantha Ganesh wrote:
>>
>>   Thank you, that did work. Kawa complains that the interface that I
>> created in kawa is not an interface.
>
>
> (define-simple-class libc (library)
>   (make-interface #t)
>   (getpid::long))
>
> - defines a field named make-interface.
> You probably want:
>
> (define-simple-class libc (library)
>   interface: #t
>   (getpid::long))
>
> --
>         --Per Bothner
> [hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: Help, writing kawa equivalent of java program

Vasantha Ganesh
Sorry for excluding the code, here it goes:

(define-alias library com.sun.jna.Library)
(define-alias native com.sun.jna.Native)

(define-simple-class libc (library)
  interface: #t
  (getpid::long))

(define inst::libc (native:loadLibrary "c" libc:class))
(display (inst:getpid))

On Sun, Apr 2, 2017 at 1:28 AM, Vasantha Ganesh
<[hidden email]> wrote:

> Hello Mr. Bothner,
>   I still get this error:
>
> [homonculus@alchemist kawa-scheme]$ kawa -J-cp
> -J/usr/share/java/jna.jar:.:/usr/share/java/kawa-2.0.jar -f
> jnagetpid.scm
> Exception in thread "main" java.lang.ClassFormatError: Illegal field
> modifiers in class libc: 0x1
>     at java.lang.ClassLoader.defineClass1(Native Method)
>     at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
>     at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
>     at gnu.bytecode.ArrayClassLoader.loadClass(ArrayClassLoader.java:125)
>     at gnu.expr.ModuleExp.evalToClass(ModuleExp.java:135)
>     at gnu.expr.ModuleExp.evalModule1(ModuleExp.java:259)
>     at gnu.expr.ModuleExp.evalModule(ModuleExp.java:214)
>     at kawa.Shell.run(Shell.java:291)
>     at kawa.Shell.runFile(Shell.java:524)
>     at kawa.Shell.runFileOrClass(Shell.java:447)
>     at kawa.repl.processArgs(repl.java:260)
>     at kawa.repl.main(repl.java:871)
>
> Thank you,
> Vasantha Ganesh K.
>
> On Sun, Apr 2, 2017 at 1:22 AM, Per Bothner <[hidden email]> wrote:
>> On 04/01/2017 12:44 PM, Vasantha Ganesh wrote:
>>>
>>>   Thank you, that did work. Kawa complains that the interface that I
>>> created in kawa is not an interface.
>>
>>
>> (define-simple-class libc (library)
>>   (make-interface #t)
>>   (getpid::long))
>>
>> - defines a field named make-interface.
>> You probably want:
>>
>> (define-simple-class libc (library)
>>   interface: #t
>>   (getpid::long))
>>
>> --
>>         --Per Bothner
>> [hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: Help, writing kawa equivalent of java program

Sudarshan S Chawathe
> (define-alias library com.sun.jna.Library)
> (define-alias native com.sun.jna.Native)
>
> (define-simple-class libc (library)
>   interface: #t
>   (getpid::long))
>
> (define inst::libc (native:loadLibrary "c" libc:class))
> (display (inst:getpid))

I think you need to define the interface to have a getpid method with
the proper signature.  Here is a small example, somewhat similar to your
code, that I tried a while back and that works:

(define-simple-class clib (com.sun.jna.Library)
  interface: #t
  ((puts (s ::String)) ::void #!abstract))

((as clib
     (com.sun.jna.Native:loadLibrary "c" clib)):puts "Hello, World!")

Regards,

-chaw
Reply | Threaded
Open this post in threaded view
|

Re: Help, writing kawa equivalent of java program

Per Bothner
On 04/01/2017 01:20 PM, Sudarshan S Chawathe wrote:

>> (define-alias library com.sun.jna.Library)
>> (define-alias native com.sun.jna.Native)
>>
>> (define-simple-class libc (library)
>>   interface: #t
>>   (getpid::long))
>>
>> (define inst::libc (native:loadLibrary "c" libc:class))
>> (display (inst:getpid))
>
> I think you need to define the interface to have a getpid method with
> the proper signature.  Here is a small example, somewhat similar to your
> code, that I tried a while back and that works:
>
> (define-simple-class clib (com.sun.jna.Library)
>   interface: #t
>   ((puts (s ::String)) ::void #!abstract))

Kawa should be able to infer the signature, so I believe you can write:

     ((puts (s)) #!abstract))

The problem is that:
    (getpid::long)
defines a field, not a method (and non-statuc fields aren't allowed in interfaces).

Kawa should probably catch this error.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: Help, writing kawa equivalent of java program

Vasantha Ganesh
Hello,
  It worked after making it a method and then making the method abstract.

Code for future users?

(define-alias library com.sun.jna.Library)
(define-alias native com.sun.jna.Native)

(define-simple-class libc (library)
  interface: #t
  ((getpid)::long #!abstract))

(define inst::libc (native:loadLibrary "c" libc:class))
(display (inst:getpid))


Thanks a lot!
Vasantha Ganesh K.

On Sun, Apr 2, 2017 at 1:55 AM, Per Bothner <[hidden email]> wrote:

> On 04/01/2017 01:20 PM, Sudarshan S Chawathe wrote:
>>>
>>> (define-alias library com.sun.jna.Library)
>>> (define-alias native com.sun.jna.Native)
>>>
>>> (define-simple-class libc (library)
>>>   interface: #t
>>>   (getpid::long))
>>>
>>> (define inst::libc (native:loadLibrary "c" libc:class))
>>> (display (inst:getpid))
>>
>>
>> I think you need to define the interface to have a getpid method with
>> the proper signature.  Here is a small example, somewhat similar to your
>> code, that I tried a while back and that works:
>>
>> (define-simple-class clib (com.sun.jna.Library)
>>   interface: #t
>>   ((puts (s ::String)) ::void #!abstract))
>
>
> Kawa should be able to infer the signature, so I believe you can write:
>
>     ((puts (s)) #!abstract))
>
> The problem is that:
>    (getpid::long)
> defines a field, not a method (and non-statuc fields aren't allowed in
> interfaces).
>
> Kawa should probably catch this error.
>
> --
>         --Per Bothner
> [hidden email]   http://per.bothner.com/
Reply | Threaded
Open this post in threaded view
|

Re: Help, writing kawa equivalent of java program

Per Bothner
In reply to this post by Per Bothner
On 04/01/2017 09:28 AM, Per Bothner wrote:

> On 04/01/2017 08:54 AM, Vasantha Ganesh wrote:
>>
>> and this Kawa program:
>>
>> (define-simple-class kittens ()
>>   (make-interface #t)
>>   (a::long))
>>
>> (display kittens:class)
>>
>> I think both are equivalent, but kawa seems to think that I'm doing a
>> type cast and throws this error message:
>>
>> Argument #1 'class kittens' to 'gnu.bytecode.Type.getReflectClass()'
>> has wrong type (class) (java.lang.Class cannot be cast to
>> gnu.bytecode.Type)
>>     at not_working.run(not_working.scm:5)
>>     at gnu.expr.ModuleExp.evalModule2(ModuleExp.java:317)
>>     at gnu.expr.CompiledModule.evalModule(CompiledModule.java:42)
>>     at gnu.expr.CompiledModule.evalModule(CompiledModule.java:61)
>>     at kawa.Shell.runFile(Shell.java:538)
>>     at kawa.Shell.runFileOrClass(Shell.java:447)
>>     at kawa.repl.main(repl.java:881)
>> Caused by: java.lang.ClassCastException: java.lang.Class cannot be
>> cast to gnu.bytecode.Type
>>     ... 7 more
>
> That looks like a bug.  I'll take a look.

I checked in a fix (and a simplified testcase) for this.
--
        --Per Bothner
[hidden email]   http://per.bothner.com/