简体   繁体   English

java在maven和eclipse中混合了clojure

[英]java mixed with clojure in maven and eclipse

i created a sample polyglot program. 我创建了一个样本多语言程序。 i have a sensor and a robot implemented in java and AI implemented in clojure. 我有一个传感器和一个用java和AI实现的机器人在clojure中实现。 and i can't connect maven properly 我无法正确连接maven

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

DistanceSensor.java: DistanceSensor.java:

package clojuretest;

public class DistanceSensor {

    public int getValue() {return 5;}
}

AI.clj: AI.clj:

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

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

Robot.java: Robot.java:

package clojuretest;

public class Robot {

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

i can even manually force maven to compile it: mvn clean clojure:compile produces error - no DistanceSensor class (but for some reason creates AI.class). 我甚至可以手动强制maven编译它: mvn clean clojure:compile产生错误 - 没有DistanceSensor类(但由于某种原因创建了AI.class)。 so then mvn compile sees AI.class and compiles everything correctly and tests pass. 所以然后mvn compile看到AI.class并正确编译所有内容并测试通过。 but what can i do to make mvn clean compile pass? 但是我能做些什么来使mvn clean compile通过? how should my pom.xml look like? 我的pom.xml应该怎么样? also what can i do to make eclipse stop complaining about non existing AI.class? 还有什么办法可以让eclipse停止抱怨不存在的AI.class?

You need to change layout of source code in your project. 您需要更改项目中源代码的布局。 Clojure maven plugin requires, that clojure code went to separate directory, so you should have following layout: Clojure maven插件需要,clojure代码进入单独的目录,所以你应该有以下布局:

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

More details you can find in following article 您可以在以下文章中找到更多详细信息

You have an inter-dependency between Java code and Clojure code. 您在Java代码和Clojure代码之间存在相互依赖关系。 No matter which type of classes you'll compile first, you'll get an error. 无论你先编译哪种类,都会出错。

Since it's not an actual cyclic dependency, you can still fix this by splitting the Java compilation part in two. 由于它不是一个实际的循环依赖,你仍然可以通过将Java编译部分分成两部分来解决这个问题。

First, compile DistanceSensor , which doesn't depend on anything else. 首先,编译DistanceSensor ,它不依赖于任何其他东西。

Second, compile AI , which depends on DistanceSensor . 其次,编译AI ,这取决于DistanceSensor

Finally, compile Robot which depends on AI . 最后,编译依赖AI Robot

To split the java compilation in two steps, you need to configure the default execution of the maven-compiler-plugin so that it excludes Robot , and add another execution after the clujure:compile goal that excludes DistanceSensor . 要分两步拆分java编译,您需要配置maven-compiler-plugin的默认执行,以便它排除 Robot ,并在clujure:compile目标之后添加另一个执行,该目标排除DistanceSensor You'll probably have to misuse the phases to properly order the three executions. 你可能不得不滥用阶段来正确地命令三个执行。

I think :gen-class is usually a code smell, as is trying to instantiate such a class from Java code with new AI() . 我认为:gen-class通常是代码气味,试图用new AI()从Java代码实例化这样的类。

Here's an alternative approach that can solve this problem of cyclic dependencies: 这是一种可以解决循环依赖性问题的替代方法:

  1. Define AI as a Java interface in your Java code AI定义为Java代码中的Java接口
  2. Write a Clojure function to create an instance conforming to the interface using reify 编写Clojure函数以使用reify创建符合接口的实例
  3. Dynamically invoke the Clojure function from Java (eg using the technique outlined in this blog post ) 从Java动态调用Clojure函数(例如,使用本博文中概述的技术)
  4. You now have an instance of the AI interface that you can use however you like in Java 您现在拥有了一个可以在Java中使用的AI接口实例

The advantage is this approach is that everything will work smoothly, in particular: 这种方法的优点是一切都能顺利进行,特别是:

  • The Java code base can be compiled independently of the Clojure code Java代码库可以独立于Clojure代码进行编译
  • The Clojure code base can access all the defined Java classes and interfaces Clojure代码库可以访问所有已定义的Java类和接口
  • You don't need any special IDE / Maven config. 您不需要任何特殊的IDE / Maven配置。 In fact, you can treat is as just a regular Java app that happens to include clojure.jar as a dependency. 实际上,您可以将其视为一个普通的Java应用程序,恰好包含clojure.jar作为依赖项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM