java mixed with clojure in maven and eclipse

半城伤御伤魂 提交于 2019-12-10 09:45:56

问题


i created a sample polyglot program. i have a sensor and a robot implemented in java and AI implemented in clojure. and i can't connect maven properly

--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();
    }
}

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). so then mvn compile sees AI.class and compiles everything correctly and tests pass. but what can i do to make mvn clean compile pass? how should my pom.xml look like? also what can i do to make eclipse stop complaining about non existing AI.class?


回答1:


I think :gen-class is usually a code smell, as is trying to instantiate such a class from Java code with new AI().

Here's an alternative approach that can solve this problem of cyclic dependencies:

  1. Define AI as a Java interface in your Java code
  2. Write a Clojure function to create an instance conforming to the interface using reify
  3. Dynamically invoke the Clojure function from Java (e.g. using the technique outlined in this blog post)
  4. You now have an instance of the AI interface that you can use however you like in Java

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
  • The Clojure code base can access all the defined Java classes and interfaces
  • You don't need any special IDE / Maven config. In fact, you can treat is as just a regular Java app that happens to include clojure.jar as a dependency.



回答2:


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:

 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




回答3:


You have an inter-dependency between Java code and Clojure code. 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.

First, compile DistanceSensor, which doesn't depend on anything else.

Second, compile AI, which depends on DistanceSensor.

Finally, compile Robot which depends on AI.

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. You'll probably have to misuse the phases to properly order the three executions.



来源:https://stackoverflow.com/questions/14110657/java-mixed-with-clojure-in-maven-and-eclipse

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!