Title: Java -> elisp communication (was RE: BanInfo wizard anyone?)

Hi Nick,

> > >> The translation layer could handle things like the java method
> > >> signature returning, say, a hashmap.  The layer could have a
> > >> hashmap to alist converter.
> > >
> > > I've actually got a working prototype of a generic
> > > interface/translation layer that does just that.  For now, I'm
> > > calling it JUCI (JDEE Universal Communication Interface).
>  It allows
> > > elisp to call java and java to call back to elisp in a standard
> > > manner.  It's still very alpha.  One (minor, IMHO)
> drawback is that
> > > it requires JDK 1.3 or greater, because I'm making use of the
> > > java.lang.reflect.Proxy mechanism.
> [..elided...]
> >
> > I see.  You aren't referencing the beanshell here.  Are you
> opening up
> > a direct connection to a JVM?
>
> Well, I didn't, but the beanshell is still directly involved.
>  Elisp sends strings to the beanshell which invokes java
> code, and java code invokes interfaces which, through a
> proxy, print lisp forms back to stdout and are evaluated by
> `bsh-eval-r'.

I looked into this problem some time ago, and actually got a working interface between Transmogrify and Emacs, using their Hook interface. You can download it from http://home.nc.rr.com/nascifandelaine/emacs.html.

Some comments though:
1) Development in Transmogrify has not being very active for quite some time (http://sourceforge.net/mailarchive/forum.php?thread_id=612615&forum_id=1015). The last major release is more than a year and a half old and I don't see any signs of a new release soon.

2) Graham Bennet has an implementation of a Refactoring tool for Java already integrated with Emacs. His tool takes some pages from Transmogrify http://freefactor.sourceforge.net.

3) Both my implementation and Graham's use gnuclient to implement the Java -> elisp side of the equation (elisp -> Java using the BeanShell support in JDE). The reason being that Java tools will need (and that is true for Transmogrify) to make asynchronous calls to the elisp side.

I'm curious on how the JUCI would solve that problem, as I assume the BeanShell call that starts the communication with the Java portion would block until a response is received, so how could the Java portion (in the same thread of execution) submit a lisp form back for evaluation? Would you use multiple BeanShell instances or multiple threads inside Beanshell, one to submit the Java request and one to "listen" to stdout for asynchronous evaluation requests?

An "real world" example from my Transmogrify Hook implementation should make it clear. Let's say you use the elisp interface to call the ExtractMethod refactoring on Transmogrify. The steps would be:

1) User marks a region in the current buffer and calls "jde-transmogrify-extract-method";
2) This defun calls jde-eval, using the BeanShell to activate the Transmogrify engine;
3) Transmogrify gathers the necessary information by making calls to the Hook interface:

Here I'm guessing a little, I don't remember exactly the number and order of calls to the Hook interface.
For simplicity let's assume all the source code info can be obtained in 3.2 call. It could actually require three to four calls to obtain line number, caret position, etc.

3.1) getUserInput (to obtain the new method name)
3.2) getSelecteText (to obtain the body of the extracted method)
3.3) displayMessage or displayException (for the result)

Each one of the 3.* calls will create an elisp form that will be sent (via gnuclient) back to Emacs for evaluation.
The processing keeps going back and forth between the Transmogrify engine and Emacs (through the hook implementation and gnuclient) until Transmogrify has all the info it needs, at which point:

4) Transmogrify applies the refactoring to the source code;
5) Transmogrify returns the control to the original jde-eval call.
6) jde-transmogrify-extract-method completes

(this is really asking for an UML sequence diagram :-)

So even though the refactoring is "put in motion" by the jde-eval call, the control of execution is pretty much in the hands of Transmogrify. Emacs must be ready to act as an "evaluation server", receiving forms on demand. This is the behavior implemented by gnuserv/gnuclient. It would be great if you can find a way to implement this behavior using BeanShell only. You mentioned that the Java code would print "lisp forms back to stdout and are evaluated by `bsh-eval-r'". Doesn't that imply that you are limited to control flows where Emacs is driving? How can the Java proxy "trigger" the call to bsh-eval-r, get the result of the evaluation and recover the control of the execution flow - for example, to move from 3.1 to 3.2 in the scenario described above?

All that said I would love to see something like JUCI actually integrated into JDE; I advocated that in many messages some months ago. I just don't see how the requirements of generic Java tools (like asyncronous calls back to Emacs) can be solved without the use of gnuclient or a similar tool. Having an OpenTool (to use the JBuilder terminology) -like API to allow pure Java extensions to an IDE is becoming quite standard, and would be a powerful extension to JDEE.

Best Regards,
        Nascif

>
> /Nick
>

Reply via email to