1

I have to write a pure Java library. But I'd like to use Clojure to unit test it.

So I'd like to set up something like this : two project repositories. The Java code itself, and a second, Leiningen project that includes the library and runs unit tests on it.

I do TDD so this is a fairly tight iteration (ie. write a test, write code to pass it). I can have code from both projects open in Emacs at the same time, but I want to know how to automate the connection.

For example, ideally, whenever I do "lein test", it would grab the most up-to-date Java code, compile it (if it isn't compiled), pull it into the Clojure project and use it in the tests.

How can I achieve this? I currently have the Lein project.clj file refer to the Java library in a local Maven repository. But I'm not sure if Lein automatically updates from Maven unless, say the version number changes, and I don't think I want to have to be updating the version numbering for every single change to the code-base / every 2 or 3 minutes. (At least, certainly not manually.)

Anyone got experience with this?

1 Answer 1

4

You can do this with simple java interop. You should not be using maven at all for your local files (java or clojure), only for outside libraries.

Here is a sample:

Java code:

~/xpr > tree
.
└── src
    └── samp
        └── HelloMain.java

> cat  src/samp/HelloMain.java 
package samp;
public class HelloMain {
  public static void hello() {
    System.out.println("Hello There");  }}

Clojure code:

 > cat project.clj 
(defproject clj "0.1.0-SNAPSHOT"
  :dependencies [
    [org.clojure/clojure "1.9.0-alpha13"]
  ]
  :java-source-paths ["/home/alan/xpr/src"]
  :main ^:skip-aot clj.core
  :target-path "target/%s"
)

> cat test/tst/clj/core.clj
(ns tst.clj.core
  (:use clj.core
        clojure.test )
  (:import [samp.HelloMain])
)

(println "begin" )
(samp.HelloMain/hello)
(println "end" )

To Run:

> lein test
(:repositories detected in user-level profiles! [:user] 
See https://github.com/technomancy/leiningen/wiki/Repeatability)
Compiling 1 source files to /home/alan/clj/target/base+system+user+dev+test+test/classes
begin
Hello There
end

lein test user

Ran 0 tests containing 0 assertions.
0 failures, 0 errors.

So the clojure compiler has a reference to the java source code through the entry in project.clj

:java-source-paths ["/home/alan/xpr/src"]

When you run lein test it will compare the java source files to the compiled java *.class files it has cached and recompile the java source when necessary. If we make a change

"Hello There" -> "Hello, again!" in the java source, we get:

 > lein test
(:repositories detected in user-level profiles! [:user] 
See https://github.com/technomancy/leiningen/wiki/Repeatability)
Compiling 1 source files to /home/alan/clj/target/base+system+user+dev+test+test/classes
begin
Hello, again!
end

lein test user

Ran 0 tests containing 0 assertions.
0 failures, 0 errors.

So lein detected the source file change and recompiled the java source files.


Update

I have a template project with mixed Clojure/Java source code. Just clone it and you are off to the races!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.