1
votes

I am trying to integrate some Clojure code with Java and Groovy under Intellij on a Grails 3 project. My ultimate goal is to use some Clojure code mixed with Groovy code.

I wrote a class in Groovy and I am trying to instantiate it in Clojure. Basically what I did was:

1) I wrote a class app/server/src/main/groovy/mypackage/State.groovy

package mypackage

class State {
   def Calendar date;
   def static State stateBuilder() {
       State state = new State()
       state.date = Calendar.getInstance()
       return state;
   }

2) Then I wrote file called app/server/src/main/clj/state.clj as follows:

(ns mypackage.state)

(import mypackage.State)

(def groovystate (new State))

(println (bean groovystate))

(defn -main
  [& args]
  (println "Hello, World!"))

3) Finally I wrote the following app/server/project.clj

 (defproject brkmopt "0.1.0-SNAPSHOT"
   :description "Test Clojure and Grails integration"
   :url ""
   :plugins [[lein-localrepo "0.5.4"]]
   :license {:name ""
             :url ""}

   :repositories [["bintray-grails-plugins" "https://dl.bintray.com/grails/plugins"]
                  ["java.net" "https://download.java.net/maven/2"]
                  ]

   :dependencies [[org.clojure/clojure "1.9.0"]
                  [org.codehaus.groovy/groovy-all "3.0.0-alpha-4" :extension "pom"]
                  [org.grails/grails-datastore-gorm "6.1.9.RELEASE"]
                  ]

   :main mypackage.state
   :source-paths ["src/main/clj"]
   :java-source-paths ["src/main/java"]
   :test-paths ["src/test/clj"]
   :resource-paths ["resources"]
   :target-path "out/production"
   :aot :all)

Note that I configured :target-path to "out/production" and configured :dependencies to download some dependencies lein fail to find at Groovy project.

It worked. Running "lein run" I got:

{:date nil}
Hello, World!

as expected.

But if I replace:

(def groovystate (new State))

by

(def groovystate (State/stateBuilder))

The compiler start asking for more dependencies and I spent several hours in a dependency hell that ultimately lead me on a dead end asking for a dependency I could not found on any maven repository.

The latest version of the project.clj is:

 (defproject brkmopt "0.1.0-SNAPSHOT"
   :description "Test Clojure and Grails integration"
   :url ""
   :plugins [[lein-localrepo "0.5.4"]]
   :license {:name ""
             :url ""}

   :repositories [["bintray-grails-plugins" "https://dl.bintray.com/grails/plugins"]
                  ["java.net" "https://download.java.net/maven/2"]
                  ;["central"  "https://central.maven.org/maven2/"]
                  ;["sonatype" "https://oss.sonatype.org/content/repositories/releases"]
                  ;["snapshots" "https://blueant.com/archiva/snapshots"]
                  ]

   :dependencies [[org.clojure/clojure "1.9.0"]
                  [org.clojure/data.priority-map "0.0.10"]
                  [com.google.code.gson/gson "2.7"]
                  [org.codehaus.groovy/groovy-all "3.0.0-alpha-4" :extension "pom"]
                  [org.grails/grails-datastore-gorm "6.1.9.RELEASE"]
                  [org.grails.plugins/events "3.3.2"]
                  [org.grails/grails-core "3.3.3"]
                  [org.grails/grails-plugin-domain-class "3.3.3"]
                  [org.grails/grails-web-databinding "3.3.3"]
                  [org.grails/grails-gsp "3.3.1"]
                  ]

   :main mypackage.state
   :source-paths ["src/main/clj"]
   :java-source-paths ["src/main/java"]
   :test-paths ["src/test/clj"]
   :resource-paths ["resources"]
   :target-path "out/production"
   :aot :all)

I could not find grails-gsp version 3.3.1. Anyway, I am sure that this is not the way to go. It was supposed to use the same libraries Grails uses, not download them again.

All the necessary dependencies are at .dr/.gradle/ folder but I have no idea on how to make them visible to Clojure.

Please advise!

---------- EDIT 1 ----------

As suggested by Alex, I am including more information. I am embedding the Clojure code on a Grail 3 project as shown in the picture below:

enter image description here

When it works (first case), I see this:

root@linuxkit-025000000001:~/workspace/brkm_app/server# lein run
Compiling com.nitryx.brkmopt.state
{:date nil}
Hello, World!
root@linuxkit-025000000001:~/workspace/brkm_app/server# 

When I change to (println (bean (groovystate)) and include all dependencies I could, I see this:

root@linuxkit-025000000001:~/workspace/brkm_app/server# lein run
Could not find artifact org.grails:grails-gsp:jar:3.3.1 in central (https://repo1.maven.org/maven2/)
Could not find artifact org.grails:grails-gsp:jar:3.3.1 in clojars (https://repo.clojars.org/)
Could not find artifact org.grails:grails-gsp:jar:3.3.1 in bintray-grails-plugins (https://dl.bintray.com/grails/plugins)
Could not find artifact org.grails:grails-gsp:jar:3.3.1 in java.net (https://download.java.net/maven/2)
This could be due to a typo in :dependencies, file system permissions, or network issues.
If you are behind a proxy, try setting the 'http_proxy' environment variable.
root@linuxkit-025000000001:~/workspace/brkm_app/server# 

Grails runs on Gradle. Lein on Maven. I am running it on a docker container and there is no .m2 folder there.

root@linuxkit-025000000001:~# ls -la
total 20
drwxr-xr-x  1 root root 4096 Feb 16 18:41 .
drwxr-xr-x  1 root root 4096 Feb 12 15:18 ..
drwx------  2 root root 4096 Feb 16 18:41 .cache
drwxr-xr-x  3 root root 4096 Feb 16 16:23 .lein
drwxr-xr-x  1 root root 4096 Feb 12 15:18 .vscode
drwxr-xr-x 15 root root  480 Feb 13 19:42 workspace

root@linuxkit-025000000001:~# cd workspace
root@linuxkit-025000000001:~/workspace# ls -la
total 36
drwxr-xr-x 15 root root  480 Feb 13 19:42 .
drwxr-xr-x  1 root root 4096 Feb 16 18:41 ..
-rw-r--r--  1 root root 6148 Feb 13 19:27 .DS_Store
drwxr-xr-x  9 root root  288 Feb 15 14:08 .dr
drwxr-xr-x 18 root root  576 Feb 16 22:08 .git
-rw-r--r--  1 root root  120 Feb 13 17:42 .gitignore
drwxr-xr-x 13 root root  416 Feb 16 17:09 brkm_app
drwxr-xr-x  4 root root  128 Feb 13 16:53 doc
-rw-r--r--  1 root root  290 Feb 13 18:56 docker-compose.yml
drwxr-xr-x  9 root root  288 Feb 13 19:27 dockerfiles
-rwxr-xr-x  1 root root  994 Feb 13 17:42 run_container_linux.sh
-rwxr-xr-x  1 root root  949 Feb 15 18:47 run_container_mac.sh
-rwxr-xr-x  1 root root   37 Feb 13 17:50 run_idea.sh
-rwxr-xr-x  1 root root   20 Feb 13 17:49 run_visual_studio_code.sh
drwxr-xr-x  8 root root  256 Feb 15 11:51 tests

root@linuxkit-025000000001:~/workspace# cd brkm_app/
root@linuxkit-025000000001:~/workspace/brkm_app# ls -la
total 40
drwxr-xr-x 13 root root   416 Feb 16 17:09 .
drwxr-xr-x 15 root root   480 Feb 13 19:42 ..
-rw-r--r--  1 root root    21 Feb 13 16:53 .gitignore
drwxr-xr-x  4 root root   128 Feb 13 17:37 .gradle
drwxr-xr-x 12 root root   384 Feb 16 22:13 .idea
-rw-r--r--  1 root root   692 Feb 13 17:40 brkm_app.iml
drwxr-xr-x 13 root root   416 Feb 13 16:53 client
drwxr-xr-x  3 root root    96 Feb 13 16:53 gradle
-rwxr-xr-x  1 root root  4971 Feb 13 16:53 gradlew
-rwxr-xr-x  1 root root  2404 Feb 13 16:53 gradlew.bat
-rwxr-xr-x  1 root root 12540 Feb 15 11:51 lein
drwxr-xr-x 16 root root   512 Feb 16 22:08 server
-rw-r--r--  1 root root    26 Feb 13 16:53 settings.gradle

I found the dependencies under .dr folder running a find command. I do not really understand why they are there and how they are used by Grails/Gradle.

2

2 Answers

1
votes

I see both a build.gradle and a project.clj, but you really need to pick one. Since it seems like you’re integrating into an existing Gradle project, I’d recommend installing the Gradle Clojure plugin: https://github.com/gradle-clojure/gradle-clojure. Don’t follow the instructions about the clj tool, just add it like another plugin if you’ve done that before.

That hopefully should resolve any dependency issues you have. The clojure plugin will be able to compile your clojure code as part of the normal Gradle build process.

0
votes

grails-web-databinding version 3.3.3 is in Maven central repo, which should be included by default by Leiningen. Perhaps it would be good to include the output you're seeing and also a list of the libs you expect to use for grails.

Leiningen uses Maven tooling under the hood and caches libs in ~/.m2/repository. I don't know of any way to make it use the deps in .dr/.gradle/ folder.