Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compile Java code after Clojure code in leiningen

In my Leiningen project:

(defproject com.stackoverflow.clojure/tests "0.1.0-SNAPSHOT"
  :description "Tests of Clojure test-framework."
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [instaparse "1.3.4"]]
  :aot [com.stackoverflow.clojure.testGenClass]
  :source-paths      ["src/main/clojure"]
  :java-source-paths ["src/main/java"]
  :test-paths        ["src/test/clojure"]
  :java-test-paths   ["src/test/java"]
  )

I'm generating Java-classes with gen-class:

(ns com.stackoverflow.clojure.testGenClass
  (:gen-class
     :name com.stackoverflow.clojure.TestGenClass
     :implements [com.stackoverflow.clojure.TestGenClassInterface]
     :prefix "java-"))

(def ^:private pre "START: ")

(defn java-addToString [this text post]
  (str pre text post))

which I want to use in Java:

package com.stackoverflow.clojure;

public class TestGenClassTest {

    private TestGenClassTest() {
    }

    public static void main(String[] args) {
        TestGenClassInterface gc = new TestGenClass();
        System.out.println(gc.addToString("Called from Java!", " :END"));
    }
}

Starting lein compile throws the following error:

Compiling 4 source files to /home/eddy/workspace/TestSkripts/target/classes
/home/eddy/workspace/TestSkripts/src/main/java/com/stackoverflow/clojure/TestGenClassTest.java:9: error: cannot find symbol
        TestGenClassInterface gc = new TestGenClass();
                                       ^
  symbol:   class TestGenClass
  location: class TestGenClassTest
1 error

It seems to me, that during compilation of the Java-code (here: TestGenClassTest) the Class is not available. What I usually did is

  1. commenting out those parts that use the gen-class generated class (here TestGenClass)
  2. run lein compile (to generate the class-file)
  3. then taking the outcommented code in again
  4. and run lein compile again.

I' sure there is a better way, that makes all manual steps redundat.

like image 615
Edward Avatar asked Oct 17 '14 07:10

Edward


People also ask

What does clojure compile to?

Clojure compiles all code you load on-the-fly into JVM bytecode, but sometimes it is advantageous to compile ahead-of-time (AOT). Some reasons to use AOT compilation are: To deliver your application without source. To speed up application startup.


1 Answers

You want to add a pre-compilation step. Run the pre-compile ...then you're good to go.

  1. Put your interface into a seperate file path src/main/pre/interface/clojure

  2. add the below to :profiles

    (defproject com.stackoverflow.clojure/tests "0.1.0-SNAPSHOT"
     :description "Tests of Clojure test-framework."
     :url "http://example.com/FIXME"
     :dependencies [[org.clojure/clojure "1.6.0"]
                 [instaparse "1.3.4"]]
     :source-paths      ["src/main/clojure"]
     :java-source-paths ["src/main/java"]
     :test-paths        ["src/test/clojure"]
     :java-test-paths   ["src/test/java"]
     :profiles { :precomp { :source-paths ["src/main/pre/interface/clojure"]
                         :aot [parser.ast] } })
    

Then you can run lein with-profile precomp compile after which lein test should work

like image 94
Pumphouse Avatar answered Oct 20 '22 11:10

Pumphouse