java在maven和eclipse中混合了clojure

时间:2013-01-01 12:55:13

标签: java eclipse maven clojure interop

我创建了一个样本多语言程序。我有一个传感器和一个用java和AI实现的机器人在clojure中实现。我无法正确连接maven

--src/main/java/clojuretest
                          |
                           DistanceSensor.java
                           AI.clj       (uses DistanceSensor)
                           Robot.java   (uses AI)

DistanceSensor.java:

package clojuretest;

public class DistanceSensor {

    public int getValue() {return 5;}
}

AI.clj:

(ns clojuretest.AI
  (:gen-class :methods [[isObstacleAhead [] boolean]]))

(defn -isObstacleAhead [this] (< (.getValue (clojuretest.DistanceSensor.)) 10))

Robot.java:

package clojuretest;

public class Robot {

    public boolean shouldStop() {
        return new AI().isObstacleAhead();
    }
}

我甚至可以手动强制maven编译它: mvn clean clojure:compile产生错误 - 没有DistanceSensor类(但由于某种原因创建了AI.class)。那么 mvn compile看到AI.class并正确编译所有内容并且测试通过。但我能做些什么让mvn clean compile通过?我的pom.xml应该怎么样?还有什么可以让eclipse停止抱怨不存在的AI.class?

3 个答案:

答案 0 :(得分:2)

您需要更改项目中源代码的布局。 Clojure maven插件需要,clojure代码进入单独的目录,所以你应该有以下布局:

 src/
    main/
      java/
        java-code
      clojure/
        clojure code
    test/
      java/
        java tests code
      clojure/
        clojure tests code

您可以在following article

中找到更多详细信息

答案 1 :(得分:1)

Java代码和Clojure代码之间存在相互依赖关系。无论你先编译哪种类,都会出错。

由于它不是一个实际的循环依赖,你仍然可以通过将Java编译部分分成两部分来解决这个问题。

首先,编译DistanceSensor,它不依赖于任何其他内容。

其次,编译AI,这取决于DistanceSensor

最后,编译Robot,这取决于AI

要分两步拆分java编译,您需要配置maven-compiler-plugin的默认执行,使其excludes Robot,并在{{1}之后添加另一个执行}目标,不包括clujure:compile。你可能不得不滥用phases来正确地命令三次执行。

答案 2 :(得分:1)

我认为:gen-class通常是代码气味,就像尝试使用new AI()从Java代码实例化这样的类一样。

这是一种可以解决循环依赖性问题的替代方法:

  1. AI定义为Java代码中的Java接口
  2. 使用reify
  3. 编写Clojure函数以创建符合界面的实例
  4. 从Java动态调用Clojure函数(例如,使用this blog post中概述的技术)
  5. 您现在有了一个可以在Java中使用的AI接口实例
  6. 优点是这种方法是一切都能顺利进行,特别是:

    • 可以独立于Clojure代码
    • 编译Java代码库
    • Clojure代码库可以访问所有已定义的Java类和接口
    • 您不需要任何特殊的IDE / Maven配置。实际上,您可以将其视为仅包含clojure.jar作为依赖项的常规Java应用程序。