阅读:154203次   评论:103条   更新时间:2011-06-01    
工欲善其事,必先利其器。在我们深入Struts2之前,我还是想废一些口舌来讲述一下开发环境的搭建。每个人都会根据自己的习惯来搭建自己的开发环境。开发环境是否便捷,也将直接影响开发的效率。所以对于开发环境已经非常熟悉的朋友可以直接忽略这篇文章。而我在这里给大家介绍一下我的开发和调试环境的搭建,之后所有的章节的代码,也都将建立在这个开发环境之上。

在编写J2EE程序的时候,我们往往需要一个Web容器进行调试,比较常见的Web容器是Tomcat,在Eclipse等IDE中,也有很多针对Tomcat的插件支持,使你可以很轻松地在Tomcat上调试你的J2EE应用。而我所使用的Web容器是更加轻量级的Jetty。利用它进行J2EE的开发和调试,甚至只需要依赖Jetty的jar包即可。

搭建最简单的开发环境 Top

首先我们来看看如何搭建最简单的J2EE项目的开发环境。

1. 我们需要建立的一个空的J2EE项目的目录结构



在这里,我简单解释一下这些目录的作用:

src(source folder):存放所有的Java源代码。
conf(source folder):存放所有的配置文件。
test(source folder):存放所有的Java测试代码和调试代码。
web:web项目的根目录,下面有WEB-INF目录以及在此之下的classes和lib目录。classes目录将会成为所有的source folder的编译对象目录,而lib目录则存放项目所依赖的jar包。
lib:也存放jar包,这些jar包可能仅仅在开发调试时依赖,项目本身则不依赖这些jar文件。

2. 编写IDE相关的文件

在这里,你还能看到classpath文件和project文件。这两个文件是导入到eclipse中所必须的文件,是我为eclipse工程而写的文件。如果你使用其他IDE,可能需要自行编辑与其他IDE相关的项目文件。

在建立了这些目录结构后,你就可以将其导入到eclipse中作为eclipse的工程了。



3. 加入相关调试所需要的jar包,并指定classpath

接下来,我们把Jetty所需要的jar包copy到lib目录下,并在IDE中指定classpath。



4. 添加Jetty启动类

在test下建一个runtime的目录,并添加Jetty启动类。

package runtime;

import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.webapp.WebAppContext;

/**
 * Jetty Server starter. Use embedded mode.
 * 
 * @author Downpour
 */
public class JettyStarter {

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		long begin = System.currentTimeMillis();
		Connector connector = new SelectChannelConnector();
		connector.setPort(Integer.getInteger("jetty.port", 8080).intValue());

		WebAppContext webapp = new WebAppContext("web", "/struts-sample");
		webapp.setDefaultsDescriptor("./test/runtime/webdefault.xml");
		
		Server server = new Server();
		server.setConnectors(new Connector[] { connector });
		server.setHandler(webapp);
		server.start();
		System.out.println("Jetty Server started, use " + (System.currentTimeMillis() - begin) + " ms");
	}
}


如果此时,你在WEB-INF下有web.xml,那么你就可以执行上面这个Jetty的启动类。



5. 启动、调试、测试

执行了Jetty的启动类后,可以看到启动界面的日志:

15 [main] INFO org.mortbay.log - Logging to org.slf4j.impl.SimpleLogger(org.mortbay.log) via org.mortbay.log.Slf4jLog
15 [main] INFO org.mortbay.log - jetty-6.1.7
1109 [main] INFO org.mortbay.log - Started SelectChannelConnector@0.0.0.0:8080
Jetty Server started, use 1547 ms


这表示你已经成功启动了Jetty作为你的Web服务器。当然,你可以使用Debug模式来执行Jetty类,这样就进入了调试模式,你可以在代码中设置断点进行调试。

在这里,还有一点需要简单提一下,默认情况下,Jetty会在windows上使用缓存,所以会把js,css等文件进行锁定,使你无法编辑。为了解决这个问题,需要设置一些默认参数。这里,我们可以使用google大法,已经有朋友为我们解决了这个问题:

http://www.blogjava.net/alwayscy/archive/2007/05/27/120305.html

所以,我在runtime的同级目录建立了一个webdefault.xml文件,并且指定Jetty使用该文件作为默认的参数设定。

【小结】
在上面我介绍了我个人的开发调试环境,这种开发环境的好处可能有一下这些:

1. 开发环境不依赖于任何IDE或者相关的插件,只需要运行Java文件即可进行调试。(当然,你可能需要编写IDE相关的project文件来获取IDE的工程支持)

2. 开发环境不依赖于任何外部的Web服务器,与环境无关,所以无论将项目迁移到哪里,都可以直接运行。

3. 不需要开发人员额外学习如何搭建开发环境,开发环境已经内置,降低了开发人员的学习成本。

完善Library的管理方式 Top

在上面搭建环境的过程中,我们发现,Library的管理存在着一定问题。这个问题主要表现为:

1. 不容易做Library的版本管理。如果Library的版本需要升级,那么我们不得不重新copy一份新的jar包,并且借助IDE重新指定项目的classpath。这种劳动,对于一个项目还可以接受,如果你有10多个项目,那么jar包的复制工作会让你很头疼。

2. 每个项目都会有Library的副本。这一点让人非常恼火。实际上,对于一个公司或者一个项目组而言,使用的技术体系基本不变。然而,每个项目的Library却是分开的。不仅如此,每个项目都要从svn中下载大量的相同的Library文件,给我们的硬盘造成极大的空间浪费。对于那些频繁使用Branch的项目来说,这些Library的下载简直就是噩梦。

所以,我们需要一个集中式的Library管理方式。而这一点曾经在Javaeye的海阔天空版激烈得讨论过使用maven来进行管理还是自行管理。

Readonly 写道

共享类库可以用IDE reference project解决,公司内部项目给常用的lib建立一个project,从CVS上check out,其他工程项目都依赖这个project就可以了,ant build也直接引用这个项目的jar就可以,项目体积照样只有几百K。

——一个讨厌ant,更加讨厌maven的人


我比较赞同Readonly老大的说法而倾向于自行管理。maven这样的高级货,偶实在是用不来啊。那么我们就来看看如何使用共享类库来进行Library管理。


1. 首先建立一个共享类库


建立一个共享类库,将项目中需要共享的Library进行恰当的分类。同时,为每个加入到Library中的jar包进行统一的格式化的命名方式。例如:spring/spring-2.5.5.jar等等。这样的好处在于,一旦jar包的版本有更新,可以加入新的jar包而保留原来的。在项目中,就可以通过引用不同版本的jar包来对Library进行版本管理。

以下就是我个人建立的一个共享类库,大家可以参考:

svn://www.demo2do.com/library

2. checkout共享类库,并将其导入到IDE中作为一个Library工程



3. 为你的项目指定classpath,引用的jar包存在于Library工程中



在这里,我们可以看到,原来项目中的lib目录被删除,jar包也被删除。在项目中所引用的jar包是Library项目中的jar包。

【小结】
完成了上述所有的步骤之后,Library就被集中管理起来,而每个项目也不会再变得那么庞大。当然,开发环境的搭建完全取决于个人的习惯,所以使用各自喜欢的方式吧,不要让环境问题束缚你们的手脚。
评论 共 103 条 请登录后发表评论
73 楼 lichaosmile 2010-01-13 17:07
第一次看到用Jetty做服务器,在网上临时学习了一下,基本都是将项目复制到webapps下面,在运行java -jar start.jsp就行了。所以我特别纠结得一点是,像楼主那样写一个Jetty启动类用什么作用,难道这样可以不用将项目手动复制到webapps下面?如果是这样,那我得项目如何部署到Jetty呢?求解,谢谢!
72 楼 sing4j 2009-12-28 09:54
嗯,这种方式不错。

学习。
71 楼 xici_magic 2009-12-16 15:21
太乱了 新手看的话也许会看不明白。
70 楼 金家寶 2009-12-10 17:54
jerry 写道
引入 Jetty 是败笔

让我联想到一本学习Hibernate的书,各种工具的运用扰乱了头绪。
69 楼 jerry 2009-12-03 14:52
引入 Jetty 是败笔
68 楼 adminsun 2009-11-26 13:03
67 楼 achenbj 2009-11-23 11:15
很不错,我之前也是用的这种结构的,使用maven编译,Junit测试,TDD开发模式。
66 楼 liangrun 2009-11-09 10:01
感觉很不错!
65 楼 ddh9504 2009-10-22 18:23
1.一个是maven管理,一个自行管理,看清本质之后,其实是一样的!
方便之处有,依赖的增加也未必是好事!
2.开发环境的搭配对于个每个开发者来说都可以自创,但在一个团队来说,应该统一!
不排除你的环境搭配得简单,好用!
3.如果这贴是教初学者的话,应该更加详细一些,谢谢!
64 楼 yqin 2009-10-06 21:14
正在学习struts 可以参考一下 谢谢啦!
63 楼 java_web 2009-07-15 11:31
楼主的东西很不错啊
给我很大的帮助
为了方便我已经把东西都下载到本地了
谢谢楼主
62 楼 myseo 2009-07-03 09:49
收藏了,THX
61 楼 folishwood 2009-06-25 15:14
几篇文章读下来,启发挺大的。
60 楼 crabboy 2009-06-13 12:56
很好的文章,收藏了。
59 楼 lucky16 2009-05-25 16:00
确实多好的!


简单实用!

但是在开发高级项目中我们还是这种模式吗?????
58 楼 javajdbc 2009-05-20 07:00
不错 收藏了
57 楼 anky_end 2009-05-11 14:57
ant还是比较简单的;maven委实复杂了些,看情况吧,我觉得主要还是适度就好。

楼主的做法俺也用过,确实是个不错的做法,虽然功能未必强大,但是简单好学。

如果真的需要高级的功能复杂的要求,共享project满足不了就用maven吧。
比如ant,有简单的用法,但是复杂的用法也可以写一本书的,多数时候我们只用到其中最简单的功能。
56 楼 jasstion 2009-04-14 18:00
我用的是NetBeans不过大概步骤差不多!
55 楼 cangwu 2009-03-11 11:02
如果基於maven,更完美
54 楼 it.go 2009-03-02 23:34
楼主的意思是介绍IDE工具的refrence功能,不过的确有心,但是对于项目管理来说,的确不算是最最好的解决方案,特别是对于一些绑定JAR版本,JDK的项目来说还存在一些险,比较适合初学者做例子,还值得推荐。不过还是有点矛盾,对于IDE来说比如myeclipse都集成了大部分的开源框架,都是自动化的,个人觉得没必要 。如果是公司做项目,自然都是用版本控制,最新代码在服务器上跑,自动更新。正如其他朋友说的,为这么几M在这里争论的确是没必要。本人喜欢用ANT。
53 楼 elvishehai 2009-02-16 15:26
都不能拉啊,直接发给我一个好吗?elvishehai@gmail.com 谢谢
52 楼 bei-jin-520 2009-02-12 15:56
不错。赞一个。
51 楼 风の使者 2009-02-09 09:50
你们还真的没事找事做,讨论那几M的空间。
jar包冲突我见过,例如你作poi写excel文件事,原来有的人用2.x写2003以下的版本,结果后来excel功能2003的版本无法满足,改成2007的升级poi3.x就带来了一个版本的程序无法使用,当然这也不一定不能用,假如你用ibm的jdk就没问题,用weblogic的jdk问题就出来的

还有你的文章没写到点........

还有ant mavan我都不会,呵呵!

“还有看来你公司同时让你处理几个项目,真没人性”
50 楼 downpour 2009-02-06 00:14
真不知道为什么hantsy为什么要在这个问题上纠缠不清,实在是不能理解。

你所谓的Library的兼容性和冲突,老实说,在现实环境中,我们还真没有碰到过。我真不知道到底是因为我们的程序员过于优秀,还是你个人对于Library的版本研究过了头。

拒绝和你讨论这类问题了,浪费时间和精力。

By the way,我语文很好,从小就拿作文比赛的名次。鉴于你再一次毫无根据得诋毁我的语文水平,我也再一次对你的人品表示鄙视。
49 楼 hantsy 2009-02-05 17:13
如果是保留多个版本,我原来说的,兼容性和风险依然存在,而且你这样做,包的依赖性和兼容性解决也完全个人判断,而不是maven那样完全让它自己来判断。
对于参与某一个项目来说,要下载svn那么多依赖,然后只添加一部分自己项目要用jar,资源也太浪费了。
还不如,利用maven repository, 用ant加上ivy, 也很容易配置起来,用到多少下载多少。
48 楼 downpour 2009-02-05 14:08
所以我说,hantsy始终没有仔细阅读文章。始终无法理解classpath文件与Project Reference之间的区别

引用
假如有A,B两个项目,a的开发周期为一年,采用当时比较新的技术组合,sprin 1.2.8 +hibernate 2.1.8 ,b在a开始半年之后,b项目组想采用最新的spring 2.0.8 +hibernate 3.2.6。


没有人强迫A项目升级。事实上,A项目在开发之初,已经确定了的Library版本,并且在A项目自己的classpath文件和ant脚本中规定。A项目所引用的,是Library/spring/spring-1.2.8.jar。B项目启动,和A项目没有任何联系,因为B项目有自己的classpath文件和ant脚本,B项目在其classpath中,引用的是Library/spring/spring-2.0.8.jar,两者完全不会冲突。

我们甚至会为某些结构类似,框架使用相同的项目,由有经验的程序员,编写固定的classpath依赖文件,这样,新的项目启动时,拿过来用就可以了。

本文的关键就在于使用的是项目各自的classpath文件进行版本库控制管理,只是版本库的位置是统一的,而不是让一个Project去依赖于Library这个Project,这时完全不同的2种概念,而这种管理方式,在思想上与maven的区别并不大。
47 楼 hantsy 2009-02-05 12:17
实际项目中,我也在使用ant,作一些自动化的处理(编译,测试,打包,部署),项目的构建过程是不依赖IDE的,当然也试图用maven,但一直得不到公司的采纳。
至于文中提供这种共享方式,在实际开发中,意义不大。每个公司在做项目时都会考虑风险,技术风险也是其中之一。假如有A,B两个项目,a的开发周期为一年,采用当时比较新的技术组合,sprin 1.2.8 +hibernate 2.1.8 ,b在a开始半年之后,b项目组想采用最新的spring 2.0.8 +hibernate 3.2.6。文中的方法如何处理,全部升级到最新?实际上,上了一定规模的项目,项目过程中是不可能随便升级依赖库的。
一个项目组share一个版本更似乎更实际些,但这样文中的作法就没有什么意义了。
maven 自动处理依赖有时候也是很麻烦,特别有些jar包打包颗粒度太粗,如hibernate 3.2.x的版本(3.3 的打包细了很多),让它自动下载很多jboss的依赖。或许ant+ivy是个折中。
46 楼 downpour 2009-02-05 10:06
谢谢Quake的回复,我对maven的知识的确很匮乏,需要认真补课。几年前曾经试图使用maven来做项目,但是那是一次不成功的尝试,之后就一直对这样的工具心存忌惮。

后来慢慢自己摸索出类似我文章中提到的方法,就像你所说:

Quake Wang 写道
每一个项目都有独立的ant脚本和ide classpath依赖这个大仓库的其中某些lib包的具体版本


我感觉这种方式已经足够管理,同时极大程度上减轻了团队程序员对于环境搭建的知识的理解程度。因为很多情况下,往往项目经理或者构架师会来负责这些library的管理。如果一个普通程序员都需要花大量的时间来学习maven怎么用,无疑在实践上不可取。目前的这种方式,对于任何团队成员来说,只需要checkout,然后run一个java程序即可。似乎也减轻了很多环境搭建的压力。

hantsy同学所宣传的maven等工具同样是很优秀的library管理工具。我也从来不会贬低这些工具的使用,只是我个人不太喜欢这类工具而已。
45 楼 QuakeWang 2009-02-05 09:49
downpour 写道

我最大的问题在于,maven是如何解决library的副本问题的?就是说,如果我某个项目,开很多个branch,是不是每个branch依然需要下载那么多的lib包?

我来回答这个问题,maven会在本机构建一个仓库,下载的lib包都会放在这个仓库里面,比如在linux系统下面,会放在~/.m2/repository目录下面,相同版本的jar包是不会重复下载的。

hantsy 写道

我为什么maven在jar版本兼容上优于你的方式...但是你的方法,每个第三方jar加入都是武断的。

我在实际工作采用的方法和downpour差不多,每一个项目都有独立的ant脚本和ide classpath依赖这个大仓库的其中某些lib包的具体版本,第3方jar加入到大仓库完全不会影响到之前的项目。而这些ant脚本和ide classpath文件可以按照类似项目的特性,预先放在这个大仓库中,按照不同的项目需求做成几个样本。
44 楼 hantsy 2009-02-05 09:16
downpour 写道

hantsy 写道to downpour :至于人品,我不想和你讨论了,大概看了你写的其它的东西,拿“李刚”作标题。。。太厉害了。我们只谈技术问题,我已经说了你的方式一些问题,看来你是看不明白了,说些你明白的。1.每个项目都需要所有的包吗?难道公司所有项目都是千篇一律。2.显然有些jar运行时是没有必要的,如何区分开发时和运行时的包,如何将项目打一个洁净的包。3.所谓的“完善的lib管理”,说白了就是lib共享,一些常见的IDE都支持shared lib 功能,创建项目时,直接使用就行了,用得着这么麻烦吗?我现在做过的一些项目,其实还没正式采用maven,但一直都有使用ant,作一些自动化的处理(编译,测试,打包,部署),我从来不主张项目构建依赖某一IDE。看完所有评论的朋友自会对一个人的人品做出评论。我不会把你辱骂别人的话删除,你的人品应该已经昭然若揭了。关于你的问题,我实在是没有兴趣和你讨论下去了,因为你根本就没有读懂我的文章,所以我也不再和你讨论下去。

我还真不知道辱骂过你什么。。。要是那句“脱裤子放屁”的话,只能说明你小学语文不合格,这只不过是句偈后语而已。

当然你的话大家也可以看到,我也不想和去纠缠这个问题,毕竟我们不是一个时代的人。

至于你的写的文章,严重标题党的味道,看了就让人有吃苍蝇的感觉。

发表评论

您还没有登录,请您登录后再发表评论

文章信息

  • downpour在2008-12-22创建
  • downpour在2011-06-01更新
  • 标签: struts2 开发环境
Global site tag (gtag.js) - Google Analytics