From: Luke H. <ruk...@gm...> - 2005-10-25 08:51:28
|
Okay, I can call java classes from abcl just fine, and I can create code which implements java interfaces using jinterface-implementation / %jnew-proxy. So two things: 1. How do I subclass java classes with lisp code? I presume it'd be similar to %jnew-proxy, but I can't find a function that does it. 2. How do I make these subclasses/interfaces available to be called from java source code (i.e. callbacks)? I ask because it would take me perhaps hours of digging through the code and guessing to work this out and hopefully 10 minutes for someone to answer. Just a couple of small stub example swould probably suffice. Thanks very much in advance. -Luke |
From: Andras S. <as...@ma...> - 2005-10-25 10:49:15
|
On Tue, 25 Oct 2005, Luke Hope wrote: > Okay, > > I can call java classes from abcl just fine, and I can create code > which implements java interfaces using jinterface-implementation / > %jnew-proxy. > > So two things: > 1. How do I subclass java classes with lisp code? I presume it'd be > similar to %jnew-proxy, but I can't find a function that does it. > > 2. How do I make these subclasses/interfaces available to be called > from java source code (i.e. callbacks)? > > I ask because it would take me perhaps hours of digging through the > code and guessing to work this out and hopefully 10 minutes for > someone to answer. > Just a couple of small stub example swould probably suffice. Here's the (almost) simplest example. It's "almost" because a class with a single static method would be simpler, but there seems to be a bug in jnew-runtime-class that prevents creating static methods. You have to put asm.jar (http://asm.objectweb.org (I use 1.5.1 - don't know if 2.xx works)) in your classpath. (in-package :cl-user) (defpackage :foo (:use :common-lisp :java)) (in-package :foo) (defun jrc (class-name super-name interfaces constructors methods fields &optional filename) "A friendlier version of jnew-runtime-class." (if (java:jruntime-class-exists-p class-name) (progn (warn "Java class ~a already exists. Redefining methods." class-name) (loop for (argument-types function super-invocation-args) in constructors do (java:jredefine-method class-name nil argument-types function)) (loop for (method-name return-type argument-types function &rest modifiers) in methods do (java:jredefine-method class-name method-name argument-types function))) (java:jnew-runtime-class class-name super-name interfaces constructors methods fields filename))) (jrc "FOO.Bar" "java.lang.Object" nil ;;interfaces nil ;;constructors '(("a_method" ;;name "int" ;;return type ("int" "int") ;;argument types (lambda (x y &optional this) (+ x y)) ;;the method itself "public")) ;;methods nil ;;fields "/tmp/Bar.class" ;; this is optional ) (let ((bar (jnew (jconstructor "FOO.Bar")))) (jcall (jmethod "FOO.Bar" "a_method" "int" "int") bar 1 2)) To see how to define constructors and fields, see the documentation of jnew-runtime-class in runtime-class.lisp, or ask and I'll send a more complete example. > > Thanks very much in advance. You're welcome. Andras |
From: Luke H. <ruk...@gm...> - 2005-10-27 00:43:35
|
Hi all, I recently posted these two questions: > > 1. How do I subclass java classes with lisp code? I presume it'd be > > similar to %jnew-proxy, but I can't find a function that does it. > > > > 2. How do I make these subclasses/interfaces available to be called > > from java source code (i.e. callbacks)? > > Andras forwarded me some sample code on the usage of "jnew-runtime-class", which efficiently answered the first question.=20 However, the second question seems to me to be quite tricky, but I think it's worth solving, because then I could redevelop "in place" classes which were initially written in Java and replace them piecewise with Lisp code. I've thought of a possible solution for the second question. The solution comes in two parts: first keeping javac happy so you can compile the java source, and second keeping java itself happy. Satisfying javac should be easy, just create java stub code (probably autogenerated). Satisfying java seems hard. I briefly (and naively) thought that the class output of jnew-runtime-class would work, but of course it doesn't (presumably because the Lisp environment itself doesn't get booted, and it's doubtful that the class file saves the lexical environment in which the runtime class is defined anyway). So my next thought is implementing, say, an ABCLClassLoader, which initialises Lisp, and then instead of looking for the class foo.Bar by resolving foo/Bar.class, looks for foo/Bar.abcl or foo/Bar.lisp which contains code which creates the runtime class foo.Bar. I had a quick look at the abcl source and noticed there's a "JavaClassLoader.java" I couldn't work out what it did, and a grep told me that it wasn't called by anything else. 1. Am I missing a really simple solution? 2. Any Lisp complications I may have overlooked? 3. What's the minimum amount of abcl code I need to execute to boot lisp and Load other files? I've looked at Interpreter.java, but I don't quite know whether I need to have a toplevel, etc. 4. Any ClassLoader complications I may have overlooked? Sorry if this is a bit newbie-ish, but I haven't dug this deep in Java before, and I feel it's probably better to ask questions first and not waste my time re-inventing the wheel. -Luke P.S. for jnew-runtime-class, am I correct in assuming the method implementations are full closures? |
From: Peter G. <pe...@ar...> - 2005-10-27 01:29:51
|
On Thu, 27 Oct 2005 at 10:43:20 +1000, Luke Hope wrote: > 3. What's the minimum amount of abcl code I need to execute to boot > lisp and Load other files? I've looked at Interpreter.java, but I > don't quite know whether I need to have a toplevel, etc. Look at hello.java in the examples directory. -Peter |
From: Peter G. <pe...@ar...> - 2005-10-27 13:17:02
|
On Thu, 27 Oct 2005 at 10:43:20 +1000, Luke Hope wrote: > Hi all, > > I recently posted these two questions: > > > > 1. How do I subclass java classes with lisp code? I presume it'd be > > > similar to %jnew-proxy, but I can't find a function that does it. > > > > > > 2. How do I make these subclasses/interfaces available to be called > > > from java source code (i.e. callbacks)? > > > > Andras forwarded me some sample code on the usage of > "jnew-runtime-class", which efficiently answered the first question. > However, the second question seems to me to be quite tricky, but I > think it's worth solving, because then I could redevelop "in place" > classes which were initially written in Java and replace them > piecewise with Lisp code. > > I've thought of a possible solution for the second question. The > solution comes in two parts: first keeping javac happy so you can > compile the java source, and second keeping java itself happy. > > Satisfying javac should be easy, just create java stub code (probably > autogenerated). > > Satisfying java seems hard. I briefly (and naively) thought that the > class output of jnew-runtime-class would work, but of course it > doesn't (presumably because the Lisp environment itself doesn't get > booted, and it's doubtful that the class file saves the lexical > environment in which the runtime class is defined anyway). > > So my next thought is implementing, say, an ABCLClassLoader, which > initialises Lisp, and then instead of looking for the class foo.Bar by > resolving foo/Bar.class, looks for foo/Bar.abcl or foo/Bar.lisp which > contains code which creates the runtime class foo.Bar. > > I had a quick look at the abcl source and noticed there's a > "JavaClassLoader.java" I couldn't work out what it did, and a grep > told me that it wasn't called by anything else. > > 1. Am I missing a really simple solution? > 2. Any Lisp complications I may have overlooked? > 3. What's the minimum amount of abcl code I need to execute to boot > lisp and Load other files? I've looked at Interpreter.java, but I > don't quite know whether I need to have a toplevel, etc. > 4. Any ClassLoader complications I may have overlooked? > > Sorry if this is a bit newbie-ish, but I haven't dug this deep in Java > before, and I feel it's probably better to ask questions first and not > waste my time re-inventing the wheel. > > -Luke > > P.S. for jnew-runtime-class, am I correct in assuming the method > implementations are full closures? Hi Luke, I'm not going to attempt a substantive answer to your questions, mostly because I know almost nothing about JNEW-RUNTIME-CLASS and friends. Andras may be able to help you with more specific information. But I do want to make clear that you're working in an area (ABCL's Lisp/Java interface) that hasn't been nailed down yet. A lot of things do work, and that probably gives the impression that we're a bit further along than we really are. You can certainly ask how those things work today, and in principle that question can be answered, but there is absolutely no guarantee that those things will work the same way tomorrow. I'm reasonably sure about the low-level stuff like JCALL, but proxies and callbacks are more involved and more subtle, and I'm only just starting to look at those issues. I've been guilty of neglecting this area almost completely in favor of other goals, like ANSI compliance and performance, and I have to catch up. Andras was breaking new ground when he wrote the JNEW-RUNTIME-CLASS stuff, and it was amazing that he was able to accomplish so much at a time when ABCL was still so immature (most of his work in that area was done in early 2004). But ABCL has come a long way since then. We need to take that progress into consideration. For example, when Andras wrote JNEW-RUNTIME-CLASS, ABCL's compiler barely existed and could only handle toy examples. Nowadays, I'm pretty sure ABCL's compiler could do what ASM is doing for JNEW-RUNTIME-CLASS (although I'd need to do a bit of work to make that actually happen). We're moving in the direction of a stable, documented, and tested Lisp/Java interface. We're not there yet. -Peter |
From: Andras S. <as...@ma...> - 2005-10-29 00:49:26
|
On Thu, 27 Oct 2005, Luke Hope wrote: > I had a quick look at the abcl source and noticed there's a > "JavaClassLoader.java" I couldn't work out what it did, and a grep > told me that it wasn't called by anything else. Strange, because RuntimeClass.java, Lisp.java and Java.java refer to it. (I think the archives of this list contain some discussion about its role - but maybe only in the form of questions...) > P.S. for jnew-runtime-class, am I correct in assuming the method > implementations are full closures? I think so, but your best bet is to do some experiments. Andras |
From: Luke H. <ruk...@gm...> - 2005-10-30 21:40:18
|
Since there's been lots of discussion about interfacing Java and Lisp lately, I thought I'd put up my work for people to inspect/use. My motivation for using Lisp and Java together is that I want to use Lisp to access java libraries that I have to use, in particular Norsys's Netica Bayesian Network Library and the weka machine learning library (both easily googled.) I also want to rewrite some of my legacy java apps in lisp so they can be more easily extended, and because I don't necessarily want to rewrite the java apps top-down in Lisp, being able to replace java-defined java classes with lisp-defined java classes in place is important. There are two packages in http://www.csse.monash.edu.au/~lhope/lisp/ 1. javaclass.tgz , which contains a gpl'd clos java class wrapper generator. I wrote this before I knew about jfli (hey, reinventing the wheel is at least educational :-) ). Examples of its usage are in README.txt in the package. It generates the wrappers using macros, and hence should generate the definitions at compile time. It's quite new software so if anyone wants to use it and provide feedback on how to improve it, that'd be useful. 2. callback.tgz . This contains a java system class loader to replace the standard java one like this: java -Djava.system.class.loader=3Dhope.luke.callback.LispSystemClassLoader hope.luke.foo.CallBar This changes the behaviour of the classloader to look in the classpath for, eg, hope.luke.foo.Bar.{abcl/lisp} and load this to get the class definition of Bar instead of Bar.class , thus implementing the "in place" behaviour I wanted. A stub Bar.java is necessary for the java compiler. It's probably not that hard to add code to autogenerate Bar.java, but since this package is more for replacing existing classes, the original java file probably already exists. I'd love for people to use/inspect this stuff and tell me any improvements that should be included. -Luke |
From: Andras S. <as...@ma...> - 2005-10-31 17:21:38
|
On Mon, 31 Oct 2005, Luke Hope wrote: > Since there's been lots of discussion about interfacing Java and Lisp > lately, I thought I'd put up my work for people to inspect/use. My > motivation for using Lisp and Java together is that I want to use Lisp > to access java libraries that I have to use, in particular Norsys's > Netica Bayesian Network Library and the weka machine learning library > (both easily googled.) I also want to rewrite some of my legacy java > apps in lisp so they can be more easily extended, and because I don't > necessarily want to rewrite the java apps top-down in Lisp, being able > to replace java-defined java classes with lisp-defined java classes in > place is important. > > There are two packages in http://www.csse.monash.edu.au/~lhope/lisp/ > 1. javaclass.tgz , which contains a gpl'd clos java class wrapper > generator. I wrote this before I knew about jfli (hey, reinventing > the wheel is at least educational :-) ). Examples of its usage are in > README.txt in the package. It generates the wrappers using macros, > and hence should generate the definitions at compile time. It's quite > new software so if anyone wants to use it and provide feedback on how > to improve it, that'd be useful. Hi Luke, I played with javaclass a bit this afternoon, and it looks nice. But I have to do something more substantial with it before I can really decide if I like it better than or as much as jfli-abcl. (BTW, do you plan to put in support for interfaces and runtime generated classes? I could then try to port the jfli-abcl examples to javaclass.) One thing though: if a class has a static field and a method with the same name (modulo case), DEF-JAVA-CLASS defines an ordinary and a generic function with the same name. Andras |