【问题标题】:Ivy dependency as provided提供的 Ivy 依赖项
【发布时间】:2016-10-16 21:02:49
【问题描述】:

问题:我需要在 Eclipse 类路径上有一个不应部署到 Tomcat 的库。 (在 maven 项目中,它将提供范围)

说明:

我已经设置了一个具有一些 Ivy 依赖项的项目,并且必须将配置外部化为 JNI(邮件/会话)才能做到这一点,我必须将 mail-1.4.7.jar 放在 Tomcat lib 文件夹中。

问题是我有一个依赖项将javax.mail-1.5.2.jar 添加到我的类路径中,所以我将其更改为:

<dependency org="org.apache.logging.log4j" name="log4j-core" rev="2.2">
    <exclude org="com.sun.mail" name="javax.mail"/>
</dependency>

现在的问题是我的项目由于缺少javax.mail.MessagingException等邮件类而中断(编译错误)

所以我必须添加邮件依赖项,但仅限于 Eclipse。我已经尝试了一些配置,如 here 从我从 Maven 行为中了解到的,但无济于事。

仅在项目中保留邮件依赖项会破坏 Tomcat,将其保留在 tomcat 和项目上都会破坏项目。当我从我的项目库文件夹(WEB-INF\lib)中手动删除它时,部署项目后,它可以正常工作。

底线(部署后):

tomcatFolder                    
  |_lib
  |   |_...
  |   |_mail-1.4.7.jar
  |   |_...
  |_webapps
        |_myproject
             |_WEB-INF
                  |_lib
                     |_...
                     |_javax.mail-1.5.2.jar //need to remove it at deploy time only
                     |_...

现在无法将其更改为 maven。但它正在处理中:)

【问题讨论】:

    标签: java eclipse ivy


    【解决方案1】:

    这确实是这个问题的重复:

    但是.. 从您的问题来看,我怀疑您没有使用常春藤配置映射。这是不幸的,因为这是 ivy 用来在逻辑上将依赖项分组到功能组中的机制,类似于 Maven 维护范围的方式。以下帖子试图弥合这种理解

    此外,您还使用 Eclipse,这意味着除非您使用 ivy plugin,否则您实际上拥有两种构建机制。 (常春藤和日食)。我建议先修复您的 ANT 构建,然后再看看如何维护 Eclipse 类路径。

    示例

    第一部分描述如何在 ivy 文件中声明和使用配置,第二部分解释如何在构建逻辑中使用 ivy ANT 任务。

    ivy.xml

    您应该始终声明 ivy 配置并使用它们来控制您的类路径。在我的构建中,我总是至少有三个:编译、运行时和测试。请注意 extends 属性是如何用于创建配置之间的关系的,因为运行时还应该包含编译依赖项。

    为提供的范围 jar 添加一个额外的很容易。简单的单机配置:

    <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"/>
            <conf name="provided" description="Needed for compile, but will be present on the target platform."/>
        </configurations>
    
        <dependencies>
            <!-- compile dependencies -->
            <dependency org="org.slf4j" name="slf4j-api" rev="1.7.5" conf="compile->default"/>
    
            <!-- runtime dependencies -->
            <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.5" conf="runtime->default"/>
    
            <!-- test dependencies -->
            <dependency org="junit" name="junit" rev="4.11" conf="test->default"/>
    
            <!-- provided dependencies -->
            <dependency org="org.apache.tomcat" name="servlet-api" rev="6.0.16" conf="provided->master"/>
        </dependencies>
    
    </ivy-module>
    

    配置映射让事情变得特别。简单的解释是,当从 Maven 存储库中拉取时,它们分为两种基本类型:

    • conf="local_configuration->default"
    • conf="local_configuration->master"

    第一种方法包括远程模块及其所有依赖项。第二种方法包括远程模块和 exclude 它的依赖项。这意味着您不需要以下排除技巧:

    <dependency org="org.apache.logging.log4j" name="log4j-core" rev="2.2">
        <exclude org="com.sun.mail" name="javax.mail"/>
    </dependency>
    

    如果您想要的只是 log4j-core jar,您只需使用以下内容:

    <dependency org="org.apache.logging.log4j" name="log4j-core" rev="2.2" conf="provided->master"/>
    

    补充说明:

    • 在 ivy 映射到远程“默认”配置时,只会拉下您需要的 jar。它将排除可选依赖项和其他内容,例如 javadocs。
    • 当模块作者的依赖关系错误时,有时需要“排除”。

    build.xml

    解析目标将下拉依赖项,生成报告并创建编译和测试类路径。注意使用配置来确定应该使用哪些 jar 分组:

    <target name="resolve" description="Use ivy to resolve classpaths">
        <ivy:resolve/>
    
        <ivy:report todir='${build.dir}/ivy-reports' graph='false' xml='false'/>
    
        <ivy:cachepath pathid="compile.path" conf="compile,provided"/>
        <ivy:cachepath pathid="test.path"    conf="test,provided"/>
    </target>
    

    编译目标会照常使用这些类路径引用:

    <target name="compile" depends="resolve,resources" description="Compile code">
        <mkdir dir="${build.dir}/classes"/>
        <javac srcdir="${src.dir}" destdir="${build.dir}/classes" includeantruntime="false" debug="true" classpathref="compile.path"/>
    </target>
    
    <target name="compile-tests" depends="compile" description="Compile tests">
        <mkdir dir="${build.dir}/test-classes"/>
        <javac srcdir="${test.src.dir}" destdir="${build.dir}/test-classes" includeantruntime="false" debug="true">
            <classpath>
                <path refid="test.path"/>
                <pathelement path="${build.dir}/classes"/>
            </classpath>
        </javac>
    </target>
    

    以及测试目标:

    <target name="test" depends="compile-tests" description="Run unit tests">
        <mkdir dir="${build.dir}/test-reports"/>
        <junit printsummary="yes" haltonfailure="yes">
            <classpath>
                <path refid="test.path"/>
                <pathelement path="${build.dir}/classes"/>
                <pathelement path="${build.dir}/test-classes"/>
            </classpath>
            <formatter type="xml"/>
            <batchtest fork="yes" todir="${build.dir}/test-reports">
                <fileset dir="${test.src.dir}">
                    <include name="**/*Test*.java"/>
                    <exclude name="**/AllTests.java"/>
                </fileset>
            </batchtest>
        </junit>
    </target>
    

    最后,ivy 检索任务用于构建 war 文件。仅使用“运行时”配置 jar:

    <target name="package" depends="test" description="Create the WAR file">
        <ivy:retrieve pattern="${build.dir}/lib/[artifact].[ext]" conf="runtime"/>
    
        <war destfile="${war.file}" webxml="${resources.dir}/web.xml">
            <fileset dir="${resources.dir}" excludes="web.xml"/>
            <lib dir="${build.dir}/lib"/>
        </war>
    </target>
    

    总之,cachepath ivy 任务用于根据 ivy 配置创建类路径引用,retrieve 任务用于组装 war 文件。

    【讨论】:

    • 这是一个非常好的解释。谢谢你。我会在星期一回去工作的时候试试!!真的很感激!!再次感谢您。
    猜你喜欢
    • 2015-07-11
    • 2015-11-05
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 2019-03-17
    相关资源
    最近更新 更多