[armedbear-devel] Using ABCL with large Java app

Blake McBride blake at arahant.com
Sat Feb 16 12:39:30 UTC 2013


On Fri, Feb 15, 2013 at 10:24 PM, Rudolf Schlatte <rudi at constantly.at>wrote:

> Hi,
>
> I'm not sure I understand the basic problems yet.  Why construct Lisp-side
> mirror classes instead of dispatching directly on Java objects?
> (defmethod foo ((x (jclass "org.comp.Whizzle")))
>   (let ((datum (jcall "getWhizzleComponent" x)))
>     ...))
>

I have a large set of classes that I need to use with a lot of name
duplicates so there are several reasons I need to mirror the classes.

Given the large number of classes & methods the lisp wrappers (you show
above) or clos mirrors have to be generated in an automated fashion.  My
main problem has to do with method name duplicates across classes with
different arguments (which I solved), method name duplicates within the
same class (which I haven't solved), and the hierarchical nature of Java
classes (having methods defined in super classes) (a problem I created by
use of my mirrors but solved).

The solution you show above (naming the lisp method "foo" when the Java
method name is "getWhizzleComponent" doesn't work.  I could never keep
track of the names in the different environments.

Here are the circumstances:

A.  The are a large number of Java classes and methods I need to use
from within lisp containing many class hierarchies, many duplicate method
names with varying argument lists both across classes and within classes,
and there is need to use methods defined in superclasses.

B.  The interface must be automatically built (presumably at runtime via
Java reflection).  I cannot build and maintain a manual one with this many
classes and methods (and possibly having multiple programmers adding more
Java classes and methods daily).

C.  The class and method names in lisp must be the same as their peers in
Java.  There is no way to remember a translation.

D.  The lisp code must be as clean as the Java code - a simple call must be
a simple call.  I can't have additional code to get the Java method in the
application code making the equivalent lisp code far more convoluted than
the Java code (as you propose below).

In order to do anything meaningful in lisp I must have access to many Java
classes and methods.  My ultimate aim would be to have the core libraries
(i.e. hibernate, etc.) in Java and all of my application specific code in
lisp.  I have already solved all of the above problems except the ability
to handle the same method names within the same class hierarchy.  I can
even create web services in lisp.

Up to this point I have solved all of my problems except the the problem of
duplicate method names in a single Java class hierarchy.  (There is also
the other problem I spoke of but that is of secondary concern.)  I have a
lot of (for me) complex code to solve my problem up to this point.  I fear
that solving my last problem would make my existing automation
geometrically more complex.

I hope this helps to understand the problem.  I appreciate any pointers you
can offer.

Thanks.

Blake



>
> Also, why reconstruct Java methods Lisp-side? Currently, I tend to use
> abcl as a "top-level scripting layer", without trying to duplicate stuff
> (including methods) that's already implemented Java-side (the following
> fragment uses jss for method call notation, although currently I prefer
> plain jcall again):
>
> (defun piechart ()
>   (let* ((data (jnew "org.jfree.data.general.DefaultPieDataset"))
>          (chart (jstatic "createPieChart" "org.jfree.chart.ChartFactory"
>                          ;; check ChartFactory for chart types!
>                          "Sample Pie Chart" data +true+ +false+ +false+))
>          (frame (jnew "org.jfree.chart.ChartFrame" "Test" chart)))
>     (#"setValue" data "Category 1" 401)
>     (#"setValue" data "Category 2" 227)
>     (#"setValue" data "Category 3" 211)
>     (#"pack" frame)
>     (#"setVisible" frame +true+)))
>
> But I suspect that I'm answering the wrong questions here.
>
> Rudi
>
> On Feb 16, 2013, at 11:59, Blake McBride <blake at arahant.com> wrote:
>
> Thanks for the feedback.   I'm not sure about that approach because most
> methods don't share the same name.  I'd have to know in advanced which do,
> which don't, an what the special keys are.  This doesn't amount to anything
> more than name mangling generics.  I am still stuck having to know too many
> special cases.  Having, essentially, custom dispatching code in the
> generics based on argument count and types seems to be the only clean
> solution I can think of.  The problem  of course, is that it is a bit
> difficult to implement - auto generation of this based on Java reflection.
>  I'd love to find an easier solution to implement that doesn't make it hard
> to use.
>
> Thanks for the idea!!
>
> Blake
>
>
> On Fri, Feb 15, 2013 at 9:40 PM, Vsevolod Dyomkin <vseloved at gmail.com>wrote:
>
>> Hello Blake,
>>
>> What would you say of the following scheme for variable-argument methods:
>>
>> (defgeneric method (object spec &rest &key))
>>
>> (defmethod method ((object clos-mirror-object) (spec (eql :variantion1))
>> &rest &key arg1 arg2 &allow-other-keys)
>>    ...)
>>
>> I.e. introducing an additional argument that you can use for dispatching
>> of the same-named methods belonging to one class?
>>
>> Best
>>
>> Vsevolod Dyomkin
>> +38-096-111-41-56
>> skype, twitter: vseloved
>>
>>
>> On Sat, Feb 16, 2013 at 1:54 AM, Blake McBride <blake at arahant.com> wrote:
>>
>>> Greetings,
>>>
>>> I have a large Java app with more than 15K Java classes.  I linked it up
>>> with ABCL and successfully used it in several places.  However, I had a
>>> couple of problems that caused me to use ABCL significantly less than I had
>>> hoped.  I thought I would share my problems and perhaps there might be a
>>> helpful suggestion.
>>>
>>> Although I don't interface with most of the 15K Java classes, there are
>>> still a lot of classes to interface ABCL with.  I wrote some lisp code
>>> that, through Java reflection, creates CLOS classes that mirror the Java
>>> classes I wish to interface with.  In CLOS it encapsulates the Java
>>> instance, mirrors the class hierarchy, and creates generics to match the
>>> Java methods.  I found a way to create variable argument generics that feed
>>> fixed argument methods in order to handle the fact that similarly named
>>> methods can take different arguments across different Java classes.
>>>
>>> I ran into two problems that have caused me to use ABCL much less than
>>> I'd like to.  The first seems like won't be too hard to solve, but the
>>> second is something I still need to find a solution to.  Remember, I cannot
>>> build this interface manually.  There are too many classes and methods.
>>>
>>> The first problem is that I have Java classes and instances mirrored as
>>> CLOS classes and instances.  At times it was more convenient (from lisp) to
>>> deal with Java objects directly instead of CLOS mirrors.  While it was
>>> more convenient, it ended up being too confusing.  With all these classes,
>>> objects, and methods, it was too easy to forget what the heck I was dealing
>>> with at any point in the code.  I think the only answer to this is to only
>>> deal with lisp objects when in lisp.  This would avoid the confusion at the
>>> cost of wrapping and unwrapping certain Java objects at times - not too
>>> bad.  I would need to have a way to pack Jeve arguments from Jave when
>>> calling Lisp.  Doing it in Lisp is a problem because I am back to the
>>> confusion of knowing when I am dealing with a Java object and when a lisp
>>> object.
>>>
>>> The second problem has to do with the fact that a single Java class can
>>> use the same method name multiple times with different arguments.
>>>  Remember, I am using variable argument generics to handle similar Java
>>> method names taking different argument across different classes.  I still
>>> have argument checking because I dispatch to a fixed argument CLOS method.
>>>  However, I cannot do this within a single class.  The first obvious answer
>>> is to name mangle the generics.  This is too sloppy.  The other answer
>>> would be to name mangle the methods and have the generic be smart enough to
>>> dispatch to the correct method based on the argument number and types (all
>>> in CLOS).  This would be a lot of work so I thought I might solicit
>>> alternative suggestions.  Perhaps there is a simple answer that I hasn't
>>> come to me.
>>>
>>> Thanks.
>>>
>>> Blake McBride
>>>
>>>
>>> _______________________________________________
>>> armedbear-devel mailing list
>>> armedbear-devel at common-lisp.net
>>> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
>>>
>>>
>>
> _______________________________________________
> armedbear-devel mailing list
> armedbear-devel at common-lisp.net
> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/armedbear-devel/attachments/20130216/1632be17/attachment.html>


More information about the armedbear-devel mailing list