6

I'm working on a Java project which uses Maven to build it. The bit of functionality I'm developing would be quite cumbersome in Java, but straightforward in Clojure, so I'd like to implement it in Clojure and have Java use the resulting generated classes seamlessly.

Here's the unit test I need to pass (src/test/java/com/foo/weather/DataProcessorTest.java):

package com.foo.weather;

import static org.junit.Assert.*;
import org.junit.Test;
import java.util.*;

public class DataProcessorCljTest {
   @Test
   public void processWithTotalsAndSubTotals() throws Exception {
      assertEquals(2, DataProcessor.process(createRawData()).size());
   }

   private List<List<String>> createRawData() {
      List<List<String>> data = new ArrayList<List<String>>();
      data.add(new ArrayList<String>(Arrays.asList("2011-11-01", "Temperature", "19.2")));
      data.add(new ArrayList<String>(Arrays.asList("2011-11-01", "Pressure", "1.1")));
      return data;
   }
}

And here is the Clojure code (src/main/clojure/com/foo/weather/data-processor.clj):

(ns com.foo.weather.DataProcessor
  (:gen-class
    :methods [#^{:static true} [process [java.util.List] java.util.List]]))

(defn process [raw-data]
  (java.util.ArrayList. []))

I've added the following to my pom.xml to build the Clojure code:

<project>
   <!-- lots of stuff omitted -->
   <build>
      <plugins>
         <!-- ... -->
         <plugin>
            <groupId>com.theoryinpractise</groupId>
            <artifactId>clojure-maven-plugin</artifactId>
            <version>1.3.6</version>
            <executions>
               <execution>
                 <id>compile</id>
                 <phase>compile</phase>
                 <goals>
                   <goal>compile</goal>
                 </goals>
               </execution>
            </executions>
         </plugin>
      </plugins>
   </build>
   <repositories>
      <!-- ... -->
      <repository>
         <id>clojure-releases</id>
         <url>http://build.clojure.org/releases</url>
       </repository>
   </repositories>
   <dependencies>
      <!-- ... -->
      <dependency>
         <groupId>org.clojure</groupId>
         <artifactId>clojure</artifactId>
         <version>1.2.1</version>
       </dependency>
   </dependencies>
</project>

However, when trying to run my unit test, the compiler complains "cannot find symbol variable DataProcessor", so it seems that my Clojure code is not being compiled properly.

One thing that I've noticed is my src/main/clojure directory doesn't seem to be treated like a source directory in my IDE (IntelliJ). I right-click on src/main/clojure in the project view and choose "Mark directory as > Source root", but after reimporting Maven dependencies (i.e. "Update dependencies" in Eclipse), the directory is no longer marked as a source root.

This leads me to believe that my problem is in my Maven configuration.

Can anyone help?

1
  • Another option for Java + Clojure projects using Maven is Zi Commented Oct 10, 2012 at 14:41

1 Answer 1

2

I use the following in my pom.xml which seems to work:

        <plugin>
            <groupId>com.theoryinpractise</groupId>
            <artifactId>clojure-maven-plugin</artifactId>
            <version>1.3.8</version>

            <executions>
                <!-- ... -->
                <execution>
                    <id>test-clojure</id>
                    <phase>test</phase>
                    <goals>
                        <goal>test</goal>
                    </goals>
                </execution>
            </executions>

            <configuration>
                <sourceDirectories>
                    <sourceDirectory>src/main/clojure</sourceDirectory>
                </sourceDirectories>
                <testSourceDirectories>
                    <testSourceDirectory>src/test/clojure</testSourceDirectory>
                </testSourceDirectories>
            </configuration>
        </plugin>

Also, I've found that Clojure works fine if you include the Clojure source files in a resource directory (you'll obviously need to load them from the Java code of course).

You might also find this question helpful: Calling clojure from java

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

1 Comment

This does not seem to work for me; my JUnit test still doesn't see the Clojure-generated class. The Calling clojure from java was in fact my starting point for figuring out how to do this. :)

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.