提供的常春藤依赖
Ivy dependency as provided
问题:我需要在 eclipse 类路径上有一个不应部署到 Tomcat 的库。 (在 Maven 项目中,它将提供范围)
解释:
我已经设置了一个带有一些 Ivy 依赖项的项目并且必须将配置外部化为 JNI (mail/session) 为了做到这一点我必须将 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。根据我从 Maven 行为中了解到的情况,我尝试了一些解释 here 的配置,但无济于事。
仅在项目中保留邮件依赖项会中断 Tomcat,同时在 tomcat 和项目中保留它会中断项目。当我手动将它从我的项目 lib 文件夹 (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。但它正在处理中:)
这确实是这个问题的重复:
- How to copy runtime libraries without the provided ones in IVY
但是.. 从你的问题来看,我怀疑你没有使用 ivy 配置映射。这很不幸,因为这是 ivy 使用的将依赖项逻辑分组为功能分组的机制,类似于 Maven 维护作用域的方式。以下帖子试图弥合这种理解
- How are maven scopes mapped to ivy configurations by ivy
此外,您还在使用 Eclipse,这意味着除非您使用 ivy plugin,否则您实际上拥有两种构建机制。 (常春藤和日食)。我会建议先修复您的 ANT 构建,然后再看看如何维护 Eclipse 类路径。
例子
第一部分描述了如何在 ivy 文件中声明和使用配置,第二部分解释了如何在构建逻辑中使用 ivy ANT 任务。
ivy.xml
您应该始终声明 ivy 配置并使用它们来控制您的类路径。在我的构建中,我总是至少有三个:编译、运行时和测试。请注意 extends 属性如何用于创建配置之间的关系,因为运行时还应包括编译依赖项。
为提供的作用域罐子添加一个额外的罐子很容易。简单单机配置:
<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 中映射到远程 "default" 配置将只拉下您需要的罐子。它将排除可选依赖项和其他内容,如 javadocs。
- 有时 "excludes" 是必要的,因为模块作者弄错了他们的依赖关系。
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 文件。仅使用 "runtime" 配置 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 task is used to create classpath references based on the ivy configurations and the retrieve 任务在组装 war 文件时使用。
问题:我需要在 eclipse 类路径上有一个不应部署到 Tomcat 的库。 (在 Maven 项目中,它将提供范围)
解释:
我已经设置了一个带有一些 Ivy 依赖项的项目并且必须将配置外部化为 JNI (mail/session) 为了做到这一点我必须将 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。根据我从 Maven 行为中了解到的情况,我尝试了一些解释 here 的配置,但无济于事。
仅在项目中保留邮件依赖项会中断 Tomcat,同时在 tomcat 和项目中保留它会中断项目。当我手动将它从我的项目 lib 文件夹 (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。但它正在处理中:)
这确实是这个问题的重复:
- How to copy runtime libraries without the provided ones in IVY
但是.. 从你的问题来看,我怀疑你没有使用 ivy 配置映射。这很不幸,因为这是 ivy 使用的将依赖项逻辑分组为功能分组的机制,类似于 Maven 维护作用域的方式。以下帖子试图弥合这种理解
- How are maven scopes mapped to ivy configurations by ivy
此外,您还在使用 Eclipse,这意味着除非您使用 ivy plugin,否则您实际上拥有两种构建机制。 (常春藤和日食)。我会建议先修复您的 ANT 构建,然后再看看如何维护 Eclipse 类路径。
例子
第一部分描述了如何在 ivy 文件中声明和使用配置,第二部分解释了如何在构建逻辑中使用 ivy ANT 任务。
ivy.xml
您应该始终声明 ivy 配置并使用它们来控制您的类路径。在我的构建中,我总是至少有三个:编译、运行时和测试。请注意 extends 属性如何用于创建配置之间的关系,因为运行时还应包括编译依赖项。
为提供的作用域罐子添加一个额外的罐子很容易。简单单机配置:
<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 中映射到远程 "default" 配置将只拉下您需要的罐子。它将排除可选依赖项和其他内容,如 javadocs。
- 有时 "excludes" 是必要的,因为模块作者弄错了他们的依赖关系。
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 文件。仅使用 "runtime" 配置 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 task is used to create classpath references based on the ivy configurations and the retrieve 任务在组装 war 文件时使用。