Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java在maven和eclipse中与clojure混合_Java_Eclipse_Maven_Clojure_Interop - Fatal编程技术网

java在maven和eclipse中与clojure混合

java在maven和eclipse中与clojure混合,java,eclipse,maven,clojure,interop,Java,Eclipse,Maven,Clojure,Interop,我创建了一个多语言编程示例。我用java实现了一个传感器和一个机器人,用clojure实现了AI。我无法正确连接maven --src/main/java/clojuretest | DistanceSensor.java AI.clj(使用距离传感器) java(使用AI) DistanceSensor.java: package clojuretest; 公共类距离传感器{ public int getValue(){return 5;} } AI.clj: (ns clojuretes

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

--src/main/java/clojuretest
|
DistanceSensor.java
AI.clj(使用距离传感器)
java(使用AI)
DistanceSensor.java:

package clojuretest;
公共类距离传感器{
public int getValue(){return 5;}
}
AI.clj:

(ns clojuretest.AI
(:gen类:方法[[isObstacleAhead[]boolean]]))
(defn-isObstacleAhead[此](<(.getValue(clojuretest.DistanceSensor.)10))
Robot.java:

package clojuretest;
公共类机器人{
公共布尔值shouldStop(){
返回新AI().isObstacleAhead();
}
}
我甚至可以手动强制maven编译它:
mvn clean clojure:compile
生成错误-无距离传感器类(但由于某些原因创建AI.class)。那么
mvn compile
查看AI.class并正确编译所有内容,测试通过。但是我该怎么做才能使
mvn干净编译
通过呢?我的pom.xml应该是什么样子?还有,我该怎么做才能让eclipse停止抱怨不存在的AI.class?

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

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

您可以在

中找到更多详细信息,Java代码和Clojure代码之间存在相互依赖关系。无论您首先编译哪种类型的类,都会出现错误

因为它不是一个实际的循环依赖项,所以您仍然可以通过将Java编译部分一分为二来解决这个问题

首先,编译距离传感器,它不依赖于其他任何东西

其次,编译
AI
,这取决于
距离传感器

最后,编译依赖于
AI
Robot


要将java编译分为两个步骤,您需要配置
maven编译器插件的默认执行
,以便它
Robot
,并在
clujure:compile
目标之后添加另一个执行,该目标排除
DistanceSensor
。您可能必须误用来正确地排列三次执行。

我认为
:gen类
通常是一种代码气味,就像试图用
新AI()从Java代码实例化这样一个类一样

这里有一种替代方法可以解决这个循环依赖性问题:

  • AI
    定义为Java代码中的Java接口
  • 编写Clojure函数,使用
    reify
  • 从Java动态调用Clojure函数(例如,使用中概述的技术)
  • 现在您有了一个AI接口的实例,可以在Java中随意使用
  • 这种方法的优点是一切都会顺利进行,特别是:

    • Java代码库可以独立于Clojure代码进行编译
    • Clojure代码库可以访问所有定义的Java类和接口
    • 您不需要任何特殊的IDE/Maven配置。事实上,您可以将它视为一个普通的Java应用程序,碰巧包含
      clojure.jar
      作为依赖项

    这不是问题所在。我将clojure maven插件源代码设置为src/main/java。但即使按照你的建议改变了结构,我仍然有同样的错误。首先完成clojure:compile时,未找到DistanceSensor.class。如果java编译是先完成的,那么找不到AI.class对不起,请错误地阅读您的问题。请看我对Sergiu回答的评论。也许可以使用maven antrun插件在
    生成源代码
    阶段首先编译DistanceSensor,然后编译其余部分。另一个可能的解决方案是将项目拆分为子模块,并使用它提供相应的执行顺序。在Leiningen中,可以先使用钩子执行一些任务,而在Maven中,我不确定这种可能性(虽然有一个调用器插件可以在阶段之前和/或之后运行一些脚本,但我还必须排除所有依赖于Robot的类。此外,可能有很多层java调用clojure,反之亦然。我担心使用自动构建系统没有意义,因为所有事情都必须手动完成.java可以编译类,即使它们之间存在循环。lein不能以某种方式对java和clojure执行同样的操作吗?事实上,将项目拆分为模块是更好的方法。如果您只是为了混合语言而混合语言,那么您就没有做任何有用的事情。但是,如果您确实需要/想要编写不同部分的他用不同的语言编写程序(为每项工作使用最好的工具),然后您应该正确地考虑项目应该如何组织,并且应该可以有独立的层,而层之间没有相互依赖关系。一个选项是将接口与实际实现分离,这样接口就不依赖于上层,而实际实现只依赖于其他接口。通过这种方式,相互依赖关系是隐藏的,并且只有在编译所有类时才会在运行时出现。