maven学习

1、排除传递依赖
解决版本冲突,传递依赖包获取不到等问题
确定 是哪个包的传递依赖产生的冲突

首先,你要在pom.xml中加上maven-project-info-reports-plugin插件。<project><reporting>...</reporting></project>

<reporting>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>
     maven-project-info-reports-plugin
    </artifactId>
   </plugin>

  </plugins>
</reporting>

然后再执行:mvn project-info-reports:dependencies 。生成项目依赖树,在target/site/dependencies.html可以查看项目依赖关系,最后在相应的dependency中加上exclusions来排除相关的传递依赖。

例:在本例中,jmxtools在本地远程仓库中是丢失,所以采取该方式排除掉

  <dependencies>

    <dependency>

      <groupId>log4j</groupId>

      <artifactId>log4j</artifactId>

      <version>1.2.15</version>

      <exclusions>

       <exclusion>

        <groupId>com.sun.jdmk</groupId>

        <artifactId>jmxtools</artifactId>

       </exclusion>

      </exclusions>

    </dependency>


2、生成项目站点:

其实生产报表文件,可以如下比如:在<project><build>标签下加入如下代码:
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-site-plugin</artifactId>
                    <version>3.0-beta-3</version>
                    <configuration>
                        <reportPlugins>
                            <plugin>
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-checkstyle-plugin</artifactId>
                            </plugin>
                            <plugin>
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-project-info-reports-plugin</artifactId>
                                <version>2.4</version>
                                <configuration>
                                    <dependencyDetailsEnabled>true</dependencyDetailsEnabled>
                                    <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
                                </configuration>
                            </plugin>
                        </reportPlugins>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
每一个plugin产生一种类型的报表

3.项目统一的本地远程maven repository 配置
M2_HOME/conf/settings.xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

  <mirrors>
    <mirror>
      <mirrorOf>*</mirrorOf>
      <name>repo</name>
      <url>http://ip:8081/artifactory/repo</url>
    </mirror>
  </mirrors>
4. 如何忽略测试步骤
给mvn增加命令行参数 -Dmaven.test.skip=true 或者 -DskipTests=true
mvn -Dmaven.test.skip=true package (单元测试有错误,略过测试步骤)

5. property定义
1)直接在pom.xml定义property
<project>
...
  <properties>    <my.filter.value>hello</my.filter.value>  </properties>...</project>2)引用外部文件的property首先:创建外部属性文件比如: src/main/filters/filter.properties# filter.properties my.filter.value=hello!再在pom.xml中引用该外部文件  <build>     <filters>      <filter>src/main/filters/filter.properties</filter>    </filters>    <resources>      <resource>        <directory>src/main/resources</directory>        <filtering>true</filtering>      </resource>    </resources>  </build>这样就可以在属性文件中引用属性:my.filter.value比如属性文件: src/main/resources/ application.properties# application.properties application.name=${pom.name} application.version=${pom.version} message= ${my.filter.value} replace property using value in the resource file , must set "filtering=true" in pom.xml when copy resources.  <build>    <resources>      <resource>        <directory>src/main/resources</directory>        <filtering>true</filtering>      </resource>    </resources>  </build>

6. 使用maven-assembly plugin 实现自定义打包。修改pom.xml
                 <plugins>
                        <plugin>
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-assembly-plugin</artifactId> 
                                <version>2.2.1</version>
                                <configuration>
                                        <descriptorRefs>
                                                <descriptorRef>src</descriptorRef>
                                        </descriptorRefs>
                                </configuration>
                                <executions>     <!--执行器 mvn assembly:assembly-->  
                                        <execution>
                                                <id>make-assembly</id>   <!--名字任意 -->
                                                <phase>package</phase>   <!-- 绑定到package生命周期阶段上 -->    
                                                <goals>
                                                        <goal>single</goal>  <!-- 只运行一次 -->    
                                                </goals>
                                        </execution>
                                </executions>
                        </plugin>
                </plugins>
  execution的设置是为了将maven-assembly-plugin继承到标准的maven打包过程中,这样在运行maven-package时就会执行maven-assembly-plugin的操作,从而实现我们需要的自定义打包。
这样将打src目录打包,生成的打包文件有3种后缀格式: *-src.tar.bz2,*-src.tar.gz, *src.zip。默认打包到target 目录
实际上可以设置配置打包的方式: 在上面代码 <configuration> 中加入 descriptor属性,例如:
          <descriptors>  <!--配置文件路径-->  
            <descriptor>src/main/assemble/package.xml</descriptor>
          </descriptors>
容许使用多个配置文件,package.xml文件内容参考如下:
<assemblyxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/assembly-1.0.0.xsd">
  <id>package</id>
  <formats>  <!--设置打包格式 -->
    <format>zip</format>
  </formats>
  <includeBaseDirectory>true</includeBaseDirectory>
  <fileSets>
    <fileSet>  <!-- 设置要打包的原始目录和结果目录 -->
      <directory>src/main/bin</directory>
      <outputDirectory>/</outputDirectory>
    </fileSet>   <!-- 将src/main/bin目录下的文件打包到根目录(/)下. -->
    <fileSet>
      <directory>src/main/config</directory>
      <outputDirectory>config</outputDirectory>
    </fileSet>
  </fileSets>
  <dependencySets> <!-- 将scope为runtime的依赖包打包到lib目录下 -->
    <dependencySet>
      <outputDirectory>lib</outputDirectory>
      <scope>runtime</scope>
    </dependencySet>
  </dependencySets>
</assembly>

7. 自定义goal, 开发plugin 参考官方文档: http://maven.apache.org/guides/plugin/guide-java-plugin-development.html

8. 部署到服务器, mvn deploy
<distributionManagement>  <repository>    <id>proficio-repository<id>    <name>Proficio Repository<name>    <url>file://${basedir}/target/deploy<url>  <repository>< distributionManagement>

9. 导入到eclipse
安装m2eclipse plugin 
对项目执行mvn eclipse:eclipse
再导入到eclipse。
可以直接在eclipse创建maven project

10.开发自定义goal,即开发插件maven plugin实现goal,每一个mojo对应一个goal
例如:
Step1:创建插件项目
mvn archetype:create -DgroupId=org.sonatype.mavenbook.plugins -DartifactId=first-maven-plugin -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-mojo
Step2:创建Mojo类
package com.doris;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
/**
* Say hello to user.
*
* @goal sayhi
*/
public class MyMojo extends AbstractMojo
{
  /**
   * Any Object to print out.
   *
   * @parameter expression="${echo.message}" default-value="Hello Maven World"
   */
    private Object message;
    public void execute()
        throws MojoExecutionException
    {
        getLog().info(message.toString());
    }
}
@goal sayhello  指明goal名称
@parameter expression="${echo.message}" default-value="Hello Maven World"  传递参展
Step3: run 自定义插件
mvn install
插件运行遵循groupId:artifactId:version:goal格式
mvn com.doris:first-maven-plugin:1.0:sayhi -Decho.message=r3r23r3t
输出“ r3r23r3t” 在屏幕上
Step4:其他项目调用该goal,只要在项目中加入以下:
<build>
  ...
    <plugins>
      <plugin>
        <groupId>com.doris</groupId>
        <artifactId>first-maven-plugin</artifactId>
        <version>1.0</version>       
      </plugin>
    </plugins>
...
  </build>
Step5: 定义前缀,减短输入命令行长度
在.m2/settings.xml中加入
<pluginGroups>
  <pluginGroup>com.doris</pluginGroup>
</pluginGroups>
you follow the convention of using ${prefix}-maven-plugin (or maven-${prefix}-plugin),then can run: "mvn first:sayhi"
Step6: 在eclipse中运行自定义goal
依次选择:Run as -->  run Configuration.. -> Main tab栏
填写: Goals: first:sayhi, (在定义前缀的情况下,可以剪短输入的goal,否则输入 groupId:artifactId:version:goal)
           Parameters name:   message   value: Hi, I am coming!

11. how to deploy my jar to remote repository
For deploying jars to an external repository, you have to configure the repository url in the pom.xml and the authentication information for connectiong to the repository in the settings.xm
[pom.xml]
    <distributionManagement>        <repository>            <id>drutt-release</id>            <name>artifactory.drutt.com/release</name>            <url>http://artifactory.drutt.com:8081/artifactory/libs-release-local</url>        </repository>        <snapshotRepository>            <id>drutt-snapshot</id>            <name>artifactory.drutt.com/snapshots</name>            <url>http://artifactory.drutt.com:8081/artifactory/libs-snapshot-local</url>        </snapshotRepository>    </distributionManagement> [settings.xml]  <servers>
    <server>      <id>drutt-release</id>...
     </server>  </servers>
13.生成附属构件
默认Maven只生成一个构件,我们称之为主构件,那 当我们希望Maven生成其他附属构件的时候,就能用上classifier 。常见的classifier还有如dog-cli-1.0-sources.jar 表示源码包,dog-cli-1.0-javadoc.jar 表示JavaDoc包等等。制作classifier的方式多种多样,其中最重要的一种是使用 Maven Assembly Plugin
14. maven的变量

maven定义了很多变量属性,参考 http://docs.codehaus.org/display/MAVENUSER/MavenPropertiesGuide

  1. 内置属性
    • ${basedir } represents the directory containing pom.xml
    • ${version } equivalent to ${project.version } or ${pom.version }
  2. Pom/Project properties
    所有pom中的元素都可以用 project. 前缀进行引用,以下是部分常用的
    • ${project.build.directory } results in the path to your "target" dir, this is the same as ${pom.project.build.directory }
    • ${project.build. outputD irectory } results in the path to your "target/classes" dir
    • ${project.name } refers to the name of the project.
    • ${project.version } refers to the version of the project.
    • ${project.build.finalName } refers to the final name of the file created when the built project is packaged
  3. 本地用户设定
    所有用的的 settings.xml 中的设定都可以通过 settings. 前缀进行引用
    • ${settings.localRepository } refers to the path of the user's local repository.
    • ${maven.repo.local } also works for backward compatibility with maven1 ??
  4. 环境变量
    系统的环境变量通过 env. 前缀引用
    • ${env.M2_HOME } returns the Maven2 installation path.
    • ${java.home } specifies the path to the current JRE_HOME environment use with relative paths to get for example:
      <jvm>${java.home}../bin/java.exe</jvm>
  5. java系统属性
    所有JVM中定义的java系统属性.
  6. 用户在pom中定义的自定义属性
    复制代码
    < project >
        ...
       
    < properties >
           
    < my.filter.value > hello </ my.filter.value >
       
    </ properties >
        ...
    </ project >
    复制代码
    则引用 ${my.filter.value } 就会得到值 hello
  7. 上级工程的变量
    上级工程的pom中的变量用前缀 ${project.parent } 引用. 上级工程的版本也可以这样引用: ${parent.version }.
15. mvn release
dry run: don't checkin or tag anything in the scm repository, or modify the checkout. Running mvn -DdryRun=true release:prepare is useful in order to check that modifications to poms and scm operations (only listed on the console) are working as expected


16.  【转】关于maven可选依赖和排除依赖的学习 http://qa.taobao.com/?p=7351

   了解可选依赖和排除依赖的功能,能够帮助我们更好的理解依赖是什么、怎样使用、如何工作和何时最适宜应用。其中,排除依赖是作为依赖的基本概念而不是处于pom层。

一、    可选依赖

       当一个项目不适合分割成多个子模块的时候,我们可以使用可选依赖。它的思想在于某些依赖只应用于某些功能,而且当没有该功能时也不存在该依赖。理想状况下,一个功能可能被划分为一个子模块,该子模块是一个只有核心功能的项目,由于当你要使用这个子工程的功能的时候,你会需要它的全部,所以这个子工程只含有非可选性依赖。

      然而,如果工程不可被分割,这些依赖被声明为可选。如果一个用户想要使用和可选性依赖相关的功能,他们必须要在工程中重新声明可选性依赖。也许可选依赖和排除依赖不是解决问题的最好方法,但是不失为一种有效的解决方案。

      1. 为何使用可选依赖

      声明可选依赖不仅对于节省空间/内存等是重要的,而且对于使用一个工程的时候控制实际依赖的列表也是非常重要的。因为jar包最终可能编译成WAR、EAR、EJB等等,包含错误的jar包可能产生违反许可证协议、导致类路径错误等问题。

      2.如何使用optional标记

      在你的依赖声明中简单地将<optional>标记设置成true,就能将一个依赖声明为可选的。示例如下

<project>  ...  <dependencies>    <!-- declare the dependency to be set as optional -->    <dependency>      <groupId>sample.ProjectA</groupId>      <artifactId>Project-A</artifactId>      <version>1.0</version>      <scope>compile</scope>      <optional>true</optional> <!-- value will be true or false only -->    </dependency>  </dependencies></project>

      3.可选依赖是如何工作的?

Project-A -> Project-B

      如上图所以projectA依赖projectB,当A在它的pom中声明B作为它的可选依赖时,这个关系会一直保持。 这就像在通常的构建中,projectB会被加到它的类路径中。

Project-X -> Project-A

      但是当另外一个工程projectX在它的pom中声明A作为其依赖时,可选性依赖这时就发挥作用了。你会发现projectB并不存在projectX的类路径中。如果X的类路径要包含B那么需要在你的pom中直接进行声明。

      4.例子:

      让我们假设现在有这样一个和Hibernate有类似功能的工程X2,支持多种诸如mysql, postgre, oracle等数据库驱动/依赖,所有这些驱动/依赖是X2但不是你的工程所需要的,所以一种比较可行的方法就是X2将这些驱动/依赖声明为可选的。这样,无论任何时候当你的工程在pom中声明X2作为直接依赖,X2所支持的这些驱动/依赖都不会被自动加到你工程的类路径中,相反地,你必须要直接声明需要使用的数据库驱动/依赖。

二、  排除依赖

       由于maven2.x会传递解析依赖,所以很有可能一些你不需要的依赖也会包含在工程类路径中。例如,一些你依赖的工程可能没有正确的声明它们的依赖集。为了解决这种特殊情况,maven2.x已经引入了显式排除依赖的概念。排除是设置在pom中指定的依赖上,并且有指定的groupId和artifactId来标注。当你构建工程时,该物件不会像解析加载依赖一样被加载到你工程的类路径中。

       1. 如何使用排除依赖

       我们在pom中的<dependency>段下面加上<exclusions>标签。

<project>  ...  <dependencies>    <dependency>      <groupId>sample.ProjectA</groupId>      <artifactId>Project-A</artifactId>      <version>1.0</version>      <scope>compile</scope>      <exclusions>        <exclusion>  <!-- declare the exclusion here -->          <groupId>sample.ProjectB</groupId>          <artifactId>Project-B</artifactId>        </exclusion>      </exclusions>    </dependency>  </dependencies></project>

       2.排除依赖是如何工作的并且在何时使用它(作为最后一种解决方法)

Project-A   -> Project-B        -> Project-D <! -- This dependency should be excluded -->              -> Project-E              -> Project-F   -> Project C

       如上图所示,Project-A依赖Project-B和C,Project-B依赖Project-D,Project-D依赖Project-E和F,默认的Project-A的类路径会包含:

B, C, D, E, F

       如果由于我们知道Project-D的某些依赖在仓库中丢失,那么我们不想Project-D和它所有的依赖加载到Project-A的类路径中,而且也不想/不需要依赖Project-D的Project-B的功能。在这种情况下,Project-B的开发者会提供一个Project-D的 <optional>true</optional>依赖,如下:

<dependency>  <groupId>sample.ProjectD</groupId>  <artifactId>ProjectD</artifactId>  <version>1.0-SNAPSHOT</version>  <optional>true</optional>

</dependency>

      然而,并不能达到你想要的效果。作为最后一种解决方法你仍然可以选择将它在Project-A中排除掉。如下:

<project>  <modelVersion>4.0.0</modelVersion>  <groupId>sample.ProjectA</groupId>  <artifactId>Project-A</artifactId>  <version>1.0-SNAPSHOT</version>  <packaging>jar</packaging>  ...  <dependencies>    <dependency>      <groupId>sample.ProjectB</groupId>      <artifactId>Project-B</artifactId>      <version>1.0-SNAPSHOT</version>      <exclusions>        <exclusion>          <groupId>sample.ProjectD</groupId> <!-- Exclude Project-D from Project-B -->          <artifactId>Project-D</artifactId>        </exclusion>      </exclusions>    </dependency>  </dependencies></project>

      如果我们将Project-A部署到一个仓库中,而且Project-X声明了一个普通依赖到Project-A。那么Project-D是不是依旧从类路径中排除了?

Project-X -> Project-A

       答案是yes。Project-A已经声明了它不需要Project-D,所以它不会作为Project-A的传递依赖而引入。那么考虑下图的Project-X依赖Project-Y,

Project-X -> Project-Y               -> Project-B                    -> Project-D                       ...

       Project-Y依赖于Project-B,并且它有需要Project-D所支持的功能,所以不能在Project-D的依赖列表中声明排除。也可再提供一个额外的我们可以解析Project-E的仓库。在这种情况下,不能将Project-D全局排除,因为它是Project-Y的合法依赖。

      在另外一种场景中,如果我们不需要的依赖是Project-E而不是Project-D,我们如何排除它呢?如下图:

Project-A   -> Project-B        -> Project-D              -> Project-E <!-- Exclude this dependency -->              -> Project-F   -> Project C

      排除会影响到在依赖图上所有它的声明点以后的部分。如果你想排除Project-E而不是Project-D,可以简单的将排除指向Project-E。但是你无法将排除作用到Project-D,因为你无法改变Project-D的pom,如果你想这样,你应该用选择依赖而不是排除,或者将Project-D分成多个子工程,每个只有普通依赖。

<project>  <modelVersion>4.0.0</modelVersion>  <groupId>sample.ProjectA</groupId>  <artifactId>Project-A</artifactId>  <version>1.0-SNAPSHOT</version>  <packaging>jar</packaging>  ...  <dependencies>    <dependency>      <groupId>sample.ProjectB</groupId>      <artifactId>Project-B</artifactId>      <version>1.0-SNAPSHOT</version>      <exclusions>        <exclusion>          <groupId>sample.ProjectE</groupId> <!-- Exclude Project-E from Project-B -->          <artifactId>Project-E</artifactId>        </exclusion>      </exclusions>    </dependency>  </dependencie>

      3.为什么排除是依赖的基本概念,而不是在pom层上?

       这主要是为了确保依赖图是可预测的,并且防止排除不该排除的依赖。如果你用到了这个最终的解决方法并且必须要把它放到排除中,你必须绝对清楚你讨厌的传递依赖中有哪些依赖会被引入。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值