• 1. Maven-项目管理工具研发支撑 2010-11-29
  • 2. MavenMaven介绍 Maven基本应用 Maven高级应用 实际操作
  • 3. Maven介绍-简介 Maven是一个构建工具。 Maven是一个项目管理工具。它包含了一个项目对象模型 (Project Object Model POM),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。当你使用Maven的时候,你用一个明确定义的项目对象模型(POM)来描述你的项目。Maven的核心很小,主要的功能是依靠各种插件来完成的。 Maven有一个生命周期,当你运行 mvn install 的时候被调用。这条命令告诉 Maven 执行一系列的有序的步骤,直到到达你指定的生命周期。遍历生命周期旅途中的一个影响就是,Maven 运行了许多默认的插件目标,这些目标完成了像编译和创建一个 JAR 文件这样的工作。 此外,Maven能够很方便的帮你管理项目报告,生成站点,管理JAR文件,等等。
  • 4. Maven介绍-目标 (1)1、使项目构建过程变得更加简单 在使用Maven的时候,不要抛开具体的需求而想要去了解Maven内部的工作机制,Maven屏蔽了许多细节部分。 2、提供统一的构建系统 3、提供高质量的项目信息 某些产品项目中,不仅需要编译、测试、打包这些基础的信息,Maven还提供足够多的其他的有用的项目信息。例如: 可以直接从版本管理系统(例如:CVS,SVN等)中创建出更改日志  依赖列表(Dependency list)  单元测试报告及测试覆盖率  这些信息对于Maven来说是简单的,很容易就可以实现的。
  • 5. Maven介绍-目标 (2)4、提供开发方面的最佳实践 Maven致力于搜集一些当前在开发方面的最佳实践原则,并且可以很容易的指导一个项目往这个方向上发展。例如,规格说明(specification)、execution和单元测试报告(reporting of unit tests)是使用Maven进行项目构建的正常步骤。现在的单元测试最佳实践采用以下的一些指导方针: 把你的测试源代码放在一个单独的,但是平行的代码树中  使用测试用例命名规则来定位和执行测试  不要去人为的定义测试的初始化环境,让测试用例自己来装载他们的测试环境      Maven也在项目的工作流程上提供了一些帮助,比如发布管理和一些版本跟踪信息。     Maven在项目目录结构的布局上也提出了一些自己的建议,所以一旦你掌握了Maven的基本目录结构,那么就可以很轻松的管理和操作其他的同样使用了Maven的项目,说白了可以让你很快的看清其他项目的概况。
  • 6. Maven介绍-价值依赖管理 鼓励最佳实践 管理公司内部项目 管理第三方非Maven库 版本控制
  • 7. Maven介绍-价值-依赖管理依赖管理 Maven最强大的特征之一,它支持了传递性依赖(transitive dependencies)。假如你的项目依赖于一个库,而这个库又依赖于五个或者十个其它的库(就像Spring或者Hibernate那样)。你不必找出所有这些依赖然后把它们写在你的pom.xml里,你只需要加上你直接依赖的那些库,Maven会隐式的把这些库间接依赖的库也加入到你的项目中。 Maven也可以处理某些特殊依赖的冲突,可以自定义默认行为,或者排除一些特定的传递性依赖。 产品项目依赖的软件包是需要区分范围的,不同范围的使用方式不同。如果全部打包在一起,容易引起混乱。例如:测试时依赖的junit,在部署时是不需要的;编译时依赖的servlet-api,在部署时由tomcat等服务器提供,产品软件包中不应该包含。使用maven可以方便的管理软件包的范围。 利用maven定义的软件包之间的依赖关系,可以尽量精简地加入我们依赖的软件包,防止人工管理时产品中加入无用的冗余的软件包。
  • 8. Maven介绍-价值-鼓励最佳实践鼓励最佳实践 Maven的特点之一约定优于配置实际上就是鼓励最佳实践,像目录结构和开发过程(编译、测试、打包)等,这些最佳实践都是在长期的软件开发中总结出来,适合绝大多数的项目,不需要在每次开发时都进行配置,约定成统一的格式,使开发过程更加快捷。当然,对于有些项目,由于历史原因,可能并不适合使用这些好的办法,但是Maven被设计成可伸缩性和可伸展性,在这种情况下,这些项目可以根据需求,作一下相应的配置即可。
  • 9. Maven介绍-价值-管理公司内部项目管理公司内部项目 Maven提供了统一的、标准的、业界认可的管理方式对公司内部项目进行有效的管理: - 多个工程之间的管理:一个大项目往往是由许多有联系又独立的工程组成的,这些工程存在着复杂的依赖关系。Maven最初的目标就是管理多个工程的依赖关系,这是最擅长的方面。 - 通用框架或组件与产品项目的管理:公司内部往往会存在通用的框架或组件,例如:公司许多产品项目都依赖WebX框架。不同的产品可能依赖不同的框架版本,通过Maven可以将各个版本的通用框架或组件打包发布到本地仓库,组件产品依赖哪个版本就使用哪个版本,实现版本的统一管理。 - 统一的软件包发布平台:外界开源的软件包发现bug,公司内部进行修改后,可以通过公司的maven库统一发布。多个项目组可以共享bug修改的成果。
  • 10. Maven介绍-价值-管理第三方非Maven库管理第三方非Maven库 实际开发中需要用到的一些软件包,并没有进入maven官方的软件库,甚至也没有采用maven管理。例如:oracle的jdbc驱动包。我们把这一类型的软件包,统一纳入到公司内的maven库管理,将其上传到公司Maven仓库供所有项目使用,而不需要每个项目都单独下载。一方面分享方便,一方面可以有效管理版本。
  • 11. Maven介绍-pom介绍 POM = Project Object Model = pom.xml是Maven的核心文件,它是指示Maven如何工作的元数据文件,类似于Ant中的build.xml文件。POM文件位于每个工程的根目录中。 主要内容: 项目基本信息 项目之间的依赖关系; 项目所需要使用的插件信息:如war,jetty,javadoc等等;
  • 12. Maven介绍-pom介绍-最简单的pom 4.0.0 cn.ceopen quickstart jar 1.0.0 quickstart http://maven.apache.org
  • 13. Maven介绍-pom介绍-复杂的pom (1) 4.0.0 boss-demo cn.ceopen.mqx 1.0.0 cn.ceopen.mqx cic 1.0.0 war cic http://maven.apache.org commons-logging commons-logging 1.1.1 。。。。。。
  • 14. Maven介绍-pom介绍-复杂的pom (2) ${project.basedir}/src/main/ ${project.basedir}/resource org.apache.maven.plugins maven-war-plugin 2.1 ${basedir}/WebRoot org.apache.maven.plugins maven-compiler-plugin utf-8 1.6 1.6 。。。。。。
  • 15. Maven介绍-依赖定义 – groupId (构件所属的组织id) – artifactId (构件唯一标识符) – version (版本) – scope (生命周期) 配置人员需要考虑使用什么JAR包?版本号使多少?所在生命周期是什么? junit junit 4.7 test ……
  • 16. Maven介绍-依赖范围 在实际企业应用程序中,你可能无需包含所有的依赖项到你的部署应用程序中,有些JARs只有单元测试需要,而有些可能由应用服务器提供。使用称为依赖范围的技术,Maven让你使用那些你需要的JARs,而在不需要时则从classpath排除它们。 compile:编译范围,默认scope,在classpath中存在。 provided:已提供范围,比如容器提供Servlet API。 runtime:运行时范围,编译不需要,接口与实现分离。 test:测试范围,单元测试环境需要。 system:系统范围,自定义构件,指定systemPath import:2.0.9以上版本可用
  • 17. Maven介绍-生命周期(1)Clean Lifecycle 在进行真正的构建之前进行一些清理工作。 Default Lifecycle 构建的核心部分,编译,测试,打包,部署等等。 Site Lifecycle 生成项目报告,站点,发布站点。 pre-clean  执行一些需要在clean之前完成的工作 clean  移除所有上一次构建生成的文件 post-clean  执行一些需要在clean之后立刻完成的工作 pre-site     执行一些需要在生成站点文档之前完成的工作 site    生成项目的站点文档 post-site     执行一些需要在生成站点文档之后完成的工作,并且为部署做准备 site-deploy     将生成的站点文档部署到特定的服务器上 记住,运行任何一个阶段的时候,它前面的所有阶段都会被运行,这也就是为什么我们运行mvn install 的时候,代码会被编译,测试,打包。
  • 18. Maven介绍-生命周期(2)validate generate-sources process-sources generate-resources process-resources     复制并处理资源文件,至目标目录,准备打包。 compile     编译项目的源代码。 process-classes generate-test-sources  process-test-sources generate-test-resources process-test-resources     复制并处理资源文件,至目标测试目录。 test-compile     编译测试源代码。 process-test-classes Test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。 prepare-package Package 接受编译好的代码,打包成可发布的格式,如 JAR 。 pre-integration-test integration-test post-integration-test verify Install 将包安装至本地仓库,以让其它项目依赖。 Deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。
  • 19. Maven介绍-阶段每个生命周期包含一组阶段序列,一个阶段只属于一个生命周期,这样当执行mvn xx阶段时就先确定该阶段所属的生命周期,然后顺序执行该生命周期内xx阶段之前的所有阶段。比如 mvn integration-test首先定位integration-test在default生命周期内,然后执行default生命周期内integration-test阶段之前的所有阶段,但不会执行clean生命周期中的任何阶段。 如果要一次执行多个生命周期内的阶段,就传递多个阶段参数即可。 mvn clean install mvn clean package  
  • 20. Maven基本应用下载安装 创建项目 基本命令 导入eclipse 自定义本地仓库
  • 21. Maven基本应用-下载安装1、下载 Linux:http://www.apache.org/dyn/closer.cgi/maven/binaries/apache-maven-3.0-bin.tar.gz Windows:http://www.apache.org/dyn/closer.cgi/maven/binaries/apache-maven-3.0-bin.zip 2、 解压缩 tar -zxvf apache-maven-3.0-bin.tar.gz 3、 设置环境变量 cd /etc/profile.d //创建java.sh并编辑 vi java.sh //java.sh内容如下: M2_HOME=/.../apache-maven-3.0 M2=$M2_HOME/bin PATH=$M2:$PATH export M2_HOME M2 PATH //为java.sh添加可执行权限 chmod +x java.sh //执行java.sh ./java.sh 设置完环境变量重新登录,运行mvn -v验证。 注:由于Maven是java工具,所以安装Maven前必须保证安装了jdk并且版本在1.5及以上。返回
  • 22. Maven基本应用-创建项目-基本项目创建基本项目创建: mvn archetype:generate -DgroupId=cn.ceopen -DartifactId=quickstart -Dversion=1.0.0 -Dpackage=cn.ceopen.demo -DarchetypeArtifactId=maven-archetype-quickstart基本项目目录结构: quickstart │ pom.xml //项目配置文件 │ └─src ├─main //源代码 │ └─java │ └─cn │ └─ceopen │ └─demo │ App.java │ └─test //单元测试源代码 └─java └─cn └─ceopen └─demo AppTest.javapom.xml: 4.0.0 cn.ceopen quickstart jar 1.0.0 quickstart http://maven.apache.org junit junit 3.8.1 test
  • 23. Maven基本应用-创建项目-参数解释maven-archetype-archetypeAn archetype which contains a sample archetype.maven-archetype-j2ee-simpleAn archetype which contains a simplifed sample J2EE application.maven-archetype-mojoAn archetype which contains a sample a sample Maven plugin.maven-archetype-pluginAn archetype which contains a sample Maven plugin.maven-archetype-plugin-siteAn archetype which contains a sample Maven plugin site.maven-archetype-portletAn archetype which contains a sample JSR-268 Portlet.maven-archetype-quickstartAn archetype which contains a sample Maven project.maven-archetype-simpleAn archetype which contains a simple Maven project.maven-archetype-siteAn archetype which contains a sample Maven site which demonstrates some of the supported document types like APT, XDoc, and FML and demonstrates how to i18n your site.maven-archetype-site-simpleAn archetype which contains a sample Maven site.maven-archetype-webappAn archetype which contains a sample Maven Webapp project.groupId:组织id artifactId:构件id version:版本号 package:包名 archetypeArtifactId:项目类型
  • 24. Maven基本应用-创建项目-web项目创建Web项目创建: mvn archetype:generate -DgroupId=cn.ceopen -DartifactId=webapp -Dversion=1.0.0 -Dpackage=cn.ceopen.demo -DarchetypeArtifactId=maven-archetype-webappweb项目目录结构: webapp │ pom.xml //项目配置文件 │ └─src └─main ├─resources //资源文件,存放配置文件等 └─webapp //web文件,相当于WebRoot目录 │ index.jsp │ └─WEB-INF web.xmlpom.xml: 4.0.0 cn.ceopen webapp war 1.0.0 webapp Maven Webapp http://maven.apache.org junit junit 3.8.1 test webapp
  • 25. Maven基本应用-基本命令执行编译:D:\my-app> mvn compile。输出的.class文件在target/classes中。 打包: D:\my-app> mvn package。输出Jar包 D:\my-app> mvn install把包安装在本地的repository中,可以被其他工程作为依赖来使用。 D:\my-app> mvn site为工程建立一个简单的网站,输出在target/site中。 D:\my-app> mvn clean删除target目录。
  • 26. Maven基本应用-导入eclipse1. 使用Maven创建项目; 2. 在DOS下到项目目录下,使用命令:mvn eclipse:eclipse 将一个Maven项目创建成一个EclipseIDE可以识别的项目; 3. 运行mvn -Declipse.workspace=D:\workspace eclipse:add-maven-repo会自动在eclipse中添加Classpath变量M2_REPO,并指向maven本地仓库,或者在eclipse中打开Window->Preferences->Java->Build Path->Classpath Variables,手动添加M2_REPO并指向maven本地仓库。 4.在eclipse中import该项目。
  • 27. Maven基本应用- maven自定义本地仓库 用户可以自行改变本地仓库的设置。默认仓库的位置是${user.home}/.m2/repository/. 修改$M2_HOME$/conf/settings.xml: ... /path/to/local/repo/ ...
  • 28. Maven高级应用多模块配置 依赖导出 Maven仓库 构件分发 约定优于配置
  • 29. Maven高级应用-多模块配置例:webx3有多个项目webx-util、webx-service、webx-struts1-annotation、webx-richclient新建一个文件夹webx3,将三个工程放在目录下,并创建pom.xml:
  • 30. Maven高级应用-多模块配置(2)然后分别在每个工程文件夹下添加pom.xml。文件结构如下:webx-service的pom.xml配置信息:D:\MAVENDEMO\WEBX3 │ pom.xml │ ├─webx-richclient │ pom.xml │ ├─webx-service │ pom.xml │ ├─webx-struts1-annotation │ pom.xml │ └─webx-util pom.xml
  • 31. Maven高级应用-工程依赖导出 mvn dependency:copy-dependencies 将pom.xml中描述的依赖导出,默认会生成target\dependency目录,将依赖的jar保存在该目录。 打包时导出依赖并指定目录,需要配置plugin:
  • 32. Maven高级应用-Maven仓库什么是Maven仓库 在不用Maven的时候,比如说以前我们用Ant构建项目,在项目目录下,往往会看到一个名为/lib的子目录,那里存放着各类第三方依赖jar文件,如log4j.jar,junit.jar等等。每建立一个项目,你都需要建立这样的一个/lib目录,然后复制一堆jar文件,这是很明显的重复。重复永远是噩梦的起点,多个项目不共用相同的jar文件,不仅会造成磁盘资源的浪费,也使得版本的一致性管理变得困难。此外,如果你使用版本管理工具,如SVN(你没有使用版本管理工具?马上试试SVN吧,它能帮你解决很多头疼的问题),你需要将大量的jar文件提交到代码库里,可是版本管理工具在处理二进制文件方面并不出色。 Maven仓库就是放置所有JAR文件(WAR,ZIP,POM等等)的地方,所有Maven项目可以从同一个Maven仓库中获取自己所需要的依赖JAR,这节省了磁盘资源。此外,由于Maven仓库中所有的JAR都有其自己的坐标,该坐标告诉Maven它的组ID,构件ID,版本,打包方式等等,因此Maven项目可以方便的进行依赖版本管理。你也不在需要提交JAR文件到SCM仓库中,你可以建立一个组织层次的Maven仓库,供所有成员使用。 简言之,Maven仓库能帮助我们管理构件(主要是JAR)。
  • 33. Maven高级应用-本地仓库本地仓库 运行Maven的时候,Maven所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。 比如说,你的项目配置了junit-3.8的依赖,在你运行mvn test 的时候,Maven需要使用junit-3.8的jar文件,它首先根据坐标查找本地仓库,如果找到,就直接使用。如果没有,Maven会检查可用的远程仓库配置,然后逐个尝试这些远程仓库去下载junit-3.8的jar文件,如果远程仓库存在该文件,Maven会将其下载到本地仓库中,继而使用。如果尝试过所有远程仓库之后,Maven还是没能够下载到该文件,它就会报错。 Maven缺省的本地仓库地址为${user.home}/.m2/repository 。也就是说,一个用户会对应的拥有一个本地仓库。 你也可以自定义本地仓库的位置,修改${user.home}/.m2/settings.xml :     ...     D:\java\repository     ...   你还可以在运行时指定本地仓库位置: mvn clean install -Dmaven.repo.local=/home/juven/myrepo/ 还有一点需要理解的是,当我们运行install的时候,Maven实际上是将项目生成的构件安装到了本地仓库,也就是说,只有install了之后,其它项目才能使用此项目生成的构件。
  • 34. Maven高级应用-中心仓库了解了本地仓库,接着了解一下Maven缺省的远程仓库,即Maven中央仓库。 安装好Maven之后,我们可以建立一个简单的项目,配置一些简单的依赖,然后运行mvn clean install,项目就构建好了。我们没有手工的去下载任何jar文件,这一切都是因为Maven中央仓库的存在,当Maven在本地仓库找不到需要的jar文件时,它会查找远程仓库,而一个原始的Maven安装就自带了一个远程仓库——Maven中央仓库。 这个Maven中央仓库是在哪里定义的呢?在我的机器上,我安装了maven-2.0.10,我可以找到这个文件:${M2_HOME}/lib/maven-2.0.10-uber.jar ,打开该文件,能找到超级POM:\org\apache\maven\project\pom-4.0.0.xml ,它是所有Maven POM的父POM,所有Maven项目继承该配置,你可以在这个POM中发现如下配置:            central       Maven Repository Switchboard       default       http://repo1.maven.org/maven2                false              
  • 35. Maven高级应用-pom.xml配置远程仓库   …...                inner-repositoryl   inner repository        http://221.123.173.11:8088/artifactory/repo      ……                        inner-plugin-repositoryl   inner plugin repository        http://221.123.173.11:8088/artifactory/repo           ……      …...    
  • 36. Maven高级应用-settings.xml配置远程仓库     ...                     dev                                 dev          ...    这里我们定义一个id为dev的profile,将所有repositories以及pluginRepositories元素放到这个profile中,然后,使用元素自动激活该profile。这样,你就不用再为每个POM重复配置仓库。 使用profile为settings.xml添加仓库提供了一种用户全局范围的仓库配置。
  • 37. Maven高级应用-分发构件至远程仓库(1)分发构件至远程仓库 mvn install 会将项目生成的构件安装到本地Maven仓库,mvn deploy 用来将项目生成的构件分发到远程Maven仓库。本地Maven仓库的构件只能供当前用户使用,在分发到远程Maven仓库之后,所有能访问该仓库的用户都能使用你的构件。 我们需要配置POM的distributionManagement来指定Maven分发构件的位置,如下:       ...                           webx           WebX Repository           http://221.123.173.11:8088/artifactory/repo/webx-repository                     nexus-snapshots           Nexus Snapshot Repository           http://127.0.0.1:8080/nexus/content/repositories/snapshots/                          ...     Maven区别对待release版本的构件和snapshot版本的构件,snapshot为开发过程中的版本,实时,但不稳定,release版本则比较稳定。Maven会根据你项目的版本来判断将构件分发到哪个仓库。
  • 38. Maven高级应用-分发构件至远程仓库(2)一般来说,分发构件到远程仓库需要认证,如果你没有配置任何认证信息,你往往会得到401错误。这个时候,如下在settings.xml中配置认证信息:        ...                           webx           admin           admin123              …            ...     需要注意的是,settings.xml中server元素下id的值必须与POM中repository或snapshotRepository下id的值完全一致。将认证信息放到settings下而非POM中,是因为POM往往是它人可见的,而settings.xml是本地的。
  • 39. Maven高级应用-约定优于配置(1)-build.xml simple example build file
  • 40. Maven高级应用-约定优于配置(2)-遵循约定的pom.xml     4.0.0     org.sonatype.mavenbook     my-project     1.0    maven做到这么简单,是有条件的,条件就是你要遵守Maven约定。pom.xml所在的目录应为项目的根目录,假设该目录为${proj-dir},那么Maven有以下假设: ${proj-dir}/src/main/java —— 存放项目的.java文件。 ${proj-dir}/src/main/resources —— 存放项目资源文件,如spring, hibernate配置文件。 ${proj-dir}/src/test/jave —— 存放所有测试.java文件,如JUnit测试类。 ${proj-dir}/src/test/resources —— 测试资源文件。 ${proj-dir}/target —— 项目输出位置。运行一条mvn clean package命令,Maven会帮你清除target目录,重新建一个空的,编译src/main/java类至target/classes,复制src/main/resources的文件至target/classes,编译src/test/java至target/test-classes,复制src/test/resources的文件至target/test-classes;然后运行所有测试;测试通过后,使用jar命令打包,存储于target目录。Maven做的事情一点也不少,只是都对用户隐蔽起来了,它只要求你遵循它的约定。
  • 41. Maven高级应用-约定优于配置(3)-个性化的pom.xml 4.0.0 org.sonatype.mavenbook my-project 1.0 src/java src/test output/classes output/test-classes target/jar 很显然,Maven允许你自定义,比如这个例子中,Maven就被配置成从src/java目录寻找源码,编译class文件至output/classes,从src/test寻找测试源码,编译至output/test-classes目录,最后,打包jar文件至target/jar目录。Maven允许你这么做,但不推荐你这么做。因为一旦你使用这种自定义,习惯Maven约定的人一开始会觉得奇怪,src/main/java目录去哪里了?target下面怎么没有我要的jar文件?这些都造成了无谓的交流成本提高。只有一些特殊的情况,这些自定义手段能帮你解决实际的问题,比如你在处理遗留代码,你没办法改变源码目录结构,这个时候只有让Maven妥协。
  • 42. Maven高级应用-约定优于配置(4)-约定默认值目录src/main/java java源码目录 目录src/main/resources 资源文件目录 目录src/test/java 测试java源码目录 目录src/test/resources 测试资源文件目录 目录target 打包输出目录 目录target/classes 编译输出目录 目录target/test-classes 测试编译输出目录 目录target/site 项目site输出目录 目录src/main/webapp web应用文件目录(当打包为war时),如WEB-INF/web.xml jar默认打包格式 *Test.java Maven只会自动运行符合该命名规则的测试类 %user_home%/.m2 Maven默认的本地仓库目录位置 中央仓库 Maven默认使用远程中央仓库:http://repo1.maven.org/maven2 1.3Maven Compiler插件默认以1.3编译,因此需要额外配置支持1.5 下面总结一些Maven的默认值,也就是说,虽然你没做什么配置,但是你应该知道Maven假设它们成立,也就是所谓的“约定”,这些约定都在超级pom中设定。
  • 43. Maven常见问题打包源代码 更改编译级别 跳过/忽略单元测试 编译错误
  • 44. Maven常见问题-打包源代码mvn source:jar mvn source:test-jar配置中指定了phase为compile,意思是在生命周期compile的时候就将源文件打包,即只要执行的mvn命令包括compile这一阶段,就会将源代码打包。同样,phase还可以指定为package、install等等
  • 45. Maven常见问题-更改编译级别Maven默认编译级别为1.3,修改编译级别需要在pom.xml中添加compiler插件
  • 46. Maven常见问题-跳过/忽略单元测试mvn install –Dmaven.test.skip=truemvn test -Dmaven.test.failure.ignore=true
  • 47. Maven常见问题-编译错误原因: UltraEdit、EditPlus等编辑器会在utf8编码格式的文件开头添加utf8标识,使文件的编码格式由utf8变为utf8+BOM,导致maven编译时将utf8标识误认为非法字符。 解决办法: 通过UltraEdit、EditPlus等编辑器将utf8+BOM编码格式的文件改为utf8格式,去掉文件开头的utf8标识即可。
  • 48. Maven仓库管理工具Artifactory Nexus
  • 49. 相关网站maven官网:http://maven.apache.org/ maven中心仓库:http://repo2.maven.org/maven2/ maven权威指南中文版:http://www.sonatype.com/books/maven-book/reference_zh/public-book.html maven仓库搜索:http://www.mvnrepository.com/
  • 50. 谢谢!