显示标签为“maven”的博文。显示所有博文
显示标签为“maven”的博文。显示所有博文

2009年3月13日星期五

mvn有时让人费解

在运行mvn compile时,总是出错:
The plugin 'org.apache.maven.plugins:maven-resources-plugin' does not exist or no valid version could be found

以前用还好好的,为什么突然报错,配置错了(这期间没有修改)。再使用-U试试,又可以了:
mvn -U compile

-U参数的含义:
-U,--update-snapshots Forces a check for updated releases and
snapshots on remote repositories
呵呵,在编译时需要联到remote服务器上,虽然我在本机上架上一个伺服器,作为maven中心库的代理。在每次编译时,即使不使用到网上的库(本地伺服器中心已经有),但还要使用网络,若网络不通,编译等操作不成功。

2008年12月27日星期六

使用maven2构建多环境

这种解决办法有别于maven的官方解决方法。


软件的开发,一般有3个环境:开发(dev)、测试(test)、生产(live)。
dev:开发人员在本机上开发,如也许数据库是本机上,log的级别一般在DEBUG;
test:测试专用,完成构建工作,有专门的测试的库(不允许使用生产环境的库),log级别一般在INFO;
live:实际部署的环境。

每种环境有作一些差异,尤其对于dev来说,每个开发人员环境差异就更大,所以每个开发人员都可以配置自己独特的环境。在每种环境下只需要针对该环境配置一次即可,不需要在每次环境切换时修改配置。

这种情况下,使用maven很容易解决上述问题。文字描述比较难懂,还是例子来说话。

下面的工作前提是安装好maven2。在某目录下创建2个工程,这里只是例子组织名以及工程名根据自己喜好设置:
  • mvn archetype:create -DgroupId=com.kiwiyard.shamrock -DartifactId=shamrock-namenode-dal
工程名:shamrock-namenode-dal,后面简称为dal
创建好工程,即创建一个同工程名的目录,所有工程信息都在此目录下,
并自动创建好java的package:com.kiwiyard.shamrock
  • mvn archetype:create -DgroupId=com.kiwiyard.shamrock -DartifactId=shamrock-namenode-service
创建一个shamrock-namenode-service工程,简称为service。

再在此目录下创建一个pom.xml和一个和该项目相关的环境配置文件shamrock.properties(文件名可自己随意取),后面会用到。一切完成后目录的结构如下:

|--shamrock.properties
|--pom.xml
|--shamrock-namenode-dal
****|--pom.xml
|--shamrock-namenode-service
****|--pom.xml

需要说明的是service依赖dal,service和dal都继承一个父pom,就是顶层的pom.xml。

  • 父pom.xml内容如下:
<project xmlns="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.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kiwiyard.shamrock</groupId>
<artifactId>shamrock</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>

<modules>
<module>shamrock-namenode-dal</module>
<module>shamrock-namenode-service</module>
</modules>

</project>


分别到dal和service目录下,创建目录src/main/resources和src/test/resources。到dal的src/main/resources/下创建一个数据库文件datasource.properties,因为在dal里需要访问数据库,这正是我们需要对不同情况处理的。

分别在dal和service的
src/main/resources和src/test/resources下创建log4j.properties的日志配置文件。
  • dal的pom.xml内容如下:
<project xmlns="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.0 http://maven.apache.org/maven-v4_0_0.xsd">

<parent>
<groupId>com.kiwiyard.shamrock</groupId>
<artifactId>shamrock</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<artifactId>shamrock-namenode-dal</artifactId>
<packaging>jar</packaging>
<name>shamrock-namenode-dal</name>
<url>http://www.kiwiyard.com</url>

<dependencies>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
<scope>run</scope>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>run</scope>
</dependency>

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.13</version>
<scope>run</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<directory>${basedir}</directory>
<filters>
<filter>../shamrock.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>

</project>

注意这里的
<directory>${basedir}</directory>
若不加这个配置,很难指向上级目录里的文件,maven对下面的解析就行不通:
<filter>../shamrock.properties</filter>
就解析成:dal工程所在的目录/../shamrock.properties,这个解析有点傻,当然就无法识别。加上上面的配置就可以了,不会出现上面情况。 就这个问题害的我花了不少时间。
  • service的pom.xml内容如下:
<project xmlns="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.0 http://maven.apache.org/maven-v4_0_0.xsd">

<parent>
<groupId>com.kiwiyard.shamrock</groupId>
<artifactId>shamrock</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<artifactId>shamrock-namenode-service</artifactId>
<packaging>jar</packaging>
<name>shamrock-namenode-service</name>
<url>http://www.kiwiyard.com</url>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.kiwiyard.shamrock</groupId>
<artifactId>shamrock-namenode-dal</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.13</version>
<scope>run</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

</dependencies>

<build>
<directory>${basedir}</directory>
<filters>
<filter>../shamrock.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>

</project>

dal和service的log4j.properties配置内容如下:
log4j.rootCategory=${log4j.level}, stdout
log4j.appender.stdout=${log4j.appender}
log4j.appender.stdout.layout=${log4j.layout}
log4j.appender.stdout.layout.ConversionPattern=${log4j.pattern}

dal的datasource.properties(其实也可以是其它类型的文件如spring的datasource配置文件)。内容如下:
username = ${db.name}
password = ${db.password}
url = ${db.url}
driverClassName = ${db.driver}
#connectionProperties
defaultAutoCommit = true
#defaultReadOnly
#defaultTransactionIsolation
#defaultCatalog
initialSize = ${db.initialSize}
maxActive = ${db.maxActive}
maxIdle = ${db.maxIdle}
minIdle = ${db.minIdle}
maxWait = ${db.maxWait}
#validationQuery
#testOnBorrow
#testOnReturn
#testWhileIdle
#timeBetweenEvictionRunsMillis
#numTestsPerEvictionRun
#minEvictableIdleTimeMillis
poolPreparedStatements = true
maxOpenPreparedStatements = 0

在这里的log4j和datasource的配置是关键,对于${}符号就是变量,是在不同的环境需要替换成和环境匹配的值。这些匹配的值就需要根据每种环境配置,配置文件为
shamrock.properties,内容如下:
#日志配置================================================
log4j.level = DEBUG
log4j.appender = org.apache.log4j.ConsoleAppender
log4j.layout = org.apache.log4j.PatternLayout
log4j.pattern = %5p %c{2}- %m%n

#数据库配置================================================
db.name = 用户名
db.password = 密码
db.url = jdbc:mysql://dev.kiwiyard.com:3306/shamrock?useUnicode=true&characterEncoding=ut8
db.driver = com.mysql.jdbc.Driver
db.initialSize = 2
db.maxActive = 10
db.maxIdle = 8
db.minIdle = 2
db.maxWait = 2

这里配置的就是环境变量,在编译时就根据这些值替换数据库配置和log4j配置。

项目工程的根目录下(就是顶极pom.xml存在的目录下)
#>mvn resources:resources
再到dal和service
工程的target/classes下,看看其datasource.properties和log4j.properties的内容已经被替换。


例子好像很长,
其实就是几个配置文件里一些关键参数需要替换,配置的关键地方用粗题标出。只要你对maven2有一点了解,理解起来就不是难题。这种实现方式个人觉得比官方的对同一文件创建多个针对环境的版本要好,如按官方办法datasource可能就有datasource.dev、datasource.test、datasource.live这么几个文件,显得很罗嗦。

还有若把你的工程放入svn中(99%是这样),最好不要把和环境相关的信息提交到svn上,如开发者A把自己的提交后,开发者B拿到后很可能要修改才能使用,这些配置之适合特定的个体,不要分发出去。如下是一种解决办法,把指向环境配置文件shamrock.properties(以此为例),改为.shamrock.properties(注意文件名前加了一个点)。
<filter>../shamrock.properties</filter>
=>
<filter>../.shamrock.properties</filter>
shamrock.properties是受svn版本控制的,他代表一些配置的共性,也可能是由项目主管提交的一份参考配置。

其它开发人员拿到shamrock.properties后,cp
shamrock.properties .shamrock.properties,自己所有的配置就可以在.shamrock.properties上改动,不用把该文件提交到svn上,所有人的环境配置都在本地,不会找成混乱


官方的另外一种方式,你可以参考对照2种方式:
http://maven.apache.org/guides/mini/guide-building-for-different-environments.html

2008年12月19日星期五

maven2创建一个eclipse工程,设置M2_REPO

用maven创建一个支持eclipse的工程非常简单,在mvn的项目目录下:
mvn eclipse:eclipse
即可。

再打开eclipse->import->General:Existing Projects into Workspace->包含该工程的目录,eclipse会自动搜寻到刚刚创建的eclipse工程。

导入工程后会发现eclipse报"找不到M2_REPO"的错误,其实这是个环境变量,就是指向你的本地库。在linux和windows下都是$HOME/.m2/repository

把该变量加入eclipse,方法为:
Window -> Preferences -> Java -> Build Path -> Classpath Variables
-> New,Name输入M2_REPO,Path输入/home/名用户/.m2/repository(以我的为例)。确认后错误消失。

2008年12月9日星期二

用maven构建一个小型的复杂项目

若你还对maven2不太了解,快速获得一些信息。
http://maven.apache.org/guides/getting-started/index.html

本来想写个多个工程的项目,写了一点发现和“getting-started”的“How do I build more than one project at once?”类似(只不过是10来个工程的项目),所以作罢。


--------------------------------------------------------------------------
在某个目录下创建工程

mvn archetype:create -DgroupId=com.kiwiyard.shamrock -DartifactId=shamrock-clientSDK-java
工程名:
shamrock-clientSDK-java
创建好工程,创建一个目录同工程名,
并自动创建好java的package:com.kiwiyard.shamrock
在package下还有一个测试类,基本没用直接删除。



构建多个项目可以参考下面的文章,还可以实现不同的环境:

使用maven2构建多环境

2008年12月8日星期一

构建公司的maven私服中心

1 在windows下搭建
1.1 下载apache-maven-2.0.9
配置环境变量,我是直接放在c盘下,变量及其值如下:
mvn_home C:\apache-maven-2.0.9
Path .;%mvn_home%\bin #添加的信息
打开命令窗口,键入:mvn -v,若出现版本信息,则配置成功。

1.2 下载安装nexus
到http://nexus.sonatype.org/downloads/下载nexus-1.1.1-bundle.zip,解压后会产生一个目录nexus-webapp-1.1.1sonatype-work。到该目录下的\bin\jsw\windows-x86-32里,双击InstallNexus.bat安装,把nexus添加到服务里去,每次系统启动后就启动nexus服务。
双击Nexus.bat运行该服务,要30秒的样子。

1.3 访问
http://localhost:8081/nexus/index.html
管理的用户:admin
默认密码:admin123
登陆后修改此信息。

1.4 配置nexus
选择Administrator下的Repositories,如图:


在3个中心代理库分别:右键->reindex,并把这3个库的属性“Download Remote Indexes”,设置为“True”。
说明:我们正在建的库就是代理上面设置的3个库,一般一个公司搭建一个这样的中心库即可,避免开发人员乱下载包,造成项目混乱。若在该“公司中心库”没找到的自动到远程库下载。

1.5 配置mvn
个人开发者的本地库是在$HOME/.m2/repository下,若你不做任何设置,maven会自动从远程库加载依赖的包,不会从“公司中心库”加载。为了速度也是为了开发上的管理,要求必须切只能从“公司中心库”加载依赖包到本地库。设置如下:
在.m2目录下添加文件settings.xml,内容如下(google不能贴xml,改下载文件):
https://sites.google.com/site/zhuxuezheng/fen-xiang-haha
注:把里面的所有的localhost改写为前面搭建“公司中心库”的服务ip(即按装nexus的机器)。

1.6 尝试
在你的机器上,某个目录下运行:
mvn archetype:create -DgroupId=org.xyz.app1 -DartifactId=simple -DpackageName=org.xyz.app1
是不是从服务器下载东西,注意看日志。

再到中心库的sonatype-work目录下,看看其sonatype-work\nexus\storage\central-m1下是否下载了很多。你的本地库的包就是从此来,由公司中心库代理下载。所有的程序员都从此下载包,公司内部速度当然有保障。

可再访问,选择Browse Repositories,挨个Repositorie点击看看,maven central会有很多。
http://localhost:8081/nexus/index.html


2 在ubuntu下搭建
2.1 安装maven2
若输入$ mvn -v 没有任何版本信息,则说明没有安装:
sudo apt-get install maven2
$ mvn -v 会有版本信息输出。

2.2 安装nexus
到http://nexus.sonatype.org/downloads/下载nexus-1.1.1-bundle.tar.gz。
详细的具体配置参看(《maven权威指南》),不一定会成功,若不成功请参考我在下面写得:
http://books.sonatype.com/maven-book/reference_zh/repository-manager.html

这里做简要叙述。
在某个目录下解压(我的是$HOME/tools/) $ tar xvzf nexus-1.0.0-beta-3-bundle.tgz,产生nexus-wepapp-1.1.1和sonatype-work目录。nexus-wepapp-1.1.1/bin/jsw/linux-x86-32/nexus start,启动nexus,但出错:
NO JSP Suport for /nexus, did not find org.apache.jasper.servlet.JspServlet以及io等等一堆错误。
反复尝试各种方法都不行,后来把nexus-1.0.0-beta-3-bundle.tgz复制到windows下,解开运行,完全可以。一时很费解,大半天就这样溜走。无意中发现我的windows上是jdk6,而ubuntu是自带的jdk5,于是就在ubuntu上再install一个jdk6,好开始:
$sudo apt-get install sun-java6-jdk
时间比较长等。
安装完毕,把系统默认的jdk5设置成jdk6,只需一个命令即可:
$sudo update-alternatives --config java
选则sun-java6,就是刚装的。

这时再运行nexus,好使了,都说nexus 10分钟就能搭好,我费了10小时,呵呵。

总算好了,赶快试试:
http://localhost:8081/nexus/

2.3 设置一下
不能老去安装目录下运行,如:/home/.../nexus start|stop,设置一个简单的方法。如:
$cd /usr/bin
$sudo ln -s /home/用户名/tools/nexus-webapp-1.1.1/bin/jsw/linux-x86-32/nexus nexus
这样做了个连接,以后不管在那个目录下就可以使用:
$nexus start|stop

后面的操作就和windows一样。