在Eclipse之外运行P2 Ant任务

11

我在Eclipse中成功运行了Ant脚本。以下是其中的一部分:

<p2.composite.repository failOnExists="true">
            <repository location="file:/${basedir}/compRepo" name="Repository description goes here" />
            <add>
                <repository location="http://url/Eclipse/repo/Galileo-3.5.1/" />
                <repository location="http://another-url/Java/repo/4.0/" />
                <repository location="${diag.location}" />
            </add>
        </p2.composite.repository>

但是我希望Hudson CI服务器能够运行它,但是,无论我放了多少个jar文件到ANT_HOME/lib中,我都无法在简单的命令行ant中运行这个任务…… 我被卡在了这个错误:

C:\workspaces\workspace\project\junit.script\createCompRepo.xml:10: Problem: failed to create task or type p2.composite.repository
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any <presetdef>/<macrodef> declarations have taken place.

p2 Ant任务定义在哪里?有没有办法在Eclipse之外运行它们?

谢谢你的帮助!Anthony

我已经更新了我的答案,以反映您所发现的内容。请注意:Andrew Niefer(PDE / Build,p2和Equinox Framework上的Eclipse提交者)发表了一条有趣的评论,您可能想要阅读(我也在我的答案中包含了它)。 - VonC
4个回答

13

通过阅读这个主题P2 Publisher文档,应该在org.eclipse.equinox.launcher_*.jar中找到。

以下是一个P2任务的示例(这里不是ant任务),仅涉及-jar参数:

java -jar <targetProductFolder>/plugins/org.eclipse.equinox.launcher_*.jar
 -application org.eclipse.equinox.p2.publisher.UpdateSitePublisher
 -metadataRepository file:/<some location>/repository
 -artifactRepository file:/<some location>/repository
 -source /<location with a site.xml>
 -configs gtk.linux.x86
 -compress 
 -publishArtifacts

这里描述了P2 Ant任务,并在Eclipse帮助文档中有更详细的介绍。


问题发起人Anthony43 在评论中补充道:

我只是想使用p2 taskdefs运行带有ant目标的程序,而不是在Eclipse中运行。
我发现应该使用antRunner,使用以下命令行:

./eclipse -vm /opt/sun-java2-6.0/bin/java -nosplash \
-data ${java.io.tmpdir}/workspace -consolelog       \
-application org.eclipse.ant.core.antRunner         \
-f /path/to/scripts/partialMirrorFromRepo.xml 

然而,Eclipse PDE/Build、p2 和 Equinox Framework 的社区贡献者 Andrew Niefer 指出:

p2 任务需要在 OSGi 环境中运行,不能在普通的 Ant 运行中工作
这就是为什么需要使用 org.eclipse.ant.core.antRunner 应用程序。
使用 "java -jar launcher.jar" 开始只是调用 Eclipse 可执行文件的另一种方法。


martin jakubik 提到:

我希望看到一个可以复制和粘贴并将所有内容组合在一起的命令。
我使用的是:

java -jar <eclipse-install-directory>\eclipse\plugins\org.eclipse.equinox.launcher_*.jar -application org.eclipse.ant.core.antRunner. 
请注意,我无法弄清楚 <targetProductFolder> 是什么,所以我使用了 <eclipse-install...>

请参阅 http://aniefer.blogspot.com/2009/08/versioning-p2-slides-from-eclipsecon.html。 - VonC
嗨,好答案,最终对我有用。阅读链接页面时,我学到了很多东西。但我希望看到一个可以剪切和粘贴并将所有内容组合在一起的命令。我使用的是java -jar <eclipse-install-directory>\eclipse\plugins\org.eclipse.equinox.launcher_*.jar -application org.eclipse.ant.core.antRunner。请注意,我无法弄清楚<targetProductFolder>是什么,所以我使用了<eclipse-install...>。如果您能将此添加到您的答案中,我会投赞成票。 - martin jakubik
@martinjakubik:我已经更新了答案,加上了你的命令行。 - VonC
我仍然没有看到一个完整的答案,可以在我的ant脚本中使用。我认为这是关键,因为如果我不关心从另一个ant任务启动它,我可以只使用上面的java命令行解决方案。@Jarek的macrodef解决方案很好,但我想看到一个完整的示例,以便我知道要引用哪个构建文件 - 一些Eclipse插件中的构建文件,还是当前构建文件(我的),假设antrunner找到了Eclipse构建文件。 - Rhubarb
@Rhubarb 这个问题最好单独提出来,同时附上一个链接指向这个答案以便解释背景。 - VonC
显示剩余3条评论

2
我为此创建了一个小型的Ant宏。
<path id="equinox.launcher.path">
    <fileset dir="${eclipse.home}/plugins">
        <include name="org.eclipse.equinox.launcher_*.jar" />
    </fileset>
</path>

<macrodef name="antRunner">
    <!-- Ant script location -->
    <attribute name="antFile" />
    <!-- the arguments for the script that is executed -->
    <attribute name="args" default=""/>
    <sequential>
        <java 
            classname="org.eclipse.equinox.launcher.Main" 
            fork="true" 
            failonerror="true">

            <arg line="-application org.eclipse.ant.core.antRunner" />
            <arg line="-f @{antFile}" />
            <arg line="@{args}"/>
            <classpath refid="equinox.launcher.path" />
        </java> 
    </sequential>
</macrodef>

另外加一点,展示如何在Ant脚本内部执行,但我不明白@antFile的目的。我们是否需要在Eclipse中指定Ant文件,还是antrunner会为我找到它?我该如何知道常见任务的Ant文件在哪里找到? - Rhubarb

1

为了完整地展示Jarek Przygódzki的例子,这是我的解决方案,使用他的ant文件。我不太熟悉使用ant,所以可能有优化的潜力。这种方法在没有GUI的服务器上使用headless,尽管如此,我仍然需要安装eclipse。使用apt-get安装失败了,所以最好手动安装(下载和解压缩)。

  1. 第一个ant文件组装名称、版本等信息...
  2. 第二个ant文件从第一个ant文件中调用,并创建复合存储库。

第一个ant文件:

<project name="project">

<!-- ....do some other stuff...-->

<target name="p2.composite.add">

<!--Call macro for child repo-->
 <antRunner
    name="${site.composite.name}"
    location="${composite.repository.directory}"
    child="${child.repository}"
/>  

<!--Call macro for main repo-->
<antRunner
    name="${main.site.composite.name}"
    location="${main.composite.repository.directory}"
    child="${majorMinorVersion}"
/> 

</target>

<!--Eclipse installation path-->
<path id="equinox.launcher.path">
    <fileset dir="/usr/share/eclipse/plugins">
        <include name="org.eclipse.equinox.launcher_1.3.201.v20161025-1711.jar" />
    </fileset>
</path>

<macrodef name="antRunner">

    <attribute name="name"/>    
    <attribute name="location"/>
    <attribute name="child"/>

    <sequential>

        <java 
            classname="org.eclipse.equinox.launcher.Main" 
            fork="true" 
            failonerror="true">

            <arg line="-application org.eclipse.ant.core.antRunner" />
            <arg line="-f addCompositeInternal.ant run" />
            <arg line="-Dcomposite.name=@{name}"/>
            <arg line="-Dcomposite.location=@{location}"/>
            <arg line="-Dcomposite.child=@{child}"/>
            <classpath refid="equinox.launcher.path" />
        </java> 
    </sequential>
</macrodef>

</project>   

第二个Ant文件名为addCompositeInternal.ant。
<project name="composite">
<target name="run">
            <add.composite.repository.internal
                composite.repository.location="${composite.location}"
                composite.repository.name="${composite.name}"
                composite.repository.child="${composite.child}"
            />
</target>      

<!-- = = = = = = = = = = = = = = = = =
      macrodef: add.composite.repository.internal          
     = = = = = = = = = = = = = = = = = -->
<macrodef name="add.composite.repository.internal">
    <attribute name="composite.repository.location" />
    <attribute name="composite.repository.name" />
    <attribute name="composite.repository.child" />
    <sequential>

        <echo message=" " />
        <echo message="Composite repository       : @{composite.repository.location}" />
        <echo message="Composite name             : @{composite.repository.name}" />
        <echo message="Adding child repository    : @{composite.repository.child}" />

        <p2.composite.repository>
            <repository compressed="false" location="@{composite.repository.location}" name="@{composite.repository.name}" />
            <add>
                <repository location="@{composite.repository.child}" />
            </add>
        </p2.composite.repository>

        <echo file="@{composite.repository.location}/p2.index">version=1
   metadata.repository.factory.order=compositeContent.xml,\!
   artifact.repository.factory.order=compositeArtifacts.xml,\!
   </echo>

    </sequential>
</macrodef>

</project>

1
所有的p2任务都需要Eclipse运行环境(正如上面提到的Eclipse帮助中明确说明的那样),所以您一定需要使用Eclipse。
唯一摆脱它的方法是分析Eclipse代码,提取必要的内容,并创建自己的构建系统。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接