looking for the best polyglot setup for a groovy project calling clojure code

123 views
Skip to first unread message

john....@gmail.com

unread,
Jan 30, 2013, 5:52:04 AM1/30/13
to cloju...@googlegroups.com
Hi,
I have a groovy project which calls clojure code like this:

import java.util.List
import clojure.lang.RT
import clojure.lang.Var
import clojure.lang.Symbol
class Domain {
static Var REQUIRE =RT.var("clojure.core","require")
    static  {
        REQUIRE.invoke(Symbol.intern("domain.core"))
    }
 static Var GET_PROJECTS =RT.var("domain.core","get-projects")

    static List projectsOfUser(Integer user) {
            return (List) GET_PROJECTS.invoke(user)
    }
}

I have setup the groovy and clojure projects as sub projects in build.gradle
where the groovy project has a dependency runtime project(':clojure-project')

My problem is that when I make changes to core.clj (contains get-projects fn)
I have to restart the whole groovy project to see any changes.

How can can I configure gradle so that live-changes happen?
(Maybe make the groovy project depending not on the jar but on the directory containing core.clj? How do I achieve this?)

Many Greetings
John 

Meikel Brandmeyer

unread,
Jan 30, 2013, 6:02:05 AM1/30/13
to cloju...@googlegroups.com
Hi,


Am Mittwoch, 30. Januar 2013 11:52:04 UTC+1 schrieb john....@gmail.com:
Hi,
I have a groovy project which calls clojure code like this:

I have setup the groovy and clojure projects as sub projects in build.gradle
where the groovy project has a dependency runtime project(':clojure-project')

My problem is that when I make changes to core.clj (contains get-projects fn)
I have to restart the whole groovy project to see any changes.

How can can I configure gradle so that live-changes happen?
(Maybe make the groovy project depending not on the jar but on the directory containing core.clj? How do I achieve this?)


I'm not sure what you mean with "restart the whole groovy project", but you could add the clojure source directories to the relevant classpath.

yourTask {
    classpath = project.files(project(':clojure-project").sourceSets.main.clojure.srcDirs, classpath)
}

Then the clojure source directories should be picked up before any of the jar dependencies.

Meikel
 

john....@gmail.com

unread,
Jan 30, 2013, 6:11:28 AM1/30/13
to cloju...@googlegroups.com

Great! I think that will help me! This is my second day with gradle so please forgive if I am overlooking obvious things.
My groovy project apply's the jetty plugin so I "restart the whole groovy project" with ^C and gradle "jettyRun" the Servlet then calls methods of Domain.groovy

Many thanks
john
 
Am Mittwoch, 30. Januar 2013 11:52:04 UTC+1 schrieb john....@gmail.com:

Meikel Brandmeyer

unread,
Jan 30, 2013, 6:20:08 AM1/30/13
to cloju...@googlegroups.com
I was just wondering, because I didn't expect repl-style development with groovy. But your are right: a jetty makes also perfect sense.

But please note: you will also need a Clojure repl of sorts to reload the modified code. (Or some other way to trigger the reload, like a button or something in the application.) Clojure by itself won't pick up changes without being told to. So prepping the classpath is just one step to make this work.

Meikel

john

unread,
Jan 30, 2013, 6:28:32 AM1/30/13
to cloju...@googlegroups.com
Well I was actually hoping that the Var.invoke would do the trick. This is how I understood Rich Hickey http://skillsmatter.com/podcast/ajax-ria/impromptu-rich-hickey-lightning-talk in his Lightning Talk.... But I am pretty sure  your right. Clojure RT won't check the filesystem for changes. Otherwise I will try to embed nrepl Server 

Many Greetings
John 

Meikel Brandmeyer

unread,
Jan 30, 2013, 6:49:25 AM1/30/13
to cloju...@googlegroups.com
An embedded nrepl is maybe a bit more work, but certainly worth it. Then you can directly connect to the running jetty process and work directly in the server repl. That makes the feedback loop even faster than editing the files on disk. And you get support for your favourite IDE for free. :)

Meikel

john

unread,
Feb 6, 2013, 10:49:27 AM2/6/13
to cloju...@googlegroups.com
Hi Meikel,
when I connect to my nrepl server service the nrepl client evaluates all parentheses expressions as soon as I start typing. This leads to a lot of classnotfound exceptions.
I was told that I need to include  https://github.com/ninjudd/clojure-complete/ to remedy the "to early evaluation" but as soon as I put a 
(require 'complete.core)  the gradle    compileClojure task never finishes. It seems to hang. Can you help?

Meikel Brandmeyer

unread,
Feb 6, 2013, 11:33:25 AM2/6/13
to cloju...@googlegroups.com
????


Am Mittwoch, 6. Februar 2013 16:49:27 UTC+1 schrieb john:
Hi Meikel,
when I connect to my nrepl server service the nrepl client evaluates all parentheses expressions as soon as I start typing. This leads to a lot of classnotfound exceptions.
I was told that I need to include  https://github.com/ninjudd/clojure-complete/ to remedy the "to early evaluation" but as soon as I put a 
(require 'complete.core)  the gradle    compileClojure task never finishes. It seems to hang. Can you help?


I have no clue what's going on. The repl should be usable without clojure-complete. How do you start the nrepl server? And how do you connect to it? It don't think that this is a problem of gradle/clojuresque, but rather of your nrepl client. But let's check.

Meikel
 

john

unread,
Feb 6, 2013, 2:05:21 PM2/6/13
to cloju...@googlegroups.com
Hi,
I was doing something silly.    
I was getting in my nrepl emacs client an Exception : clojure.lang.Compiler$CompilerException: java.lang.ClassNotFoundException: complete.core, compiling:(NO_SOURCE_PATH:1) 

So I included the line (require 'complete.core) in my server core.clj

But I then realized that  I just only need to have  complete.core.jar on my class path. 
So I am doing good for now.

Maybe I did find a performance problem with clojuresque though because if I 
include a (require 'complete.core) in my code the build takes nearly 70 secs.
just in case  here is my code:

gradle --version
------------------------------------------------------------
Gradle 1.3
------------------------------------------------------------
Gradle build time: Tuesday, November 20, 2012 11:37:38 AM UTC
Groovy: 1.8.6
Ant: Apache Ant(TM) version 1.8.4 compiled on May 22 2012
Ivy: 2.2.0
JVM: 1.7.0_13 (Oracle Corporation 23.7-b01)
OS: Mac OS X 10.7.5 x86_64

gradle build
:domain:compileClojure
:domain:compileJava
:domain:processResources UP-TO-DATE
:domain:classes
:domain:jar
:domain:assemble
:domain:clojureTest UP-TO-DATE
:domain:compileTestJava UP-TO-DATE
:domain:processTestResources UP-TO-DATE
:domain:testClasses UP-TO-DATE
:domain:test
:domain:check
:domain:build

BUILD SUCCESSFUL

Total time: 1 mins 8.852 secs

heres the code:

tree .
.
├── build.gradle
├── domain
│   └── src
│       └── main
│           ├── clojure
│           │   └── de
│           │       └── mytest
│           │           └── core.clj
│           └── java
│               └── de
│                   └── mytest
│                       └── Domain.java
└── settings.gradle

---------------------------------- build.gradle---------------

apply plugin: 'idea'

buildscript {
    repositories {
        mavenRepo name: 'clojars', url: 'http://clojars.org/repo'
    }
    dependencies {
        classpath 'clojuresque:clojuresque:1.5.4'
    }
}


project(':domain') {
    apply plugin: 'clojure'
    apply plugin: 'java'
    apply plugin: 'application'

    mainClassName = "de.mytest.Domain"

    compileJava.dependsOn compileClojure
    repositories {
        clojarsRepo()
        mavenCentral()
    }


    dependencies {
        compile 'org.clojure:clojure:1.5.0-alpha3'
        compile 'org.clojure:tools.nrepl:0.2.1'
        compile 'clojure-complete:clojure-complete:0.2.2'
    }
}


---------------------------------- settings.gradle---------------
include 'domain'

------------------------ Domain.java -------------------------
package  de.mytest;

import clojure.lang.RT;
import clojure.lang.Var;
import clojure.lang.Symbol;

public class Domain {

 static Var REQUIRE =RT.var("clojure.core","require");

 static  {
       REQUIRE.invoke(Symbol.intern("de.mytest.core"));
}

static Var START_REPL =RT.var("de.mytest.core","start-repl");

  public static void main(String[] args){
     START_REPL.invoke();
 }}


------------------------------ core.clj ------------------------------------
(ns de.mytest.core)
(require 'complete.core)
(use '[clojure.tools.nrepl.server :only (start-server stop-server)])

(defn start-repl[]
(println "before start")
  (start-server :port 7888)
  (println  "server nrepl started"))

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

Many Greetings
John

Meikel Brandmeyer

unread,
Feb 6, 2013, 3:52:01 PM2/6/13
to cloju...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

Am 06.02.2013 20:05, schrieb john:
> Maybe I did find a performance problem with clojuresque though
> because if I include a (require 'complete.core) in my code the
> build takes nearly 70 secs.

clojure-complete does some fancy class retrieval stuff from the
classpath on load. That is nothing clojuresque can do anything about.

I'm now sure that your problems with the repl are not related to
clojuresque.

Meikel

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJREsJwAAoJEM2sO9pIirXjUbgP/13N7xugLhA5jV9wkSa2x92i
mldUqPVH/dQ8XbtumocFsOcZvoqCS2VCpePGfE8s3gE711Ki1C17pvrZx2R6vIht
BiU0yTm79fnBefifJE7HFDdvWENgV5kIjuiHXRq+E5uELY82rGKCSIq2YvoOsuFX
QFHZgk710DJ4D3W4FKcOqhigqr17FywXPcFZtNFtHLVZFnslyw29xMmjFme/mcrZ
ib5E8KI/HZ39C3jAbex5Ip+XCQm7eIsgRiy3RfK+FcedE/JF9vkCccYlyMNFUAd8
C5OttazBB73lMSvzdntzzvznysE4hkt9YdZWMV+xiHuZDRX/CECxZouCwqHGUFoT
9JaBdX398sp7q4886BV4ObNZutLganytYsHPIue7xGwgrLlaJa6hP03rQEfBD/BJ
Y+v69VPhkNSH70t5HFuGWrXG/NlBZ8vKwlIvZbgBVXAgZp+sdEl9M5vG6q9N4z0l
7puf6hRyo8PeVoM/3MYi269sS1ILigc06NGC330eERouZdr+v0Ittiqm9xMFadBM
IDqhbTgXRrT16qx0kfpInTgpgHsM/B78P0yjBTzmgbxQAMsFqP5wGb8DNXabeO7+
9sl95XJo89o8uIb/Rx+Gd+DSVMfZVVwH3Q28GUyM95ytk2eGl0IuamiU3q9olFk4
9wCK74HvL1rGDp6kv9x1
=V6KE
-----END PGP SIGNATURE-----
Reply all
Reply to author
Forward
0 new messages