Re: Proposed New Structure (starter for 10)

[email protected] (Phillip Lord) Wed, 26 Aug 2015 17:19:25 +0100
Newsgroups gmane.emacs.jdee.devel
Message-ID <[email protected]>
Paul Landes <[email protected]> writes:

> On Aug 26, 2015, at 9:25 AM, Phillip Lord <[email protected]> wrote:
>
>> Paul Landes <[email protected]> writes:
>> At the moment, I am concerned about how the build tool should be
>> launched. Maven, for example, is quite tricky to launch from within a
>> running JVM. So, I am not clear where, for example, "compile"
>> functionality should go -- JDEE as is (via an external process) or
>> jdee-live (via direct JVM invocation).
>> 
>
> This is where it gets complicated. The compilation (generation of classes) can
> be done via maven in the running JVM process, but then using the generated
> .class files become a mess regardless of the language used on top of the JVM
> because it is a JVM class loading issue itself. Class loaders are hung on to
> (technically only as long as the class has a reference count but I've seen
> this not to be the case) and old versions of classes linger. Classes
> referenced across loaders create signature and no class def exceptions etc.

Indeed, this is a risk. Although I am not entirely convinced that this
is caused by actually compiling the classes, merely that they have been
recompiled which potentially will cause all the issues that you mention.

At the moment I tend toward thinking that the build tool interaction
should be out-of-band of nREPL and the JVM, simply because maven has no
decent API. But then, for example, how do I get the source paths?

The other possibility is to use lisp to query the JVM, and then the JVM
decide how to answer this question. For a maven based project, it could
invoke maven, to get the effective pom, parse it, extract the data. But
for a leiningen based project (i.e. likely to be a mixed java/clj
project), it could just ask leiningen direct.

> This is why I wanted to find a way to use the Java source itself (not
> the .class file with reflection/introspection) for all class
> generation, wizard etc code JDEE currently uses beanshell for. Clojure
> seems to do a good job of handling this, but I'm not sure what they do
> with old versions of classes for functions/files that get recompiled.
> That said, they're going directly for Clojure to byte code so it's a
> little different. I started to look at Clojure's dynamic class loader
> but got lost in the weeds and no documentation made it more difficult.

Ironically, I had a quick peak at the JDEE source and discovered that it
actually includes a DynamicClassLoader that is supposed to reload from
file every time.

Clojure, you are right, has to handle this because every function
compiles to a class and a lisp without the ability to re-eval functions
would be daft. The old versions should hang around while they are
needed, hence insanity like this...


(defn bob []
  (println "hello from bob 1"))

(def x bob)
(def y #'bob)

;; #=> hello from bob 1
(x)
;; #=> hello from bob 2
(y)

(defn bob []
  (println "hello from bob 2"))

;; #=> hello from bob 1
(x)
;; #=> hello from bob 2
(y)

They are supposed to be accessible for GC as you say.

My strategy for dealing with this was to use Vinyasa
(https://github.com/zcaudate/vinyasa) which has a "reimport"
functionality.

Use of Java source, I agree, I can see the advantages. But set against
this is dealing with the issues of when the Java source is wrong.


>> Incidentally, I was thinking of renaming jdee-live again to "jive" just
>> for shortness.
>> 
>
> Not sure that's a great idea.


I'm just worried about secondary files "jdee-live.el" is fine. But
"jdee-live-maven".

Phil

------------------------------------------------------------------------------