3

我创建了一个示例多语言程序。我有一个用 java 实现的传感器和一个机器人,以及用 clojure 实现的 AI。我无法正确连接 Maven

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

距离传感器.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))

机器人.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?

4

3 回答 3

2

您需要更改项目中源代码的布局。Clojure maven 插件要求,该 clojure 代码位于单独的目录中,因此您应该具有以下布局:

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

您可以在以下文章中找到更多详细信息

于 2013-01-01T13:51:01.223 回答
1

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

由于它不是实际的循环依赖,您仍然可以通过将 Java 编译部分一分为二来解决此问题。

首先, compile DistanceSensor,它不依赖于其他任何东西。

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

最后,编译Robot依赖于AI.

要将java编译拆分为两步,需要配置默认执行maven-compiler-plugin,使其excludes ,并在exclude 目标Robot之后添加另一个执行。您可能不得不滥用这些阶段来正确排序三个执行。clujure:compileDistanceSensor

于 2013-01-01T18:25:29.433 回答
1

我认为:gen-class通常是代码异味,就像尝试使用new AI().

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

  1. 在 Java 代码中定义AI为 Java 接口
  2. 编写一个 Clojure 函数来创建一个符合接口的实例,使用reify
  3. 从 Java 动态调用 Clojure 函数(例如,使用本博文中概述的技术)
  4. 你现在有了一个 AI 接口的实例,你可以在 Java 中随意使用它

这种方法的优点是一切都会顺利进行,特别是:

  • Java 代码库可以独立于 Clojure 代码进行编译
  • Clojure 代码库可以访问所有已定义的 Java 类和接口
  • 您不需要任何特殊的 IDE / Maven 配置。实际上,您可以将 is 视为恰好包含clojure.jar为依赖项的常规 Java 应用程序。
于 2013-01-02T00:17:24.130 回答