创建适当的 ivy 配置(而不是弄乱 *)
Creating proper ivy configurations (and not messing with *)
我有一个项目,正在被其他项目用作 Ivy 依赖项。它的 dependencies.xml
包含很多依赖项,基本上分为 3 类:
- 在 Eclipse 中编译项目并在嵌入式 运行 中编译项目 Tomcat 以及创建完整的自动一致 WAR 文件
所需的依赖项
- 编译和运行单元测试所需的依赖项
- 通常属于 Tomcat 类路径的依赖项,包括以下内容,并且需要通过 Ant 编译 Web 项目的 JAR
- Servlet API
- JDBC 连接器(它们实际上不随应用程序一起提供)
第三个依赖类别对我来说很重要。如果我不在 javac
类路径中包含 servlet-api.jar
,我将无法编译该项目。但是,如果我将该包包含在 war 类路径中,我就会陷入一种不好的做法,因为服务器 运行 次(主要是 Tomcat,还有 Websphere)包含它们自己的 servlet-api.jar
。
对于 JDBC 连接器,我只需要将它们包含到 Ant 类路径中,以便从 Bamboo 进行 运行ning 单元测试,因为我想对多个数据库重复相同的测试。
当前代码
这是我当前的 dependency.xml 片段:
<configurations>
<conf name="test" visibility="public" extends="compile" />
<conf name="compile" visibility="public" extends="runtime" />
<conf name="runtime" visibility="public" />
<conf name="provided" visibility="public" />
<conf name="junit" visibility="public" />
</configurations>
<!-- Build -->
<dependency org="javax.servlet" name="javax.servlet-api" rev="3.0.1" transitive="false" conf="provided->*" />
<dependency org="javax.servlet.jsp" name="javax.servlet.jsp-api" rev="2.3.1" transitive="false" conf="provided->*" />
<dependency org="javax.el" name="javax.el-api" rev="3.0.0" transitive="false" conf="provided->*" />
<dependency org="mysql" name="mysql-connector-java" rev="5.1.38" transitive="false" conf="provided->*" />
<dependency org="ojdbc" name="ojdbc" rev="14" transitive="false" conf="provided->*" />
<dependency org="org.hsqldb" name="hsqldb" rev="2.3.3" transitive="false" conf="provided->*" />
<dependency org="org.postgresql" name="postgresql" rev="9.4.1207" transitive="false" conf="provided->*" />
<dependency org="com.microsoft" name="sqljdbc" rev="4.1" transitive="false" conf="provided->*" />
<dependency org="org.adrianwalker" name="multiline-string" rev="0.1.2" transitive="false" conf="provided->*" />
<!-- Spring -->
<dependency org="org.springframework" name="spring-core" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-aop" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-beans" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-context" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-context-support" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-expression" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-jdbc" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-orm" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-tx" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-web" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-webmvc" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-test" rev="4.2.4.RELEASE" transitive="false" conf="test->*"/>
<dependency org="org.springframework.plugin" name="spring-plugin-core" rev="1.2.0.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework.plugin" name="spring-plugin-metadata" rev="1.2.0.RELEASE" transitive="false" conf="runtime->*"/>
在上面的例子中,com.adrianwalker#multiline-string
只需要注解解析,不需要
蚂蚁
在我的 main-project
中,我最终通过以下任务检索依赖项
<target name="ivy-retrieve">
<ivy:configure override="true" file="${ivy.install.dir}/ivy-settings.xml" />
<ivy:retrieve sync="true" conf="runtime,junit" type="jar,bundle" pattern="${project.local.lib}/[artifact]-[revision].[ext]" />
<eclipse.refreshLocal depth="infinite" resource="/" if:set="eclipse.running" />
</target>
这将使用我需要的所有依赖项(包括 spring-test
)正确填充我的 WEB-INF/lib
目录,但没有已手动复制到 Tomcat 的 JDBC 连接器类路径
好的...
问题
当我将 main-project
嵌入 derived-project
时出现问题
<dependency org="com.example" name="main-project" rev="${current.version}" transitive="true" conf="runtime->*"/>
和
<target name="ivy-retrieve-eclipse">
<ivy:configure override="true" file="${ivy.install.dir}/ivy-settings.xml" />
<ivy:retrieve sync="true" conf="runtime,junit" type="jar,bundle" pattern="${project.local.lib}/[artifact]-[revision].[ext]" />
<eclipse.refreshLocal depth="infinite" resource="/" if:set="eclipse.running" />
</target>
结果是我仍然下载了所有依赖项。
问题
我只需要告诉 Ivy 为我的 derived-project
下载所有 runtime
和 junit
的依赖项,包括那些 runtime
和 junit
依赖项包含在 main-project
的常春藤档案中。
我该怎么做?我搞砸了什么?
所以我假设您的主要项目正在将其 jar 发布到存储库中是正确的? (使用发布任务?)。
我认为您的问题出在子构建的依赖项声明中的配置映射:
<dependency org="com.example" name="main-project" rev="${current.version}" transitive="true" conf="runtime->*"/>
你说本地构建的 "runtime" 配置映射到主项目模块中列出的 all 配置。这就是您获得所有罐子的原因:
conf="runtime->*"
修复很简单:
conf="runtime"
这是 shorthand 用于:
conf="runtime->runtime"
之前的设置有两个问题:
- 正如@MarkOConnor 强调的那样,我在 child 项目依赖项上使用了
conf="runtime->*"
,它只会将 runtime
重新映射到 all
配置
- parent 和 child 工件的配置不一致
关于第 2 点,我在 parent 项目
上有以下内容
<configurations>
<conf name="test" visibility="public" extends="compile" />
<conf name="compile" visibility="public" extends="runtime" />
<conf name="runtime" visibility="public" />
<conf name="provided" visibility="public" />
<conf name="junit" visibility="public" />
</configurations>
下面是 child 项目
<configurations>
<conf name="test" visibility="public" extends="compile" />
<conf name="compile" visibility="public" extends="runtime" />
<conf name="runtime" visibility="public" />
<conf name="provided" visibility="public" extends="compile" />
<conf name="junit" visibility="public" extends="provided, test" />
</configurations>
所以我必须先将 child 项目与 parent 对齐。
第二步,虽然可能要避免,但要为每个需要的配置多次重新映射 parent 项目的依赖关系。也许我可以优化这个,但至少 我不会再将 jdbc jar 下载到运行时类路径中
所以child依赖变成了
<dependencies>
<dependency org="com.acme" name="parent-project" rev="${phoenix.version}" transitive="true" conf="runtime->runtime"/>
<dependency org="com.acme" name="parent-project" rev="${phoenix.version}" transitive="true" conf="compile->compile"/>
<dependency org="com.acme" name="parent-project" rev="${phoenix.version}" transitive="true" conf="provided->provided"/>
<dependency org="com.acme" name="parent-project" rev="${phoenix.version}" transitive="true" conf="junit->junit"/>
<dependency org="com.acme" name="parent-project" rev="${phoenix.version}" transitive="true" conf="test->test"/>
</dependencies>
我有一个项目,正在被其他项目用作 Ivy 依赖项。它的 dependencies.xml
包含很多依赖项,基本上分为 3 类:
- 在 Eclipse 中编译项目并在嵌入式 运行 中编译项目 Tomcat 以及创建完整的自动一致 WAR 文件 所需的依赖项
- 编译和运行单元测试所需的依赖项
- 通常属于 Tomcat 类路径的依赖项,包括以下内容,并且需要通过 Ant 编译 Web 项目的 JAR
- Servlet API
- JDBC 连接器(它们实际上不随应用程序一起提供)
第三个依赖类别对我来说很重要。如果我不在 javac
类路径中包含 servlet-api.jar
,我将无法编译该项目。但是,如果我将该包包含在 war 类路径中,我就会陷入一种不好的做法,因为服务器 运行 次(主要是 Tomcat,还有 Websphere)包含它们自己的 servlet-api.jar
。
对于 JDBC 连接器,我只需要将它们包含到 Ant 类路径中,以便从 Bamboo 进行 运行ning 单元测试,因为我想对多个数据库重复相同的测试。
当前代码
这是我当前的 dependency.xml 片段:
<configurations>
<conf name="test" visibility="public" extends="compile" />
<conf name="compile" visibility="public" extends="runtime" />
<conf name="runtime" visibility="public" />
<conf name="provided" visibility="public" />
<conf name="junit" visibility="public" />
</configurations>
<!-- Build -->
<dependency org="javax.servlet" name="javax.servlet-api" rev="3.0.1" transitive="false" conf="provided->*" />
<dependency org="javax.servlet.jsp" name="javax.servlet.jsp-api" rev="2.3.1" transitive="false" conf="provided->*" />
<dependency org="javax.el" name="javax.el-api" rev="3.0.0" transitive="false" conf="provided->*" />
<dependency org="mysql" name="mysql-connector-java" rev="5.1.38" transitive="false" conf="provided->*" />
<dependency org="ojdbc" name="ojdbc" rev="14" transitive="false" conf="provided->*" />
<dependency org="org.hsqldb" name="hsqldb" rev="2.3.3" transitive="false" conf="provided->*" />
<dependency org="org.postgresql" name="postgresql" rev="9.4.1207" transitive="false" conf="provided->*" />
<dependency org="com.microsoft" name="sqljdbc" rev="4.1" transitive="false" conf="provided->*" />
<dependency org="org.adrianwalker" name="multiline-string" rev="0.1.2" transitive="false" conf="provided->*" />
<!-- Spring -->
<dependency org="org.springframework" name="spring-core" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-aop" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-beans" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-context" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-context-support" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-expression" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-jdbc" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-orm" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-tx" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-web" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-webmvc" rev="4.2.4.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework" name="spring-test" rev="4.2.4.RELEASE" transitive="false" conf="test->*"/>
<dependency org="org.springframework.plugin" name="spring-plugin-core" rev="1.2.0.RELEASE" transitive="false" conf="runtime->*"/>
<dependency org="org.springframework.plugin" name="spring-plugin-metadata" rev="1.2.0.RELEASE" transitive="false" conf="runtime->*"/>
在上面的例子中,com.adrianwalker#multiline-string
只需要注解解析,不需要
蚂蚁
在我的 main-project
中,我最终通过以下任务检索依赖项
<target name="ivy-retrieve">
<ivy:configure override="true" file="${ivy.install.dir}/ivy-settings.xml" />
<ivy:retrieve sync="true" conf="runtime,junit" type="jar,bundle" pattern="${project.local.lib}/[artifact]-[revision].[ext]" />
<eclipse.refreshLocal depth="infinite" resource="/" if:set="eclipse.running" />
</target>
这将使用我需要的所有依赖项(包括 spring-test
)正确填充我的 WEB-INF/lib
目录,但没有已手动复制到 Tomcat 的 JDBC 连接器类路径
好的...
问题
当我将 main-project
嵌入 derived-project
<dependency org="com.example" name="main-project" rev="${current.version}" transitive="true" conf="runtime->*"/>
和
<target name="ivy-retrieve-eclipse">
<ivy:configure override="true" file="${ivy.install.dir}/ivy-settings.xml" />
<ivy:retrieve sync="true" conf="runtime,junit" type="jar,bundle" pattern="${project.local.lib}/[artifact]-[revision].[ext]" />
<eclipse.refreshLocal depth="infinite" resource="/" if:set="eclipse.running" />
</target>
结果是我仍然下载了所有依赖项。
问题
我只需要告诉 Ivy 为我的 derived-project
下载所有 runtime
和 junit
的依赖项,包括那些 runtime
和 junit
依赖项包含在 main-project
的常春藤档案中。
我该怎么做?我搞砸了什么?
所以我假设您的主要项目正在将其 jar 发布到存储库中是正确的? (使用发布任务?)。
我认为您的问题出在子构建的依赖项声明中的配置映射:
<dependency org="com.example" name="main-project" rev="${current.version}" transitive="true" conf="runtime->*"/>
你说本地构建的 "runtime" 配置映射到主项目模块中列出的 all 配置。这就是您获得所有罐子的原因:
conf="runtime->*"
修复很简单:
conf="runtime"
这是 shorthand 用于:
conf="runtime->runtime"
之前的设置有两个问题:
- 正如@MarkOConnor 强调的那样,我在 child 项目依赖项上使用了
conf="runtime->*"
,它只会将runtime
重新映射到all
配置 - parent 和 child 工件的配置不一致
关于第 2 点,我在 parent 项目
上有以下内容<configurations>
<conf name="test" visibility="public" extends="compile" />
<conf name="compile" visibility="public" extends="runtime" />
<conf name="runtime" visibility="public" />
<conf name="provided" visibility="public" />
<conf name="junit" visibility="public" />
</configurations>
下面是 child 项目
<configurations>
<conf name="test" visibility="public" extends="compile" />
<conf name="compile" visibility="public" extends="runtime" />
<conf name="runtime" visibility="public" />
<conf name="provided" visibility="public" extends="compile" />
<conf name="junit" visibility="public" extends="provided, test" />
</configurations>
所以我必须先将 child 项目与 parent 对齐。
第二步,虽然可能要避免,但要为每个需要的配置多次重新映射 parent 项目的依赖关系。也许我可以优化这个,但至少 我不会再将 jdbc jar 下载到运行时类路径中
所以child依赖变成了
<dependencies>
<dependency org="com.acme" name="parent-project" rev="${phoenix.version}" transitive="true" conf="runtime->runtime"/>
<dependency org="com.acme" name="parent-project" rev="${phoenix.version}" transitive="true" conf="compile->compile"/>
<dependency org="com.acme" name="parent-project" rev="${phoenix.version}" transitive="true" conf="provided->provided"/>
<dependency org="com.acme" name="parent-project" rev="${phoenix.version}" transitive="true" conf="junit->junit"/>
<dependency org="com.acme" name="parent-project" rev="${phoenix.version}" transitive="true" conf="test->test"/>
</dependencies>