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?
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
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.
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:
AI
as a Java interface in your Java code reify
The advantage is this approach is that everything will work smoothly, in particular:
clojure.jar
as a dependency.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.