分类: Java
2009-11-18 14:39:36
Eclipse需要知道Maven的本地仓库的路径。所以,类路径变量M2_REPO必须设置。执行以下命令:
mvn -Declipse.workspace=
|
你也可以在eclipse内定义一个新的classpath变量:从菜单条,选择Window>Preferences,选择java>Build Path>Classpath变量页。进入eclipse,导入workspace下面的Sample Project。由于缺少MAVEN_REPO变量,Eclipse提示编译失败。在Eclipse的Preferences – Java - Build Path - Classpath Variables中添加名为MAVEN_REPO的变量,指向D:\maven\local\repository。
如果想让eclipse支持直接运行maven的goal,可以安装mavenide插件。
可能需要从eclipse执行一些maven goals,这可以通过配置外部装载器实现。为eclise添加一个变量,指向本地maven的可执行文件(mvn.bat/mvn)。从菜单条,选择Window>Preferences,选择Run/Debug>String Substitution,增加一个新的变量,比如maven_exec。当你设置新的外部装载器(丛菜单条,选择Run>External Tools,选择Program),你可以在位置字段引用刚才定义的maven_exec。进一步,引用project_log作为工作目录,指定所选的maven goals作为参数,比如eclipse:eclipse。更多的信息请参考eclipse的帮助。
问题:如果插件可以产生变量和runner可能会好一点。
如果你有一个单模块的简单java项目,使用eclipse将十分简单。为了从你的POM产生eclipse项目文件,执行以下命令:
mvn eclipse:eclipse |
如果你已经使用eclipse创建或者检出了项目,你只需在workspace中刷新项目。否则,你必须将项目导入eclipse工作空间(从菜单条选择File>Import>Existing Projects into Workspace)。在后面的例子,项目(目录)不应在你的workspace,因为eclipse可能导致错误,特别是你将eclipse作为scm客户端时。
Due to the workspace idea many eclipse users are used to a flat layout and therefore want to keep this structure, which is possible but not recommended. Actually, the only reason for a is the possibility to checkout and edit the parent POM without checking out the whole project. The following sample shows how to handle maven multiple module projects with eclipse while keeping the .
假设eclipse是你的SCM客户端,这个例子将告诉你如何设置一个新的多模块项目。
1. 设置一个新的叫做step-by-step的workspace,并且象上面所述增加M2_REPO类路径。
2. 打开命令行shell,并且切换到新建的工作空间(workspace)目录。
3. 从命令行使用archetype插件新建一个maven项目
mvn archetype:create -DgroupId=guide.ide.eclipse -DartifactId=guide-ide-eclipse
|
4. 在step-by-step工作空间,使用eclipse创建一个新的简单项目guide-ide-eclipse(从菜单条,选择File>New>Project,选择Simple>Project)。Eclipse会为你的guide-ide-eclipse项目创建一个简单的.project文件,你应该能够看到一个pom.xml文件。
5. 删除src文件夹,并且打开pom.xml文件,将父项目的packaging改为pom。
|
问题:mvn eclipse:eclipse也许应该为pom packaging类型产生一个简单的.project文件。
6. 从命令行切换到guide-ide-eclipse项目路径,并且创建一些模块:
cd guide-ide-eclipse mvn archetype:create -DgroupId=guide.ide.eclipse -DartifactId=guide-ide-eclipse-site mvn archetype:create -DgroupId=guide.ide.eclipse.core -DartifactId=guide-ide-eclipse-core mvn archetype:create -DgroupId=guide.ide.eclipse.module1 -DartifactId=guide-ide-eclipse-module1
|
7. 将新建的模块添加到父pom中。
|
8. 在新建的模块的POMs中添加parent。
|
9. 添加模块间依赖:
|
10. 把项目安装到本地仓库,并且产生eclipse文件:
mvn install mvn eclipse:eclipse |
11. 使用eclipse的团队开发支持(从context菜单选择Team>Share Project)检入项目。记住,不要检入产生的eclipse文件。如果使用CVS,你因该在每个模块有一个.cvsignore文件,内容如下:
target .classpath .project .wtpmodules |
即使是父项目,也应该有.cvsignore文件。当你从repository检出项目时,Eclipse自动生成新的简单的.project文件。
问题:插件应该可选的产生.cvsignore文件。
现在,你有不同的处理选项。如果你同时工作于所有模块,你应该具有eclipse的项目依赖,而不是二进制依赖,你可以设置一个新的workspace,并且从step-by-step/guide-ide-eclipse中导入。记住,你必须先删除父项目的.project文件。结果和从命令行检出整个项目相同,运行mvn eclipse:eclipse并且最后把项目导入到你的eclipse工作空间。两种方式都可以使用eclipse同步你对项目的修改。
对于有许多人参与的大项目而言,检出所有模块并且保持更新是一件相当乏味的工作。特别是你只对其中某(几)个模块感兴趣。这种情况,使用二进制依赖更合适。只要在eclipse上检出你需要工作的模块,然后为每个模块运行mvn eclipse:eclipse。当然所有用到的artifacts在你的maven仓库中必须可用。
扁平项目布局:
有可能将父POM从自己的目录搬移到和模块相同级别的目录。
1、在guide-ide-eclipse下创建一个名为guide-ide-eclipse-project的新目录,并且将父POM搬移到这个目录。
2、对父POM修改模块引用:
|
问题:发布(releasee)插件不支持扁平结构。
Maven 2是以构建生命周期为中心概念的。这意味着构建和分发一个特定的artifact是被清晰定义的。
项目有生命周期(lifecycle),生命周期中有一系列阶段,每个阶段都和一组goals绑定,goals由插件提供。
对于构建项目的人来说,只要学习一些命令就可以来构建所有的Maven项目,并且POM保证他们能获得期望的结果。
对于一个项目来说,会可能使用以下公共生命周期阶段:
Ø Validate – 验证项目正确性,以及所有必要的信息是否齐备;
Ø Compile – 编译项目源代码;
Ø Test – 使用单元测试框架测试编译过的源代码。这些测试无需代码被打包或者部署;
Ø Package – 将编译过的代码打包,如JAR;
Ø Integration-test – 为了集成测试能够进行,处理和部署应用到合时的环境;
Ø Verify – 检查和检验package是否有效并且符合质量要求;
Ø Install – 将package安装到本地仓库,供本地其他项目使用(作为依赖项);
Ø Deploy – 在集成或者发布环境中,将最终的package拷贝到远程仓库,供其它开发人员或者项目共享。
记住,对于每个阶段,所有它之前的生命周期阶段都会执行,所以,你在命令行只要指定最后的那个就行。比如:
mvn install |
如果执行这个命令的话,会编译、测试、打包、校验和安装package到本地仓库。
同时,同样的命令可以在多模块场景中使用。比如:
mvn clean install |
这个命令会遍历所有的子项目,对每个子项目执行clean和install(包括所有install之前的阶段)。
使用构建生命周期是比较简单的,但当你为一个项目创建一个Maven 构建时,如何将任务分配给那些构建阶段呢?
首先,是设置项目的packaging,默认为jar,所以不管你是否指定,packaging都会发生。每个packaging包含一系列绑定到特定阶段的goals。比如,对于JAR,会有以下goals绑定到生命周期:
阶段 |
Goal |
Process-resources |
Resources:resources |
Compile |
Compiler:compile |
Precess-test-resources |
Resources:testResources |
Test-compile |
Compiler:testCompile |
Test |
Surefire:test |
Package |
Jar:jar |
Install |
Install:install |
Deploy |
Deploy:deploy |
这是标准的一组绑定;然而,有些打包处理不同,比如,一个项目仅仅有元数据,那么只要绑定install和deploy阶段。
记住,对于一些packaging类型,你需要在pom.xml文件的build节包含特定的plugin。一个例子就是Plexus插件,它提供了plexus-application和plexus-service packaging。
第二种对阶段增加goals的方法就是在项目中配置插件。插件包含每个goal绑定到哪个阶段的信息。记住,仅仅增加插件还不够,你必须同时指定你需要的goals。
这些配置的goals将会加入到由packaging绑定到生命周期的goals。如果绑定到特定阶段的goal超过一个,那么来自packaging的goal会先执行,然后执行在POM配置的goal。可以通过executions元素控制特定goals的顺序。
比如,Modello插件将modello:java绑定到generate-souces阶段,使用Modello插件从模型产生源代码,你必须将以下内容加入到POM的plugins节:
...
... |
你可能会觉得奇怪,那儿为什么会有executions元素,这可以让你在需要时,使用不同的配置多次运行相同的goal。不同的execution可以给于不同的id,这样当用于继承或者应用profiles时,你就可以控制goal配置是否合并或者变成附加的execution中。
当有多个executions匹配一个阶段(phase)时,他们以POM中指定的顺序执行,来自继承的executions首先运行。
对于modello:java,它只对generate-source阶段(phase)有意义。不过某些goals可以用于多个阶段,并且没有默认值,对于这种情况,你可以(必须)自己指定阶段(phase)。比如,假设有一个goal touch:timestamp,用于将当前时间显示到文件中,你需要在process-test-resources阶段用它来指出测试是何时开始的,可以像下面那样配置:
...
... |
Now we want to use this library in a Web application. For simplicity, our Web application will consist of a JavaServer Pages (JSP) file that directly invokes the HotelModel
class. First, we create a new Web application project using the archetype
plug-in:
现在,要将此类库应用到一个web应用程序。为了简单,我们的web应用程序将由一个jsp文件直接调用HotelModel类。首先,我们使用archetype插件创建一个新的web应用项目:
|
Next, we need to include our business logic JAR in this application. All we need to do is to add a dependency to the new pom.xml, pointing to our HotelDatabase
component:
接着,我们需要将业务逻辑JAR包含进此web应用程序。我们所需做的事情就是加入一个依赖项到此新的pom.xml文件,并指向我们的HotelDatabase组件:
|
Now we implement the main (and only) JSP page. It simply lists the available cities and, if a city is chosen, lists the corresponding hotels:
现在,我们实现主要的JSP页面。它仅简单的列出所有可用的城市,如果选择了某个城市,就列出相应的宾馆:
Choose a destination
Please choose a city:
|