Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.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
在Eclipse插件中加载Clojure代码_Eclipse_Clojure - Fatal编程技术网

在Eclipse插件中加载Clojure代码

在Eclipse插件中加载Clojure代码,eclipse,clojure,Eclipse,Clojure,我有这种问题。我在*.clj文件中有Eclipse插件(表示为A)中包含的Clojure代码。我不想要AOT编译。但是,我需要从另一个clojure插件B加载clojure代码。当B依赖于A时,这是可能的。clojure可以轻松访问类路径,并且一切正常。但是我希望插件A作为B的扩展插件插入。但是有一个问题,因为我找不到一种方法来加载包含在B中的from*.clj文件中的Clojure文件。我想使用Clojure“load”函数,它可以从类路径加载*.clj文件,但是当我明确地像这样启动插件 (

我有这种问题。我在*.clj文件中有Eclipse插件(表示为A)中包含的Clojure代码。我不想要AOT编译。但是,我需要从另一个clojure插件B加载clojure代码。当B依赖于A时,这是可能的。clojure可以轻松访问类路径,并且一切正常。但是我希望插件A作为B的扩展插件插入。但是有一个问题,因为我找不到一种方法来加载包含在B中的from*.clj文件中的Clojure文件。我想使用Clojure“load”函数,它可以从类路径加载*.clj文件,但是当我明确地像这样启动插件

 (org.eclipse.core.runtime.Platform/getBundle "A")
<extension point="transforms">
  <function namespace="my.nemaspace" fn="my-transform"/>
</extension>
对劳伦特回答的反应

劳伦特,非常感谢你!这很有趣。然而,我认为这个mayby解决了一个比我原来的更难的问题。您描述了如何从java插件调用clojure代码,这非常棒。我需要从clojure插件调用clojure代码,我认为这可能更容易。我想我会创建扩展点并提供类似这样的clojure函数

 (org.eclipse.core.runtime.Platform/getBundle "A")
<extension point="transforms">
  <function namespace="my.nemaspace" fn="my-transform"/>
</extension>


所以我不需要IExecutableExtensionFactory的任何魔力。我可以从clojure代码中读取扩展注册表。我不能做的是加载扩展中指定的函数。这是可行的还是我只是误解了什么?我注意到您正在使用clojure.osgi。这看起来很酷,这个项目有文档吗?

你在类加载器方面遇到的问题是意料之中的:如果你的Eclipse插件/OSGi捆绑包的依赖项是A->B,Clojure jar从B引导,那么从B看不到A的资源是正常的

Eclipse插件的依赖项之间不能有循环,因此类装入器层次结构之间不能有循环

这与使用常规Eclipse机器从A向B编写扩展时所面临的问题相同:插件B将声明一个接口和一个扩展点。然后插件A可以实现接口,并声明扩展点的扩展。最后一部分允许Eclipse框架对捆绑包进行一些操作:它看到A声明了对B的扩展,从而实例化了A中的一个类,实现了B中声明的接口(这是因为A依赖于B),并为B提供了A中的实现实例,这也是可以的,因为它在B中实现了接口

(不确定这是否清楚)

无论如何,回到Clojure编写的插件。
使用Clojure,您没有现成的类加载器提供的这种独立环境,因为所有内容都聚集在一个“Clojure环境”中,该环境位于嵌入Clojure jar的插件的类加载器领域。 因此,一种可能性是,当插件A启动时,从A加载相关的名称空间。然后,它们将在正确的时间加载,并可用于任何其他Clojure代码。 另一种可能性是使用扩展点/扩展机械。Eclipse提供了一种使用“工厂”创建扩展点实例的方法。逆时针方向,我们利用了这个特性,并且有一个通用的工厂类(用java编写,所以没有AOT),它负责从正确的包中加载正确的名称空间

下面是有关如何扩展扩展点的更多详细信息

逆时针方向的示例:
Eclipse框架中已有一个扩展点,用于为控制台内容提供超链接检测器。逆时针扩展此扩展点以添加nrepl超链接。
在java世界中,您必须在扩展中直接声明实现接口IPatternMatchListenerDelegate的某个类。
但是对于CCW,出于可能与您相同的原因,我会不惜一切代价避免AOT,因此我不能在扩展中给出java类名,否则我要么用java编写并编译它,要么用Clojure编写一个
gen类
,然后AOT编译它

相反,CCW利用了plugin.xml的潜在优势:在几乎所有地方,当您必须提供类名时,您可以提供Eclipse框架将调用其
create()
方法的实例来创建所需类的实例

这使我能够编写一个通用类来调用Clojure世界:我只是使用类名来代替我应该编写的类名

摘录自:

请注意,我只是举个例子,逆时针方向的相关代码还没有准备好作为独立库“准备好使用”发布。
但是你仍然应该能够推出自己的解决方案(一旦你把所有的部分都放在头脑中,这就很容易了)

希望有帮助

--
Laurent

我想到了另一个解决方案:在Eclipse中,尽管我在前面的回答中说过,在类加载器之间创建循环依赖关系是可能的

Eclipse人员需要引入这一点,以便某些类型的库(log4j等)可以在OSGi环境中工作(这是Eclipse的基础)

这需要利用
eclipsebuddypolicy
机制()

这很简单:如果您想让插件B看到插件A的所有类和资源,只需将其添加到插件B的
META-INF/MANIFEST.MF
文件中:

Eclipse-BuddyPolicy: dependent
上面的一行表示插件B的类加载器将能够访问其从属类加载器可以访问的内容

我创建了一个名为a和B的插件示例集,其中B有两个命令(在顶部菜单中可见):第一个命令通过调用B中的clojure代码对“hello”硬编码字符串应用文本转换。第二个命令从插件a动态加载新的文本转换,以便在调用