Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using gradle/clojuresq to build clojure

I'm trying to use gradle/Clojuresque to build clojure code, run it, and get uberjar. I use hints from http://dev.clojure.org/display/doc/Getting+Started+with+Gradle, https://bitbucket.org/kotarak/clojuresque/wiki/Getting%20Started, and 'Could not find us.bpsm:edn-java:0.4.3' error with Gradle for Clojure (Clojuresque).

This is the grade script.

buildscript {
    repositories { 
        maven { url "http://clojars.org/repo" } 
        mavenCentral()
    }
    dependencies {
        classpath "clojuresque:clojuresque:1.7.0" 
    }
}

apply plugin: 'clojure'

clojure.aotCompile = true

repositories {
    flatDir dirs: project.file("lib/runtime")
    maven { url "http://clojars.org/repo" }
}

With gradle build task, there is no error and I have a jar file, but I don't see any class file generated; I don't think the generated jar contains nothing, especially when I compared the results from manual build (Compile clojure source into class (AOT) from command line (not using lein)).

.
├── build
│   ├── libs
│   │   └── clojure.jar
│   └── tmp
│       └── jar
│           └── MANIFEST.MF
├── build.gradle
└── src
    └── hello
        └── core.clj

This is the core.clj

(ns hello.core
  (:gen-class))
(defn -main
  "This should be pretty simple."
  []
  (println "Hello, World!"))

What might be wrong? Also, how to run the code and get uberjar like lein run and lein uberjar does?

I zipped the directory in https://dl.dropboxusercontent.com/u/10773282/share/2015/clojure_test.zip

like image 714
prosseek Avatar asked Dec 14 '22 16:12

prosseek


1 Answers

Create the class files

The source code should be located in ./src/main/clojure as it is the default directory.

One can specify source file in gradle file, though.

sourceSets {
    main {
        clojure {
            srcDirs = ['src']
        }
    }
}

The other issue was with missing dependencies:

repositories {
    maven { url "http://clojars.org/repo" }
    mavenCentral()
}

dependencies {
    compile "org.clojure:clojure:1.6.0"
}

gradle build will generate the class files.

Get the jar file

We need to set the main class for the jar file.

jar
{
    manifest.attributes("Main-Class": "hello.core")
}

I'm not exactly sure if the setup is quite necessary; gradle jar will generate the jar file.

execute the jar file

This is the command to run the code:

java -cp .:<PATH>/clojure-1.6.0.jar:build/libs/clojure_test.jar hello.core

uberjar

There are three modifications needed: hints from https://github.com/DevonStrawn/Clojuresque-Boilerplate/blob/master/UberJar/build.gradle.

uberjar
{
    manifest.attributes("Main-Class": "hello.core")
}

apply plugin: 'application'

uberjar.enabled = true

Execute the uberjar

Now just one jar for the execution

clojure_test> java -jar build/libs/clojure_test-standalone.jar 
Hello, World!

The new build.gradle file

buildscript {
    repositories { 
        maven { url "http://clojars.org/repo" } 
        mavenCentral()
    }
    dependencies {
        classpath "clojuresque:clojuresque:1.7.0" 
    }
}

apply plugin: 'clojure'

clojure.aotCompile = true

sourceSets {
    main {
        clojure {
            srcDirs = ['src']
        }
    }
}

repositories {
    maven { url "http://clojars.org/repo" }
    mavenCentral()
}

dependencies {
    compile "org.clojure:clojure:1.7.0"
}

jar
{
    manifest.attributes("Main-Class": "hello.core")
}   

uberjar
{
    manifest.attributes("Main-Class": "hello.core")
}

apply plugin: 'application'

uberjar.enabled = true

Shadow jar

From Opal's answer, I add the gradle script that create shadowJar. It contains the MAINFEST file that sets up the Main-Class.

buildscript {
    repositories { 
        maven { url "http://clojars.org/repo" } 
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath "clojuresque:clojuresque:1.7.0" 
        classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.0'
    }
}

apply plugin: 'application'
apply plugin: 'clojure'
apply plugin: 'com.github.johnrengelman.shadow'

clojure.aotCompile = true
mainClassName = 'hello.core'

sourceSets {
    main {
        clojure {
            srcDirs = ['src']
        }
    }
}

repositories {
    maven { url "http://clojars.org/repo" }
    mavenCentral()
}

dependencies {
    compile "org.clojure:clojure:1.7.0" 
}

Or use these two lines of code instead of the manifest change code:

apply plugin: 'application'
mainClassName = 'hello.core'

Execute the shadow jar

Get the ubjer jar

gradle shadow

It's the same as uberjar.

clojure_test> java -jar build/libs/clojure_test-all.jar 
Hello, World!

References

  • https://github.com/johnrengelman/shadow
  • Boiler plate - https://github.com/DevonStrawn/Clojuresque-Boilerplate
  • Building a uberjar with Gradle
like image 172
prosseek Avatar answered Jan 25 '23 14:01

prosseek