2013-01-01 60 views
3

我創建了一個示例多語種程序。我有一個傳感器和一個機器人用java和AI在clojure中實現。我無法連接行家正確java在maven和eclipse中與clojure混合使用

--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?

回答

1

我認爲:gen-class通常是一種代碼異味,正如試圖從Java代碼實例化這樣一個類與new AI()

下面是可以解決循環依賴的這個問題的另一種方法:

  1. 定義AI在你的Java代碼的Java接口
  2. 寫的Clojure函數來創建符合使用reify接口實例
  3. 動態調用Java的Clojure函數(例如b)使用this blog post概述的技術
  4. 您現在有AI接口的實例,你可以使用,但是你在Java中

的優點是這種方法一樣的是,一切都將順利工作,特別是:

  • Java的代碼庫可以被編譯的獨立Clojure的代碼
  • Clojure的代碼庫可以訪問所有定義的Java類和接口
  • 你d不需要任何特殊的IDE/Maven配置。事實上,你可以把它看作是一個普通的Java應用程序,它恰好包含clojure.jar作爲依賴項。
2

您需要更改項目中源代碼的佈局。 Clojure的Maven插件需要,是Clojure的代碼去單獨的目錄,所以你應該有以下佈局:

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

更多詳情,請following article

+0

這不是問題。我將clojure-maven-plugin源文件設置爲src/main/java。但即使按照你的建議改變了結構後,我仍然有同樣的錯誤。當clojure:編譯完成後,沒有找到DistanceSensor.class。如果java編譯完成後,沒有找到AI.class – piotrek

+0

對不起,錯誤地閱讀你的問題。請參閱我對Sergiu的回答的評論 –

1

找到你的Java代碼和Clojure的代碼之間的相互依賴。無論您首先編譯哪種類型的類型,都會出現錯誤。

由於它不是實際的循環依賴關係,所以仍然可以通過將Java編譯部分分爲兩部分來解決此問題。

首先,編譯DistanceSensor,它不依賴於其他任何東西。

二,編譯AI,依賴於DistanceSensor

最後,編譯Robot這取決於AI

分兩步分裂Java編譯,你需要配置maven-compiler-plugin的默認執行,使其excludesRobotclujure:compile目標排除DistanceSensor後再添執行。您可能不得不錯誤地使用phases來正確命令三次執行。

+0

也許可以在'generate-sources'階段首先使用maven-antrun-plugin編譯DistanceSensor,然後再編譯其餘部分。 –

+0

另一種可能的解決方案是將項目拆分成子模塊,並使用相應的執行順序。在Leiningen中,可以使用鉤子來執行其他任務之前的某些任務,而且我不確定Maven中是否存在這種可能性(儘管有Invoker插件可以在階段 –

+0

之前和/或之後運行一些腳本,但隨後我會還必須排除所有依賴於Robot的類,更重要的是,可能會有很多層的java調用clojure,反之亦然。我恐怕沒有必要使用自動構建系統,因爲所有事情都必須手動完成。 java可以編譯類,即使它們之間存在循環也不能用java和clojure做同樣的事情 – piotrek