【问题标题】:Error in classpath generation from default-template ant从默认模板 ant 生成类路径时出错
【发布时间】:2012-07-12 17:33:39
【问题描述】:

我正在尝试根据我的项目中指定的 ivy 依赖项在我的 Java 项目中使用默认模板来生成启动脚本。我面临的问题是,常春藤依赖项被拾取并放入类路径中,但主项目 jar 未包含在类路径中。(这在尝试运行脚本时给出类未找到异常)进一步调查和其他脚本对比发现有一行as。

export RUNTIME_CLASSPATH=""

在我生成的脚本中。这应该有我的项目 jar 的路径,但没有被填充(例如:export RUNTIME_CLASSPATH="$(dirname $0)/../lib/myproject.jar:"

我们在脚本中具体在哪里指定引用自身的项目(调用项目)? 我查看了所有其他文件,包括构建属性、常春藤、常春藤设置,但均无济于事。 如果有人能帮我找到我缺少的东西,那就太好了。

【问题讨论】:

    标签: java ant ivy


    【解决方案1】:

    ANT 没有任何标准功能来生成特定于操作系统的启动脚本。你可以做的是生成一个executable jar,它可以通过运行java来启动,如下所示:

    java -jar demo.jar
    

    可执行 jar 的关键特性是它的清单指定了主类和类路径:

    Manifest-Version: 1.0
    Ant-Version: Apache Ant 1.8.3
    Created-By: 1.6.0_20-b20 (Sun Microsystems Inc.)
    Main-Class: org.demo.App
    Class-Path: lib/slf4j-api-1.6.4.jar lib/slf4j-simple-1.6.4.jar
    

    以下 ANT 项目演示了 ivy 如何帮助创建可执行 jars

    示例

    |-- build.xml
    |-- ivy.xml
    `-- src
        |-- main
        |   `-- java
        |       `-- org
        |           `-- demo
        |               `-- App.java
        `-- test
            `-- java
                `-- org
                    `-- demo
                        `-- AppTest.java
    

    运行构建

    ant clean build
    

    执行程序

    java -jar build/dist/demo.jar
    

    jar 被打包以使用位于相对“lib”子目录中的依赖项

    build/dist/demo.jar
    build/dist/lib/slf4j-api-1.6.4.jar
    build/dist/lib/slf4j-simple-1.6.4.jar
    

    ivy.xml

    <ivy-module version="2.0">
        <info organisation="com.myspotontheweb" module="demo"/>
    
        <configurations>
            <conf name="compile" description="Required to compile application"/>
            <conf name="runtime" description="Additional run-time dependencies" extends="compile"/>
            <conf name="test"    description="Required for test only" extends="runtime"/>
        </configurations>
    
        <dependencies>
            <!-- compile dependencies -->
            <dependency org="org.slf4j" name="slf4j-api" rev="1.6.4" conf="compile->default"/>
    
            <!-- runtime dependencies -->
            <dependency org="org.slf4j" name="slf4j-simple" rev="1.6.4" conf="runtime->default"/>
    
            <!-- test dependencies -->
            <dependency org="junit" name="junit" rev="4.10" conf="test->default"/>
        </dependencies>
    
    </ivy-module>
    

    build.xml

    <project name="demo" default="build" xmlns:ivy="antlib:org.apache.ivy.ant">
    
        <!--
        ================
        Build properties
        ================
        -->
        <property name="src.dir"          location="src/main/java"/>
        <property name="test.src.dir"     location="src/test/java"/>
        <property name="build.dir"        location="build"/>
        <property name="classes.dir"      location="${build.dir}/classes"/>
        <property name="test.classes.dir" location="${build.dir}/test-classes"/>
        <property name="ivy.reports.dir"  location="${build.dir}/ivy-reports"/>
        <property name="test.reports.dir" location="${build.dir}/test-reports"/>
        <property name="dist.dir"         location="${build.dir}/dist"/>
    
        <property name="jar.main.class" value="org.demo.App"/>
        <property name="jar.file"       value="${dist.dir}/${ant.project.name}.jar"/>
    
        <!--
        ===========
        Build setup
        ===========
        -->
        <target name="init">
            <ivy:resolve/>
    
            <ivy:report todir='${ivy.reports.dir}' graph='false' xml='false'/>
    
            <ivy:cachepath pathid="compile.path" conf="compile"/>
            <ivy:cachepath pathid="runtime.path" conf="runtime"/>
            <ivy:cachepath pathid="test.path"    conf="test"/>
        </target>
    
        <!--
        ===============
        Compile targets
        ===============
        -->
        <target name="compile" depends="init">
            <mkdir dir="${classes.dir}"/>
            <javac srcdir="${src.dir}" destdir="${classes.dir}" includeantruntime="false" debug="true" classpathref="compile.path"/>
        </target>
    
        <target name="compile-tests" depends="compile">
            <mkdir dir="${test.classes.dir}"/>
            <javac srcdir="${test.src.dir}" destdir="${test.classes.dir}" includeantruntime="false" debug="true">
                <classpath>
                    <path refid="test.path"/>
                    <pathelement path="${classes.dir}"/>
                </classpath>
            </javac>
        </target>
    
        <!--
        ============
        Test targets
        ============
        -->
        <target name="test" depends="compile-tests">
            <mkdir dir="${test.reports.dir}"/>
            <junit printsummary="yes" haltonfailure="yes">
                <classpath>
                    <path refid="test.path"/>
                    <pathelement path="${classes.dir}"/>
                    <pathelement path="${test.classes.dir}"/>
                </classpath>
                <formatter type="xml"/>
                <batchtest fork="yes" todir="${test.reports.dir}">
                    <fileset dir="${test.src.dir}">
                        <include name="**/*Test*.java"/>
                        <exclude name="**/AllTests.java"/>
                    </fileset>
                </batchtest>
            </junit>
        </target>
    
        <!--
        =====================
        Build and run targets
        =====================
        -->
        <target name="build" depends="test">
            <ivy:retrieve pattern="${dist.dir}/lib/[artifact]-[revision](-[classifier]).[ext]" conf="runtime"/>
    
            <manifestclasspath property="jar.classpath" jarfile="${jar.file}">
                <classpath>
                    <fileset dir="${dist.dir}/lib" includes="*.jar"/>
                </classpath>
            </manifestclasspath>
    
            <jar destfile="${jar.file}" basedir="${classes.dir}">
                <manifest>
                    <attribute name="Main-Class" value="${jar.main.class}" />
                    <attribute name="Class-Path" value="${jar.classpath}" />
                </manifest>
            </jar>
        </target>
    
        <target name="run" depends="build">
            <java jar="${jar.file}" fork="true"/>
        </target>
    
        <!--
        =============
        Clean targets
        =============
        -->
        <target name="clean">
            <delete dir="${build.dir}"/>
        </target>
    
        <target name="clean-all" depends="clean">
            <ivy:cleancache/>
        </target>
    
    </project>
    

    【讨论】:

    • 谢谢马克,使用早期版本的 ant 构建项目也解决了这个问题..(在我的情况下为 1.2)他们以某种方式在新版本中停止了这个..
    • ANT 1.2 于 2003 年发布......我不熟悉那个版本或你描述的功能。
    猜你喜欢
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 2021-04-09
    • 2020-12-01
    • 2022-10-17
    • 2015-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多