﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-大浪搏舟</title><link>http://www.blogjava.net/surffish/</link><description>非学无以广才，非志无以成学！</description><language>zh-cn</language><lastBuildDate>Wed, 15 Apr 2026 13:44:16 GMT</lastBuildDate><pubDate>Wed, 15 Apr 2026 13:44:16 GMT</pubDate><ttl>60</ttl><item><title>职场法则</title><link>http://www.blogjava.net/surffish/archive/2007/11/27/163442.html</link><dc:creator>surffish</dc:creator><author>surffish</author><pubDate>Tue, 27 Nov 2007 06:18:00 GMT</pubDate><guid>http://www.blogjava.net/surffish/archive/2007/11/27/163442.html</guid><wfw:comment>http://www.blogjava.net/surffish/comments/163442.html</wfw:comment><comments>http://www.blogjava.net/surffish/archive/2007/11/27/163442.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/surffish/comments/commentRss/163442.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/surffish/services/trackbacks/163442.html</trackback:ping><description><![CDATA[帕金森定律<br />
<br />
　　美国著名历史学家诺斯古德-帕金森通过长期调查研究，写了一本名叫《帕金森定律》的书，他在书中阐述了机构人员膨胀的原因及后果：一个不称职的官员，可能有三条出路。第一是申请退职，把位子让给能干的人；第二是让一位能干的人来协助自己工作；第三是任用两个水平比自己更低的人当助手。<br />
<br />
　　这第一条路是万万走不得的，因为那样会丧失许多权力；第二条路也不能走，因为那个能干的人会成为自己的对手；看来只有第三条路最适宜。于是，两个平庸的助手分担了他的工作，他自己则高高在上发号施令。两个助手既无能，也就上行下效，再为自己找两个无能的助手。如此类推，就形成了一个机构臃肿、人浮于事、相互扯皮、效率低下的领导体系。<br />
<br />
　　苛希纳定律<br />
<br />
　　西方管理学中有一条著名的苛希纳定律：如果实际管理人员比最佳人数多两倍，工作时间就要多两倍，工作成本就要多四倍；如果实际管理人员比最佳人数多三倍，工作时间就要多三倍，工作成本就要多六倍。<br />
<br />
　　苛希纳定律告诉我们，在管理上并不是人多力量大，管理人员越多，工作效率未必就会越高。苛希纳定律要求我们，要认真研究并找到一个最佳人数，以最大限度地减少工作时间，降低工作成本。<br />
<br />
　　马蝇效应<br />
<br />
　　林肯少年时和他的兄弟在肯塔基老家的一个农场里犁玉米地，林肯吆马，他兄弟扶犁，而那匹马很懒，慢慢腾腾，走走停停。可是有一段时间马走得飞快。林肯感到奇怪，到了地头，他发现有一只很大的马蝇叮在马身上，他就把马蝇打落了。看到马蝇被打落了，他兄弟就抱怨说：&#8220;哎呀，你为什么要打掉它，正是那家伙使马跑起来的嘛！&#8221;<br />
<br />
　　没有马蝇叮咬，马慢慢腾腾，走走停停；有马蝇叮咬，马不敢怠慢，跑得飞快。这就是马蝇效应。马蝇效应给我们的启示是：一个人只有被叮着咬着，他才不敢松懈，才会努力拼搏，不断进步。<br />
<br />
　　&#8220;南风&#8221;法则<br />
<br />
　　&#8220;南风&#8221;法则也称&#8220;温暖&#8221;法则，源于法国作家拉封丹写过的一则寓言：北风和南风比威力，看谁能把行人身上的大衣脱掉。北风首先来一个冷风凛冽寒冷刺骨，结果行人为了抵御北风的侵袭，便把大衣裹得紧紧的。南风则徐徐吹动，顿时风和日丽，行人因为觉得春暖上身，始而解开纽扣，继而脱掉大衣，南风获得了胜利。<br />
<br />
　　这则寓言形象地说明了一个道理：温暖胜于严寒。领导者在管理中运用&#8220;南风&#8221;法则，就是要尊重和关心下属，以下属为本，多点&#8220;人情味&#8221;，尽力解决下属日常生活中的实际困难，使下属真正感受到领导者给予的温暖，从而激发出工作的积极性。<br />
<br />
　　酒与污水定律<br />
<br />
　　酒与污水定律是指，如果把一匙酒倒进一桶污水中，你得到的是一桶污水；如果把一匙污水倒进一桶酒中，你得到的还是一桶污水。<br />
<br />
　　在任何组织里，都存在几个难弄的人物，他们存在的目的似乎就是为了把事情搞糟。最糟糕的是，他们像果箱里的烂苹果一样，如果你不及时处理，它会迅速传染，把果箱里其他的苹果也弄烂。&#8220;烂苹果&#8221;的可怕之处在于它那惊人的破坏力。一个正直能干的人进入一个混乱的部门可能被吞没，而一个无德无才者能很快将一个高效的部门变成一盘散沙。一个能工巧匠花费时日精心制作的陶瓷品，一头驴子一秒钟就能将它毁坏掉。
<img src ="http://www.blogjava.net/surffish/aggbug/163442.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/surffish/" target="_blank">surffish</a> 2007-11-27 14:18 <a href="http://www.blogjava.net/surffish/archive/2007/11/27/163442.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>团队管理101招</title><link>http://www.blogjava.net/surffish/archive/2006/09/21/70968.html</link><dc:creator>surffish</dc:creator><author>surffish</author><pubDate>Thu, 21 Sep 2006 00:05:00 GMT</pubDate><guid>http://www.blogjava.net/surffish/archive/2006/09/21/70968.html</guid><wfw:comment>http://www.blogjava.net/surffish/comments/70968.html</wfw:comment><comments>http://www.blogjava.net/surffish/archive/2006/09/21/70968.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/surffish/comments/commentRss/70968.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/surffish/services/trackbacks/70968.html</trackback:ping><description><![CDATA[不论你是单一团队的领导者还是多个团队的管理人，团队管理工作都是你职权范围内一个重要的组成部分。在今日，集多重技术于一身的工作方法已逐渐取代阶层式的、缺乏弹性的传统工作体制，团队合作因而很快就成为了一种很受欢迎的工作方式。对于每一位参与团队管理工作的人而言，《团队管理》是一本不可或缺的重要读物。它向你提供了达成计划所需的技巧、建立团队成员间的信任、激发团队最大的潜能等方面的知识，为你能专业化地管理好你的团队创造了有利条件。另外，全书还散布了101条简明提示，为你提供重要而实用的讯息。后半部分有个自我评估练习，使你能正确地评估自己的领导能力，并针对自己的不足加以改进。
<p class="main"><strong>了解团队运作</strong></p><p class="main">　　<strong>团队合作是所有成功管理的根基。无论你是新手还是资深管理人，对你而言，管理好团队都是重要且具激励性的挑战。</strong></p><p class="main">1.切记：每位成员都能为团队作出一些贡献。</p><p class="main">2.谨慎地设定团队目标，且认真严肃地对待它们。</p><p class="main">3.切记成员间要彼此扶持。</p><p class="main">4.将长程目标打散成许多短程计划。</p><p class="main">5.为每个计划设定明确的期限。</p><p class="main">6.尽早决定何种形态的团队适合你的目标。</p><p class="main">7.努力与其它团队的成员建立强有力的紧密关系。</p><p class="main">8.找一位可提升团队工作士气的重量级人物。</p><p class="main">9.时时提醒团队成员：他们都是团队的一份子。</p><p class="main">10.将团队的注意力集中在固定可衡量的目标上。</p><p class="main">11.利用友谊的强大力量强化团队。</p><p class="main">12.选择领导者时要把握用人唯才原则。</p><p class="main">13.领导者需具备强烈的团队使命感。</p><p class="main">14.奖赏优异的表现，但绝不姑息错误。</p><p class="main">15.记住每位团队成员看事情的角度都不一样。</p><p class="main">16.征召团队成员时，应注重他们的成长潜能。</p><p class="main">17.密切注意团队成员缺少的相关经验。</p><p class="main">18.应使不适任的成员退出团队。</p><p class="main">19.找到能将人际关系处理得很好的人，并培养他们。</p><p class="main"><strong>设立一支团队</strong></p><p class="main"><strong>　　成立一支团队是领导者的主要工作。确保你的团队有清楚明确的目的和足够达成目标的资源。要以开放和公正无私的态度对待团队成员。</strong></p><p class="main">20.设定具挑战性的目标须根据限期来考量是否合理。</p><p class="main">21.设定目标时，考量个别成员的工作目标。</p><p class="main">22.计划的失败危及整体计划的成功。</p><p class="main">23.坚持得到信息技术支持，它能为你提供确实需要的东西。</p><p class="main">24.对待团队外的顾问要如同对待团队成员一般。</p><p class="main">25.让团队的赞助者随时知道工作进展情形。</p><p class="main">26.除非你确定没有人能够胜任，否则应避免“事必躬亲”。</p><p class="main">27.不要委托不必要的工作，最好将其去除掉。</p><p class="main">28.赋予团队自己作决策的权力。</p><p class="main">29.鼓励团队成员正面积极的贡献。</p><p class="main">30.肯定、宣扬和庆祝团队每次的成功。</p><p class="main">31.找到易于让成员及团队了解每日工作进度的展现方式。</p><p class="main">32.鼓励成员之间建立工作上的伙伴关系。</p><p class="main">33.鼓励天生具有领导才能的人，并引导和培养他们的领导技巧。</p><p class="main">34.绝对不能没有解释就驳回团队的意见，与此相反，解释要坦白，理由要充分。</p><p class="main">35.确定团队和客户经常保持联系。</p><p class="main">36.以自信肯定的态度让团队知道谁当家，但要预防予人来势汹汹的感觉。</p><p class="main">37.想办法给新团队留下一个实时的好印象，但切忌操之过急。</p><p class="main">38.倘若你要求别人的建议，抱持的心态不能只是欢迎就行了，也要依循建议有所行动。</p><p class="main"><strong>提升团队效率</strong></p><p class="main"><strong>　　团队要达到应有的效率，唯一的条件是每个成员都要学会集中力量。你必须了解团队的能力，以确保团队的成功。</strong></p><p class="main">39.协助团队找出方法以改变有碍任务推展的团体行为。</p><p class="main">40.找出可建设性地利用冲突的方法。</p><p class="main">41.记住要在工作中穿插安排娱乐调剂身心──这是每个人应得的福利。</p><p class="main">42.若有计划出错，一定要作全面性、公开化的分析。</p><p class="main">43.如果你希望团队成员有问题时能毫不犹疑地找你谈，就要实施“开门政策”。</p><p class="main">44.要求提出问题的人解决问题。</p><p class="main">45.安排正式的和非正式的会面，讨论团队的工作进展。</p><p class="main">46.使用不带感情只问事实的态度，是化解纷争的最好方法。</p><p class="main">47.保持团队成员间的熟稔，以易于沟通。</p><p class="main">48.设立交谊场所，让团队成员可作非正式的碰面交谈。</p><p class="main">49.鼓励同事间自由的沟通活动。</p><p class="main">50.建立最适合的通讯科技系统，并经常更新。</p><p class="main">51.实施会议主席轮流制，让每个人都有机会主持会议。</p><p class="main">52.尽可能多地授权给团队成员。</p><p class="main">53.事先于会前发出议程，预留时间给与会者准备。</p><p class="main">54.培养所有对团队有益的关系。</p><p class="main">55.努力保持团队内外关系的均衡与平稳。</p><p class="main">56.确定所有相关人士都能听到、了解好消息。</p><p class="main">57.倘有麻烦在团队关系中发酵蕴酿，要尽快处理。</p><p class="main">58.安排团队与机构的其它部门作社交联谊。</p><p class="main">59.找出你与“大佬”保持联系的最佳通讯科技。</p><p class="main">60.要对你在团队或办公室外接触过的重要人士作联系记录。</p><p class="main">61.谨慎分派角色以避免任务重复。</p><p class="main">62.找寻建议中的精华，且绝不在公开场合批评任何建议。</p><p class="main">63.一定要找有经验的人解决问题。</p><p class="main">64.分析团队成员每个人所扮演的角色。</p><p class="main">65.脑力激发出的意见，就算不采用，亦不得轻视。否则，会打击人的积极性，创意的流动也会因此停止。</p><p class="main">66.公平对待每个成员才能避免怨恨。</p><p class="main">67.确定团队成员真正有错之前，都须视他们没有错。</p><p class="main">68.告诉同事他们做得很好，这有助于激励团队士气。</p><p class="main">69.尊重每一位成员，包括那些给你制造麻烦的人。</p><p class="main">70.避免和团队成员有直接的冲突。</p><p class="main">71.记住采用对事不对人的处事态度。</p><p class="main">72.确定整个团队都能够从解决问题中学习经验。</p><p class="main">73.先选择完成一些规模大的、可快速达成及有成就感的任务，以激励成员再接再励。</p><p class="main">74.确信团队成员皆了解团队中的其它角色。</p><p class="main">75.计算品质的成本之前，先计算失败的成本。</p><p class="main">76.针对每笔预算及每项团队行动计划，设定重大的改进目标。</p><p class="main"><strong>为未来努力</strong></p><p class="main"><strong>为团队设定新的、更高的挑战目标是团队工作中最令人兴奋的事情之一。可运用一些适当的技巧，推动团队向更大、更好的目标前进。</strong></p><p class="main">77.告知团队每位成员，在设定的标准中有哪些评量的项目。</p><p class="main">78.确定所有改善措施及新订目标都持续进行着。</p><p class="main">79.召开检讨会议前传阅所有相关资料及资料。</p><p class="main">80.开检讨会时一定要避讳人身攻击。</p><p class="main">81.记住关系会随时间改变。</p><p class="main">82.避开低估或忽视坏消息的陷井。</p><p class="main">83.每天结束时自问团队今天是否又向前跨出了一步。</p><p class="main">84.倾听受训者关于训练课程的回馈意见。</p><p class="main">85.找到有最好设备的最佳训练场所。</p><p class="main">86.聘请顾问设立公司内部的训练课程。</p><p class="main">87.利用移地训练时的用餐时间作非正式的计划。</p><p class="main">88.每位团队成员都必须参与设定目标的工作，以促进团队合作及达成共识。</p><p class="main">89.允许团队自行决定达成目标的方法，可激励团队努力工作。</p><p class="main">90.确定目标能激发团队的斗志，如果不行，请改变目标。</p><p class="main">91.一支没有“严峻”目标的团队，工作表现将不如接受过此类考验的团队。</p><p class="main">92.设定奖励标准时，允许团队成员有发言权。</p><p class="main">93.避免使用名次表，因为落后的团队成员将会感到自尊心受创。</p><p class="main">94.指定某人监视市场上每一个相关变化。</p><p class="main">95.随时准备作改变，甚至计划的根本要素亦包含在改变的范围内。</p><p class="main">96.记住有某些人很害怕变革。</p><p class="main">97.寻找能推动改革的团队成员。</p><p class="main">98.每隔一段时间作一次生涯发展的评量。</p><p class="main">99.记住：鼓励团队成员即是在帮助团队。</p><p class="main">100.与团队同事就生涯规划达成一致意见，并给他们提供必要的协助。</p><p class="main">101.团队解散后仍旧要与团队成员保持联系，因为你可能还会与他们再次合作</p><img src ="http://www.blogjava.net/surffish/aggbug/70968.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/surffish/" target="_blank">surffish</a> 2006-09-21 08:05 <a href="http://www.blogjava.net/surffish/archive/2006/09/21/70968.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>msn 不能登陆的解决办法</title><link>http://www.blogjava.net/surffish/archive/2006/08/21/64696.html</link><dc:creator>surffish</dc:creator><author>surffish</author><pubDate>Mon, 21 Aug 2006 00:03:00 GMT</pubDate><guid>http://www.blogjava.net/surffish/archive/2006/08/21/64696.html</guid><wfw:comment>http://www.blogjava.net/surffish/comments/64696.html</wfw:comment><comments>http://www.blogjava.net/surffish/archive/2006/08/21/64696.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/surffish/comments/commentRss/64696.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/surffish/services/trackbacks/64696.html</trackback:ping><description><![CDATA[关闭msn，在开始-&gt;运行中分别输入 <br />regsvr32 softpub.dll <br /><br />regsvr32 mssip32.dll <br /><br />regsvr32 intipki.dll <br /><br />regsvr32 MSXML3.dll <br /><br />11221399B<br />再重新启动msn即可<img src ="http://www.blogjava.net/surffish/aggbug/64696.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/surffish/" target="_blank">surffish</a> 2006-08-21 08:03 <a href="http://www.blogjava.net/surffish/archive/2006/08/21/64696.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA操作数据库方式与设计模式应用 </title><link>http://www.blogjava.net/surffish/archive/2006/04/18/41603.html</link><dc:creator>surffish</dc:creator><author>surffish</author><pubDate>Tue, 18 Apr 2006 03:05:00 GMT</pubDate><guid>http://www.blogjava.net/surffish/archive/2006/04/18/41603.html</guid><wfw:comment>http://www.blogjava.net/surffish/comments/41603.html</wfw:comment><comments>http://www.blogjava.net/surffish/archive/2006/04/18/41603.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/surffish/comments/commentRss/41603.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/surffish/services/trackbacks/41603.html</trackback:ping><description><![CDATA[1. 在业务层使用JDBC直接操作数据库－最简单，最直接的操作<br /><br />1）数据库url,username,password写死在代码中<br />Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); <br />String url="jdbc:oracle:thin:@localhost:1521:orcl"; <br />String user="scott"; <br />String password="tiger"; <br />Connection conn= DriverManager.getConnection(url,user,password); <br />Statement stmt=conn.createStatement(<br />ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); <br />String sql="select * from test"; <br />ResultSet rs=stmt.executeQuery(sql); <br /><br />2）采用Facade和Command模式，使用DBUtil类封装JDBC操作；<br />数据库url,username,password可以放在配置文件中（如xml,properties,ini等）。<br />这种方法在小程序中应用较多。<br /><br />2.DAO(Data Accessor Object)模式－松耦合的开始<br />DAO = data + accessor + domain object<br /><br />例如User类－domain object (javabean)<br />UserDAO类－accessor ，提供的方法getUser(int id)，save(User user)内包含了JDBC操作<br />在业务逻辑中使用这两个类来完成数据操作。<br /><br />使用Factory模式可以方便不同数据库连接之间的移植。<br /><br />3.数据库资源管理模式<br />3.1 数据库连接池技术<br />资源重用，避免频繁创建，释放连接引起大大量性能开销；<br />更快的系统响应速度；<br /><br />通过实现JDBC的部分资源对象接口( Connection, Statement, ResultSet )，可以使用Decorator设计模式分别产生三种逻辑资源对象: PooledConnection, PooledStatement和 PooledResultSet。<br /><br /><br />一个最简单地数据库连接池实现：<br />public class ConnectionPool {<br /><br />private static Vector pools;<br />private final int POOL_MAXSIZE = 25;<br />/**<br />* 获取数据库连接<br />* 如果当前池中有可用连接，则将池中最后一个返回；若没有，则创建一个新的返回<br />*/<br />public synchronized Connection getConnection() {<br />Connection conn = null;<br />if (pools == null) {<br />pools = new Vector();<br />}<br /><br />if (pools.isEmpty()) {<br />conn = createConnection();<br />} else {<br />int last_idx = pools.size() - 1;<br />conn = (Connection) pools.get(last_idx);<br />pools.remove(last_idx);<br />}<br /><br />return conn;<br />}<br /><br />/**<br />* 将使用完毕的数据库连接放回池中<br />* 若池中连接已经超过阈值，则关闭该连接；否则放回池中下次再使用<br />*/<br />public synchronized void releaseConnection(Connection conn) {<br />if (pools.size() &gt;= POOL_MAXSIZE)<br />try {<br />conn.close();<br />} catch (SQLException e) {<br />// TODO自动生成 catch 块<br />e.printStackTrace();<br />} else<br />pools.add(conn);<br />}<br /><br />public static Connection createConnection() {<br />Connection conn = null;<br />try {<br />Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();<br />String url = "jdbc:oracle:thin:@localhost:1521:orcl";<br />String user = "scott";<br />String password = "tiger";<br />conn = DriverManager.getConnection(url, user, password);<br />} catch (InstantiationException e) {<br />// TODO自动生成 catch 块<br />e.printStackTrace();<br />} catch (IllegalAccessException e) {<br />// TODO自动生成 catch 块<br />e.printStackTrace();<br />} catch (ClassNotFoundException e) {<br />// TODO自动生成 catch 块<br />e.printStackTrace();<br />} catch (SQLException e) {<br />// TODO自动生成 catch 块<br />e.printStackTrace();<br />}<br />return conn;<br />}<br />}<br /><br />注意：利用getConnection()方法得到的Connection，程序员很习惯地调用conn.close()方法关闭了数据库连接，那么上述的数据库连接机制便形同虚设。在调用conn.close()方法方法时如何调用releaseConnection()方法？这是关键。这里，我们使用Proxy模式和java反射机制。 <br /><br />public synchronized Connection getConnection() {<br />Connection conn = null;<br />if (pools == null) {<br />pools = new Vector();<br />}<br /><br />if (pools.isEmpty()) {<br />conn = createConnection();<br />} else {<br />int last_idx = pools.size() - 1;<br />conn = (Connection) pools.get(last_idx);<br />pools.remove(last_idx);<br />}<br /><br />ConnectionHandler handler=new ConnectionHandler(this);<br />return handler.bind(con);<br />}<br /><br />public class ConnectionHandler implements InvocationHandler {<br />private Connection conn;<br />private ConnectionPool pool;<br /><br />public ConnectionHandler(ConnectionPool pool){<br />this.pool=pool;<br />}<br /><br />/**<br />* 将动态代理绑定到指定Connection<br />* @param conn<br />* @return<br />*/<br />public Connection bind(Connection conn){<br />this.conn=conn;<br />Connection proxyConn=(Connection)Proxy.newProxyInstance(<br />conn.getClass().getClassLoader(), conn.getClass().getInterfaces(),this);<br />return proxyConn;<br />}<br /><br />/* （非 Javadoc）<br />* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])<br />*/<br />public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {<br />// TODO自动生成方法存根<br />Object obj=null;<br />if("close".equals(method.getName())){<br />this.pool.releaseConnection(this.conn);<br />}<br />else{<br />obj=method.invoke(this.conn, args);<br />}<br /><br />return obj;<br />}<br />}<br /><br />在实际项目中，并不需要你来从头开始来设计数据库连接池机制，现在成熟的开源项目，如C3P0,dbcp,Proxool等提供了良好的实现。一般推荐使用Apache dbcp，基本使用实例：<br />DataSource ds = null;<br />try{<br />Context initCtx = new InitialContext();<br />Context envCtx = (Context) initCtx.lookup("java:comp/env");<br />ds = (DataSource)envCtx.lookup("jdbc/myoracle");<br />if(ds!=null){<br />out.println("Connection is OK!");<br />Connection cn=ds.getConnection();<br />if(cn!=null){<br />out.println("cn is Ok!");<br />Statement stmt = cn.createStatement();<br />ResultSet rst = stmt.executeQuery("select * from BOOK");<br />out.println(" 
<p>rst is Ok!" + rst.next());<br />while(rst.next()){<br />out.println(" </p><p>BOOK_CODE:" + rst.getString(1));<br />}<br />cn.close();<br />}else{<br />out.println("rst Fail!");<br />}<br />}<br />else <br />out.println("Fail!");<br />}catch(Exception ne){ out.println(ne);<br />}<br /><br /><br />3.2 Statement Pool<br />普通预编译代码：<br />String strSQL=”select name from items where id=?”;<br />PreparedStatement ps=conn.prepareStatement(strSQL);<br />ps.setString(1, “2”);<br />ResultSet rs=ps.executeQuery();<br /><br />但是PreparedStatement 是与特定的Connection关联的，一旦Connection关闭，则相关的PreparedStatement 也会关闭。<br />为了创建PreparedStatement 缓冲池，可以在invoke方法中通过sql语句判断池中还有没有可用实例。<br /><br />4. 持久层设计与O/R mapping 技术<br />1） Hernate：适合对新产品的开发，进行封闭化的设计 <br />Hibernate 2003年被Jboss接管，通过把java pojo对象映射到数据库的table中，采用了xml/javareflection技术等。3.0提供了对存储过程和手写sql的支持，本身提供了hql语言。<br />开发所需要的文件：<br />hibernate配置文件： hibernate.cfg.xml 或 hibernate.properties<br />hibernate 映射文件： a.hbm.xml<br />pojo类源文件： a.java　　<br /><br />导出表与表之间的关系：<br />a. 从java对象到hbm文件：xdoclet <br />b. 从hbm文件到java对象：hibernate extension <br />c. 从数据库到hbm文件：middlegen <br />d. 从hbm文件到数据库：SchemaExport<br /><br />2）Iatis ：适合对遗留系统的改造和对既有数据库的复用，有很强的灵活性 3） Apache OJB：优势在于对标准的全面支持 4）EJB：适合集群服务器，其性能也不象某些人所诟病的那么差劲 5） JDO (java data object) <br />设置一个Properties对象，从而获取一个JDO的PersistenceManagerFactory（相当于JDBC连接池中的DataSource），进而获得一个PersistenceManager对象（相当于JDBC中的Connection对象），之后，你可以用这个PersistenceManager对象来增加、更新、删除、查询对象。<br />JDOQL是JDO的查询语言；它有点象SQL，但却是依照Java的语法的。<br /><br />5. 基于开源框架的Struts+Spring+Hibernate实现方案<br />示例：这是一个3层架构的web 程序，通过一个Action 来调用业务代理，再通过它来回调 DAO类。下面的流程图表示了MyUsers是如何工作的。数字表明了流程的先后顺序，从web层(UserAction)到中间层(UserManager)，再到数据层(UserDAO)，然后返回。<br />Spring是AOP, UserManager和UserDAO都是接口.<br />1) web层(UserAction) ：调用中间层的接口方法，将UserManager作为属性注入。<br />采用流行的Struts框架，虽然有很多人不屑一顾，但是这项技术在业界用的比较普遍，能满足基本的功能，可以减少培训学习成本。<br />2) 中间层(UserManager)：将UserDAO作为属性注入，其实现主要是调用数据层接口的一些方法；它处于事务控制中。<br />采用Spring框架实现，IOC与AOP是它的代名词，功能齐全，非常棒的一个架构。<br />3) 数据层(UserDAO)：实现类继承HibernateDaoSupport类，在该类中可以调用getHibernateTemplate()的一些方法执行具体的数据操作。<br />采用Hibernate做O/R mapping，从种种迹象可以看出，Hibernate就是EJB3.0的beta版。 (转载文章请保留出处：<a href="http://www.javajia.com/">Java家(www.javajia.com)</a>)</p><img src ="http://www.blogjava.net/surffish/aggbug/41603.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/surffish/" target="_blank">surffish</a> 2006-04-18 11:05 <a href="http://www.blogjava.net/surffish/archive/2006/04/18/41603.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>老婆使用说明书</title><link>http://www.blogjava.net/surffish/archive/2006/03/23/37018.html</link><dc:creator>surffish</dc:creator><author>surffish</author><pubDate>Thu, 23 Mar 2006 04:00:00 GMT</pubDate><guid>http://www.blogjava.net/surffish/archive/2006/03/23/37018.html</guid><wfw:comment>http://www.blogjava.net/surffish/comments/37018.html</wfw:comment><comments>http://www.blogjava.net/surffish/archive/2006/03/23/37018.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/surffish/comments/commentRss/37018.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/surffish/services/trackbacks/37018.html</trackback:ping><description><![CDATA[【品名】民间俗称老婆，正式场合可称妻子或夫人；古称内人，现亦可叫爱人。<br />【成分】水、血液和脂肪类碳水化合物。<br />【性状】本品为细长条块状糖衣片，表面涂层一般为粉底、口红等化妆物，除去後呈浅黄色，外观与除去前略有差异；本品随时间推移，形状会有所改变，出现发胖、起皱等现象，但不影响继续使用。<br />【功能主治】主治单身恐惧症及传宗接代等顽疾，对失恋和相思病也有明显效果。<br />【用法用量】口服兼外用，一次限一片。对无效者，可暂时停用并向婚姻专家咨询，或间隔一段时间後重复使用。<br />【注意事项】本品仅适用于单身之成年男性。服用时　小心谨慎，细心观察有无不良反应，如有必须马上停止服用，没有则可继续使用。若忌烟酒等不良习惯，会使疗效更佳。<br />【规格】通常为45千克至55千克，特殊情况下亦有例外。<br />【贮藏】常温下妥善保存，室内阴凉处最佳；如在室外，则　避免强烈阳光直射。 贮藏期间，尤忌随意弃置一旁不管<br /><img src ="http://www.blogjava.net/surffish/aggbug/37018.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/surffish/" target="_blank">surffish</a> 2006-03-23 12:00 <a href="http://www.blogjava.net/surffish/archive/2006/03/23/37018.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java 与 .net 的socket通讯的建立</title><link>http://www.blogjava.net/surffish/archive/2005/12/09/23168.html</link><dc:creator>surffish</dc:creator><author>surffish</author><pubDate>Fri, 09 Dec 2005 08:36:00 GMT</pubDate><guid>http://www.blogjava.net/surffish/archive/2005/12/09/23168.html</guid><wfw:comment>http://www.blogjava.net/surffish/comments/23168.html</wfw:comment><comments>http://www.blogjava.net/surffish/archive/2005/12/09/23168.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/surffish/comments/commentRss/23168.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/surffish/services/trackbacks/23168.html</trackback:ping><description><![CDATA[<P>用java写服务端代码<BR><BR>import java.io.*;<BR>import java.net.*;<BR>public class test {<BR>&nbsp; public test() {<BR>&nbsp; }<BR>&nbsp; public static final int PORT = 8080;<BR>&nbsp; public static final String ip = "10.194.111.222";</P>
<P>&nbsp; public static void main(String[] args) throws IOException {<BR>&nbsp;&nbsp;&nbsp; ServerSocket s = new ServerSocket(51,2,InetAddress.getByName(ip));<BR>&nbsp;&nbsp;&nbsp; System.out.println("Started: " + s);<BR>&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Blocks until a connection occurs:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Socket socket = s.accept();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Connection accepted: "+ socket);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BufferedReader in =<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new BufferedReader(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new InputStreamReader(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; socket.getInputStream()));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Output is automatically flushed<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // by PrintWriter:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PrintWriter out =<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new PrintWriter(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new BufferedWriter(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new OutputStreamWriter(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; socket.getOutputStream())),true);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (true) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String str = in.readLine();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (str.equals("END")) break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Echoing: " + str);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println(str);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Always close the two sockets...<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } finally {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("closing...");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; socket.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; } finally {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.close();<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp; }<BR>}<BR><BR>.net写客户端代码<BR>private void button2_Click(object sender, System.EventArgs e)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;try<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;stSend = new Socket ( AddressFamily.InterNetwork , <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SocketType.Stream , ProtocolType.Tcp ) ;<BR>&nbsp;&nbsp;&nbsp;&nbsp;//初始化一个Socket实例<BR>&nbsp;&nbsp;&nbsp;&nbsp;IPEndPoint tempRemoteIP = new IPEndPoint(IPAddress.Parse("10.194.111.222"),51);<BR>&nbsp;&nbsp;&nbsp;&nbsp;//根据IP地址和端口号创建远程终结点<BR>&nbsp;&nbsp;&nbsp;&nbsp;EndPoint epTemp =&nbsp; ( EndPoint ) tempRemoteIP;<BR>&nbsp;&nbsp;&nbsp;&nbsp;stSend.Connect ( epTemp ) ;</P>
<P>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;catch ( Exception err)<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;string s = err.ToString();<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}</P><img src ="http://www.blogjava.net/surffish/aggbug/23168.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/surffish/" target="_blank">surffish</a> 2005-12-09 16:36 <a href="http://www.blogjava.net/surffish/archive/2005/12/09/23168.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JBuilder 9 常见快捷键</title><link>http://www.blogjava.net/surffish/archive/2005/12/09/23115.html</link><dc:creator>surffish</dc:creator><author>surffish</author><pubDate>Fri, 09 Dec 2005 03:40:00 GMT</pubDate><guid>http://www.blogjava.net/surffish/archive/2005/12/09/23115.html</guid><wfw:comment>http://www.blogjava.net/surffish/comments/23115.html</wfw:comment><comments>http://www.blogjava.net/surffish/archive/2005/12/09/23115.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/surffish/comments/commentRss/23115.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/surffish/services/trackbacks/23115.html</trackback:ping><description><![CDATA[<P align=left>1.工作区: (显隐) <BR><BR>项目面板：ctrl + Alt + p (Project) <BR>设计面板: ctrl + Alt + c (content) <BR>结构面板: ctrl + Alt + s (Structure) <BR>信息面板: ctrl + Alt + M (Message) <BR>状态面板: ctrl + Alt + Z <BR><BR><BR>2.主面板:(代码面板和设计面板) <BR><BR>激活代码模块: ctrl + J (@1) <BR>参数提示信息的激活: ctrl + shift + H <BR>打开查询、替换窗口: ctrl + F <BR>类的查询: ctrl + - <BR><BR><BR>3.F 键的用法 <BR><BR>F1: 帮助快捷 <BR>F4: 运行多行 <BR>F5: 加入断点 <BR>F7: 当遇到方法时会运行方法内的代码 <BR>F8: 逐步运行代码 <BR>F12: 代码面板和设计面板切换 <BR><BR><BR>4. Shift 键的用法 <BR><BR>添加多个相同组件： 按shift键在选项上选取组件，把组件添加到窗口即可 <BR>调整组件间间隔和对齐： 假设有组件JPanel 1/2/3;(要达到3个组件宽度相同，组件间隔相等，并且都是依据JPanel1左对齐),按shift键，用鼠标选中需要调整的组件，(第一个选中的组件是其他的基准)然后右键。 <BR><BR><BR>5: codeInsight 和 Codetemplates <BR>MemberInsight -- 根据当前的代码提示可用的类成员或方法(说明) <BR>ParameterInsight -- 提示当前的方法需要使用的参数 <BR>SymbolInsigh -- 查看当前的变量、方法或者类的愿代码。 <BR><BR>MemberInsight: ctrl + space 或 ctrl + H <BR>ParameterInsight: ctrl + shift + space 或 ctrl + shift + H <BR>SymbolInsight: ctrl + Enter 或 Alt + shift + H <BR>ClassInsight : ctrl + alt + space 或 ctrl + alt + H <BR><BR><BR><BR><BR>注： (@1)：使用代码功能：(ctrl + J) <BR>1、 在想要输入代码的位置输入代码摸板名，然后按 ctrl + J(开发人员可以用主菜单上的Tools/Editor/Templates命令来查看代码摸板的名字) <BR>2、把光标定位于想要输入代码的位置，然后按ctrl + J</P><img src ="http://www.blogjava.net/surffish/aggbug/23115.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/surffish/" target="_blank">surffish</a> 2005-12-09 11:40 <a href="http://www.blogjava.net/surffish/archive/2005/12/09/23115.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java环境变量设置 </title><link>http://www.blogjava.net/surffish/archive/2005/12/07/22884.html</link><dc:creator>surffish</dc:creator><author>surffish</author><pubDate>Wed, 07 Dec 2005 08:31:00 GMT</pubDate><guid>http://www.blogjava.net/surffish/archive/2005/12/07/22884.html</guid><wfw:comment>http://www.blogjava.net/surffish/comments/22884.html</wfw:comment><comments>http://www.blogjava.net/surffish/archive/2005/12/07/22884.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/surffish/comments/commentRss/22884.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/surffish/services/trackbacks/22884.html</trackback:ping><description><![CDATA[<H2><A id=viewpost.ascx_TitleUrl href="http://blog.csdn.net/javamxj/archive/2004/10/11/131935.aspx">Eclipse基础－－java环境变量设置</A> </H2>
<P><A href="http://blog.csdn.net/javamxj/archive/2004/10/11/131935.aspx">http://blog.csdn.net/javamxj/archive/2004/10/11/131935.aspx</A><BR><BR>我是一名java的爱好者，理所当然装了不少java方面的软件，大部分是开放源码的，而且多数是绿色软件，只要解压，设置一下环境变量即可使用。 </P>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;&nbsp; 由于软件本身升级比较频繁，经常需要重新设置使用的环境变量，而且我常常同时安装同一软件的不同版本（甚至是相同版本）。如eclipse我就分别在F,G,H三个盘上装了不同的版本，一个是中文版，一个是英文的Latest Release，一个是Stream Stable，反正是绿色安装，也不会发生冲突，这样通过对比便于了解和测试最新版本的先进之处。</DIV>
<DIV>&nbsp;&nbsp; 但是假如把JDK版本从1.3升级到1.4，即JDK目录名可能要从“j2sdk1.3”改为“j2sdk1.4”，如果是这样的话，那么eclipse可能会无法再启动了（它要从环境变量中寻找JAVA_HOME变量，而JAVA_HOME变量值已经从“j2sdk1.3”改为“j2sdk1.4”了）。</DIV>
<DIV>&nbsp;&nbsp; 在谈谈jakarta-tomcat，这个软件升级比较频繁，如果你是结合eclipse来使用Tomcat的，那么每次Tomcat升级，可能都要在eclipse中重新设置一下Tomcat的安装目录，是不是有些麻烦？</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;&nbsp;&nbsp; 对于此类问题，解决的方法很简单，只要把默认的软件安装目录名去掉版本号即可(如果担心忘记版本号，只要在目录中添加一个readme文件加以说明即可)。</DIV>
<DIV>&nbsp;&nbsp;&nbsp;<IMG src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54070/r_eclipse2.jpg"></DIV>
<DIV>如上图，我的j2sdk,ant,jakata-tomcat等都没有版本号。</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;&nbsp; 同样，在环境变量设置中也没有出现版本号。</DIV>
<DIV>&nbsp;&nbsp;&nbsp; <IMG src="http://blog.csdn.net/images/blog_csdn_net/javamxj/54070/r_eclipse3.jpg"></DIV>
<DIV>&nbsp;</DIV>
<DIV>这样，如果再需要升级软件时，仅仅把新版软件安装在旧版软件目录即可。其它一般都不需要再改动了。</DIV>
<DIV>&nbsp;</DIV>
<DIV>另外，在环境变量设置中，可以用%变量%代替变量值，如Path变量值可以这样设置:&nbsp; %JAVA_HOME%\bin;%JBOSS_HOME%\bin;%ANT_HOME%\bin;</DIV><img src ="http://www.blogjava.net/surffish/aggbug/22884.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/surffish/" target="_blank">surffish</a> 2005-12-07 16:31 <a href="http://www.blogjava.net/surffish/archive/2005/12/07/22884.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ant - java 构建工具（MaYong）</title><link>http://www.blogjava.net/surffish/archive/2005/12/07/22854.html</link><dc:creator>surffish</dc:creator><author>surffish</author><pubDate>Wed, 07 Dec 2005 06:33:00 GMT</pubDate><guid>http://www.blogjava.net/surffish/archive/2005/12/07/22854.html</guid><wfw:comment>http://www.blogjava.net/surffish/comments/22854.html</wfw:comment><comments>http://www.blogjava.net/surffish/archive/2005/12/07/22854.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/surffish/comments/commentRss/22854.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/surffish/services/trackbacks/22854.html</trackback:ping><description><![CDATA[<P><FONT size=2>我们要开发一个java类：其内容只有一句，输出"hello ant"字符串。并使用ant完成编译和运行工作，这个例子只是为了跑通ant，不附加多余的东西。</FONT></P>
<P><FONT size=2>下图为文件组织，请建立相应的目录，并编写HelloAnt.java<BR><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大图 style="ZOOM: 120%" height=198 src="http://www.huihoo.com/java/hello-ant/images/hello-ant-dir.gif" width=425 onload="java_script_:if(this.width>600)this.width=600" border=1></FONT></P>
<P><FONT size=2>按照人家老外的文件组织规则咱也照搬。</FONT></P>
<P align=left>
<TABLE style="BORDER-COLLAPSE: collapse" borderColor=#000000 height=69 cellSpacing=0 cellPadding=0 width="86%" border=1>
<TBODY>
<TR>
<TD width="100%" bgColor=#c0c0c0 height=13><FONT size=2>&nbsp;hello.ant.HelloAnt.java</FONT></TD></TR>
<TR>
<TD width="100%" height=52><FONT size=2><TEXTAREA style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体" name=S1 rows=7 cols=75>package hello.ant;

public class HelloAnt{
    public static void main(String[] args){
        System.out.println("hello ant,ant 的第一次接触，好棒！");
    } 
}</TEXTAREA> </FONT></TD></TR></TBODY></TABLE></P>
<P><FONT size=2>在项目根目录(hello-ant\)写1个文件：ant执行配置文件build.xml</FONT></P>
<P align=left>
<TABLE style="BORDER-COLLAPSE: collapse" borderColor=#000000 height=69 cellSpacing=0 cellPadding=0 width="86%" border=1>
<TBODY>
<TR>
<TD width="100%" bgColor=#c0c0c0 height=13><FONT size=2>&nbsp;build.xml</FONT></TD></TR>
<TR>
<TD width="100%" height=52><FONT size=2><TEXTAREA style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体" name=S1 rows=13 cols=75>&lt;?xml version="1.0"  encoding="GB2312" ?&gt;

&lt;!-- 一个项目,可包含很多任务组(target) --&gt;
&lt;project default="main" basedir="."&gt;

    &lt;!-- 项目中的一个任务组,可包含很多任务(task:javac,java...) --&gt;
    &lt;target name="main"&gt;

        &lt;!--编译--&gt;
        &lt;javac srcdir="src\main\hello\ant" destdir="build\classes"/&gt;

        &lt;!--运行--&gt;
        &lt;java classname="hello.ant.HelloAnt"&gt;
            &lt;classpath&gt;
                &lt;pathelement path="build\classes"/&gt;
            &lt;/classpath&gt;
        &lt;/java&gt;

    &lt;/target&gt;
&lt;/project&gt;</TEXTAREA> </FONT></TD></TR></TBODY></TABLE></P>
<P><FONT size=2>ok,一切大功告成，哦，不，还没有运行它。</FONT></P>
<P><FONT size=2>dos下进入hello-ant的目录，即build.xml所在的目录，我们要用ant工具执行它 ，&nbsp;</FONT></P>
<P><FONT size=2>执行: %ant_home%/bin/ant -file build.xml&nbsp;&nbsp;&nbsp;&nbsp; 用ant工具执行当前目录下的配置文件build.xml&nbsp;</FONT></P>
<P><FONT size=2>或&nbsp; ：ant -file build.xml&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 你如果设置%ant_home%/bin到path中</FONT></P>
<P><FONT size=2>这次ok了，这是答案：</FONT></P>
<P align=left>
<TABLE style="BORDER-COLLAPSE: collapse" borderColor=#000000 height=69 cellSpacing=0 cellPadding=0 width="86%" border=1>
<TBODY>
<TR>
<TD width="100%" bgColor=#c0c0c0 height=13><FONT size=2>命令提示符窗口</FONT></TD></TR>
<TR>
<TD width="100%" bgColor=#000000 height=52><FONT color=#ffffff size=2>D:\temp\hello-ant&gt;ant -file build.xml<BR>Buildfile: build.xml<BR><BR>main:<BR>[javac] Compiling 1 source file to D:\temp\hello-ant\build\classes<BR>[java] hello ant,ant 的第一次接触，好棒！<BR><BR>BUILD SUCCESSFUL<BR>Total time: 2 seconds<BR>D:\temp\hello-ant&gt;</FONT> </TD></TR></TBODY></TABLE></P>
<P><FONT size=2>检查一下build/classes目录，哦，看到编译过的文件就在这里:<BR>build/classes/hello/ant/HelloAnt.class.</FONT></P>
<P><B><FONT color=#ff0000 size=2>hello ant 进级</FONT></B></P>
<P><FONT size=2>(此段比较废话，可以略过)<BR><FONT face=仿宋_GB2312>你也许会说：这末简单的工作写个批处理不就得了，又xml又ant的，把我的时间都浪费完了，我用jbuild或<BR>webShpere不就得了，怎末说你才明白呢？反正网上开源项目大多数都用ant,你总不能给人家个*.jpx吧，<BR>而且这样的工具太贵，受不了(当然用D的兄弟不怕^_^ )，而且ant可以让你明确的管理和自动化所有的东西:<BR>编译-实施-测试...,哎，稍微麻烦一点点，但节约你以前花在零碎的copy,paste上的时间.而且我发现管理<BR>代码的质量有所提高.</FONT></FONT></P>
<P><FONT size=2>我们要改进build.xml，让它做更多的事情：</FONT></P>
<UL>
<LI><FONT size=2>定义全局变量</FONT> 
<LI><FONT size=2>初始化,主要是建立目录</FONT> 
<LI><FONT size=2>编译&nbsp; (已有)</FONT> 
<LI><FONT size=2>打包为jar</FONT> 
<LI><FONT size=2>建立API documentation</FONT> 
<LI><FONT size=2>生成distribution产品</FONT> </LI></UL>
<P class=MsoNormal><FONT face=仿宋_GB2312 size=2>凡事都讲究平衡，你要ant给你做更多事，当然要累一点点，不过只用累一次，以后的代码修改后的构建都是"一键式"完成,我们制作一个hello的简单例子，你可以自己做j2ee的练习。</FONT></P>
<P class=MsoNormal><FONT face=宋体 size=2>我们要扩充目录结构，使它更像回事：</FONT></P>
<P class=MsoNormal><FONT face=宋体 size=2>ant处理编译之前的目录：</FONT></P>
<P class=MsoNormal><FONT face=宋体 size=2><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大图 height=170 src="http://www.huihoo.com/java/hello-ant/images/hello-ant-dir-advance-2.gif" width=425 onload="java_script_:if(this.width>600)this.width=600" border=1></FONT></P>
<P class=MsoNormal><FONT face=宋体 size=2>ant处理之后的目录：</FONT></P>
<P class=MsoNormal><FONT size=2><IMG onmousewheel="return bbimg(this)" title=点击新窗口查看大图 height=283 src="http://www.huihoo.com/java/hello-ant/images/hello-ant-dir-advance-1.gif" width=454 onload="java_script_:if(this.width>600)this.width=600" border=1></FONT></P>
<P class=MsoNormal><FONT size=2>图中：\src,\docs,\lib是自己组织的文件结构，\build,\dist是ant动态生成的成品。</FONT></P>
<P class=MsoNormal><FONT size=2>\src&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 源文件：java源，script源，jsp源，xml配置.....<BR>\src\main&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; java源<BR>\src\script&nbsp;&nbsp;&nbsp;&nbsp; window,unix,liunx的执行script，我们的简单只有一个：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; run.bat:&nbsp; java hello.ant.HelloAnt</FONT></P>
<P class=MsoNormal><FONT size=2>\docs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; 手写说明文档<BR>\lib&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; 程序所需类库的jar,比如j2ee.jar,mail,jar...</FONT></P>
<P class=MsoNormal><FONT size=2>\build&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用ant动态生成的构建目录<BR>\build\classes&nbsp; 编译的类文件<BR>\build\docs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; copy "\docs"的手写说明文档，和ant生成的api文档<BR>\build\lib&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; 放置我们自己的HelloAnt.class打包成品hello-ant.jar</FONT></P>
<P class=MsoNormal><FONT size=2>\dist\bin&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; copy "\src\script" 得执行文件<BR>\dist\docs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; copy "\build\docs" 的文档<BR>\dist\lib&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; 除了copy "\build\lib"下的hello-ant.jar外，<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 还应copy "\lib"的程序所需jar，这里我们没有。</FONT></P>
<P class=MsoNormal><FONT size=2>以上是我学老外的文件组织，大家可以按照自己的爱好组织</FONT></P>
<P class=MsoNormal><FONT size=2>我们编写必要的文件： </FONT></P>
<P align=left>
<TABLE style="BORDER-COLLAPSE: collapse" borderColor=#000000 height=29 cellSpacing=0 cellPadding=0 width="86%" border=1>
<TBODY>
<TR>
<TD width="100%" bgColor=#c0c0c0 height=13><FONT size=2>hello.ant.&nbsp;HelloAnt.java</FONT></TD></TR>
<TR>
<TD width="100%" height=12><FONT size=2>已有</FONT> </TD></TR></TBODY></TABLE>
<TABLE style="BORDER-COLLAPSE: collapse" borderColor=#000000 height=69 cellSpacing=0 cellPadding=0 width="86%" border=1>
<TBODY>
<TR>
<TD width="100%" bgColor=#c0c0c0 height=13><FONT size=2>\src\script.bat</FONT></TD></TR>
<TR>
<TD width="100%" height=52><FONT size=2><TEXTAREA style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体" name=S1 rows=7 cols=75>@echo off
echo ========================================================
echo   请先设置 Environment
echo .
echo   JAVA_HOME: %JAVA_HOME%
echo ======================================================

%java_home%\bin\java -classpath ..\lib\hello-ant.jar  hello.ant.HelloAnt

pause </TEXTAREA> </FONT></TD></TR></TBODY></TABLE>
<TABLE style="BORDER-COLLAPSE: collapse" borderColor=#000000 height=69 cellSpacing=0 cellPadding=0 width="86%" border=1>
<TBODY>
<TR>
<TD width="100%" bgColor=#c0c0c0 height=13><FONT size=2>\docs\index.html 随便写一个手写的文档</FONT></TD></TR>
<TR>
<TD width="100%" height=52>
<P align=center><B><FONT color=#ff0000 size=2>hello ant 软件项目手册docs</FONT></B></P>
<HR color=#008000 SIZE=1>

<P align=center><B><A href="http://www.huihoo.com/java/hello-ant/api/index.html"><FONT color=#ff0000 size=2>访问api文档</FONT></A></B></P>　 </TD></TR></TBODY></TABLE>
<TABLE style="BORDER-COLLAPSE: collapse" borderColor=#000000 height=69 cellSpacing=0 cellPadding=0 width="86%" border=1>
<TBODY>
<TR>
<TD width="100%" bgColor=#c0c0c0 height=13><FONT size=2>\build.xml 配置文件&nbsp;</FONT></TD></TR>
<TR>
<TD width="100%" height=52><FONT size=2><TEXTAREA style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体" name=S1 rows=24 cols=83>&lt;?xml version="1.0"  encoding="GB2312" ?&gt;
&lt;!--
    =======================================================================
      hello-ant 项目 ,学习ant工具的第2个build file.

      参照ant的jakarta-ant-1.6alpha的build.xml

      Copyright (c) 2002 The Neusoft Software Foundation.  All rights
      reserved.

    =======================================================================
--&gt;

&lt;!--
    文档结构为:
    &lt;project&gt;
        &lt;property/&gt;               全局变量的定义
        &lt;property/&gt;...

        &lt;target name="1"&gt;         任务组(tasks)
            &lt;javac&gt;&lt;/javac&gt;       一项javac任务
            ...
            &lt;oneTask&gt;&lt;/ontTask&gt;   一项其它任务
        &lt;/target&gt;

        &lt;target name="2"&gt;
            &lt;javac&gt;&lt;/javac&gt;
            ...
            &lt;oneTask&gt;&lt;/ontTask&gt;
        &lt;/target&gt;
    &lt;/project&gt;

    project代表一个项目，
    default:运行到名称为"dist"的target(任务组)
    basedir:基准路径。
--&gt;
&lt;project default="dist" basedir="."&gt;

&lt;!--
    ===================================================================
      定义属性（property tasks）
      最好把用到的路径呀，名称呀都在这里定义成全局变量
      例：定义
          &lt;property name="a" value="hello"/&gt;
      以后就可以这样用它：
          &lt;property name="b" value="${a}/b"/&gt;
      现在:b=="hello/b"
    ===================================================================
--&gt;

    &lt;!--主要的系统环境属性--&gt;
    &lt;property environment="env"/&gt;&lt;!--取window,unix...的环境变量--&gt;
    &lt;property name="java.home" value="${env.JAVA_HOME}"/&gt;
    &lt;property name="ant.home"  value="${env.ANT_HOME}"/&gt;

    &lt;!--主要的app环境属性--&gt;
    &lt;property name="app.name"      value="hello-ant"/&gt;
    &lt;property name="app.jar"       value="${app.name}.jar"/&gt;
    &lt;property name="app.copyright" value=" Copyright (c) 2002 The Neusoft Software Foundation.  All rights reserved."/&gt;


    &lt;!--app中src的属性--&gt;
    &lt;property name="src.dir"    value="src" /&gt;
    &lt;property name="src.main"   value="${src.dir}/main"/&gt;
    &lt;property name="src.script" value="${src.dir}/script"/&gt;

    &lt;!--app用到的lib--&gt;
    &lt;property name="lib.dir" value="lib"/&gt;

    &lt;!--app的build目录中--&gt;
    &lt;property name="build.dir"      value="build" /&gt;
    &lt;property name="build.classes"  value="${build.dir}/classes"/&gt;
    &lt;property name="build.docs"     value="${build.dir}/docs"/&gt;
    &lt;property name="build.docs.api" value="${build.docs}/api"/&gt;
    &lt;property name="build.lib"      value="${build.dir}/lib"/&gt;

    &lt;!--app的dist (distribution) 目录中--&gt;
    &lt;property name="dist.dir"      value="dist"/&gt;
    &lt;property name="dist.bin"      value="${dist.dir}/bin"/&gt;
    &lt;property name="dist.docs"     value="${dist.dir}/docs"/&gt;
    &lt;property name="dist.lib"      value="${dist.dir}/lib"/&gt;

    &lt;!--app的docs目录中--&gt;
    &lt;property name="docs.dir"      value="docs"/&gt;

    &lt;!--
    定义一组路径以后可以通过id重用这组路径 ，例：
    &lt;javac srcdir="src/main" destdir="build/classes"&gt;
            &lt;classpath refid="classpath"/&gt;
    &lt;/javac&gt;
    --&gt;
    &lt;path id="classpath"&gt;
        &lt;!--本项目只有一个java，用不上classpath，这里只是做个例子--&gt;
        &lt;pathelement location="${build.classes}"/&gt;
        &lt;pathelement path="${java.home}/lib/tools.jar"/&gt;
    &lt;/path&gt;

&lt;!--
    ===================================================================
      init 准备目录(File Tasks)
      主要的目录结构通常是不会变的，一起生成他们
    ===================================================================
--&gt;
    &lt;target name="init"&gt;
        &lt;!--清除以前目录--&gt;
        &lt;delete dir="${build.dir}" failonerror="false" /&gt;
        &lt;delete dir="${dist.dir}"  failonerror="false"/&gt;

        &lt;!--准备目录--&gt;
        &lt;mkdir dir="${build.dir}"/&gt;
        &lt;mkdir dir="${build.classes}"/&gt;
        &lt;mkdir dir="${build.docs}"/&gt;
        &lt;mkdir dir="${build.docs.api}"/&gt;
        &lt;mkdir dir="${build.lib}"/&gt;

        &lt;mkdir dir="${dist.dir}"/&gt;
        &lt;mkdir dir="${dist.bin}"/&gt;
        &lt;mkdir dir="${dist.lib}"/&gt;

    &lt;/target&gt;

&lt;!--
    ===================================================================
      Build the code (Compile Tasks,File Tasks)
    ===================================================================
--&gt;
    &lt;target name="build" depends="init"&gt;
        &lt;!--编译--&gt;
        &lt;javac srcdir="${src.main}" destdir="${build.classes}"&gt;
            &lt;classpath refid="classpath"/&gt;
        &lt;/javac&gt;
    &lt;/target&gt;

&lt;!--
    ===================================================================
      打包文档(Archive Tasks)
      Create the project jars: xxx1.jar and xxx2.jar
    ===================================================================
--&gt;
   &lt;target name="jars" depends="build"&gt;
        &lt;jar basedir="${build.classes}" jarfile="${build.lib}/${app.jar}"/&gt;
    &lt;/target&gt;

&lt;!--
     ===================================================================
       Creates the API documentation
     ===================================================================
--&gt;
    &lt;target name="javadocs"
            depends="jars"
            description="--&gt; creates the API documentation"&gt;
        &lt;!--copy docs 手册... --&gt;
        &lt;copy todir="${build.docs}"&gt;
            &lt;fileset dir="${docs.dir}"/&gt;
        &lt;/copy&gt;

        &lt;javadoc packagenames="hello.ant.*"
                 sourcepath="${src.main}"
                 defaultexcludes="yes"
                 destdir="${build.docs.api}"
                 author="true"
                 version="true"
                 use="true"
                 windowtitle="Docs API"&gt;
             &lt;doctitle&gt;&lt;![CDATA[&lt;h1&gt;hello ant Docs API&lt;/h1&gt;]]&gt;&lt;/doctitle&gt;
             &lt;bottom&gt;&lt;![CDATA[&lt;i&gt;${app.copyright}&lt;/i&gt;]]&gt;&lt;/bottom&gt;
             &lt;tag name="todo" scope="all" description="To do:" /&gt;
         &lt;/javadoc&gt;
    &lt;/target&gt;

&lt;!--
     ===================================================================
       Create the distribution that can run (Archive Tasks)
       主要是从各目录中把该copy的copy上
     ===================================================================
--&gt;
   &lt;target name="dist" depends="javadocs"&gt;
        &lt;!--copy bin 执行文件 --&gt;
        &lt;copy todir="${dist.bin}"&gt;
            &lt;fileset dir="${src.script}/"/&gt;
        &lt;/copy&gt;
        &lt;copy todir="${dist.docs}"&gt;
            &lt;fileset dir="${build.docs}/"/&gt;
        &lt;/copy&gt;
        &lt;!-- copy lib 文件 --&gt;
        &lt;copy todir="${dist.lib}"&gt;
            &lt;fileset dir="${build.lib}/"/&gt;
        &lt;/copy&gt;

    &lt;/target&gt;
&lt;!--
     ===================================================================
      Cleans everything(File Tasks)
      例如可以删除build中的文件，留给你发挥吧
     ===================================================================
--&gt;

&lt;/project&gt;</TEXTAREA> </FONT></TD></TR></TBODY></TABLE></P>
<P class=MsoNormal><FONT size=2><BR>build.xml多了些，但其实很简单：(注释比较详细可以参照，这里再简单说一下)</FONT></P>
<P class=MsoNormal><FONT size=2>一个build.xml包含一个工程的自动化处理的完整xml说明，并且基本由3种东东组成：</FONT></P>
<P class=MsoNormal><FONT size=2>&lt;project &gt;<BR><BR>&nbsp;&nbsp;&nbsp; 1.全局变量的定义<BR>&nbsp;&nbsp;&nbsp; &lt;property/&gt;</FONT></P>
<P class=MsoNormal><FONT size=2>&nbsp;&nbsp;&nbsp; 2.任务组<BR>&nbsp;&nbsp;&nbsp; &lt;target&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.许多单项任务... 像copy,delete,javac,jar...<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;task1/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;task2/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;task3/&gt;<BR>&nbsp;&nbsp;&nbsp; &lt;/target&gt;</FONT></P>
<P class=MsoNormal><FONT size=2>&lt;/project&gt;</FONT></P>
<P class=MsoNormal><FONT color=#ff0000 size=2><B>参考及下载：<BR><BR></B></FONT><FONT size=2><A href="http://www.huihoo.com/java/hello-ant/src/hello-ant-src-first.zip"><FONT color=#003366>本文程序:第1个hello-ant<BR></FONT></A><BR><A href="http://www.huihoo.com/java/hello-ant/src/hello-ant-src-advance.zip"><FONT color=#003366>本文程序:第2个进阶的hello-ant</FONT></A></FONT></P>
<P class=MsoNormal><FONT size=2>ant最新下载：<A href="http://jakarta.apache.org/ant/index.html"><BR><FONT color=#003366>http://jakarta.apache.org/ant/index.html</FONT></A>&nbsp;</FONT></P>
<P class=MsoNormal><FONT size=2>ant具体的编写方法参考ant手册以下2部分就形，<BR><A href="http://jakarta.apache.org/ant/manual/using"><FONT color=#003366>http://jakarta.apache.org/ant/manual/using</FONT></A> 使用说明<BR><A href="http://jakarta.apache.org/ant/manual/coretasklist.html"><FONT color=#003366>http://jakarta.apache.org/ant/manual/coretasklist.html</FONT></A> 核心tasks<BR>其他一大堆东西你要看也行。不过我觉得比较浪费时间。<A href="http://jakarta.apache.org/ant/manual/index.html"><BR><FONT color=#003366>http://jakarta.apache.org/ant/manual/index.html</FONT></A>&nbsp; 手册index<BR><BR>huihoo.com翻译改编的<A href="http://jakarta.apache.org/ant/manual/using"><FONT color=#003366>ant/manual/using</FONT></A><BR><A href="http://www.huihoo.com/java/ant.html"><FONT color=#003366>http://www.huihoo.com/java/ant.html</FONT></A> <BR><BR></FONT><FONT size=2><SPAN class=p16><B>用ANT构造Application</B></SPAN>作者：余斌斌 &nbsp;&nbsp;&nbsp;<BR><A href="http://developer.ccidnet.com/pub/disp/Article?columnID=295&amp;articleID=27619&amp;pageNO=1"><FONT color=#003366>http://developer.ccidnet.com/pub/disp/Article?columnID=295&amp;articleID=27619&amp;pageNO=1<BR><BR></FONT></A>ibm 利用 Ant 和 JUnit 进行增量开发——使用单元测试来逐步改进代码</FONT><A href="http://www-900.ibm.com/developerWorks/cn/java/j-ant/index.shtml"><FONT size=2><BR><FONT color=#003366>http://www-900.ibm.com/developerWorks/cn/java/j-ant/index.shtml</FONT></FONT></A></P><img src ="http://www.blogjava.net/surffish/aggbug/22854.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/surffish/" target="_blank">surffish</a> 2005-12-07 14:33 <a href="http://www.blogjava.net/surffish/archive/2005/12/07/22854.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java的Build工具—Ant应用指南（引用）</title><link>http://www.blogjava.net/surffish/archive/2005/12/07/22852.html</link><dc:creator>surffish</dc:creator><author>surffish</author><pubDate>Wed, 07 Dec 2005 06:29:00 GMT</pubDate><guid>http://www.blogjava.net/surffish/archive/2005/12/07/22852.html</guid><wfw:comment>http://www.blogjava.net/surffish/comments/22852.html</wfw:comment><comments>http://www.blogjava.net/surffish/archive/2005/12/07/22852.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/surffish/comments/commentRss/22852.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/surffish/services/trackbacks/22852.html</trackback:ping><description><![CDATA[<BR>本文以最新发布的Ant 1.5.1为例，介绍这款优秀的Build工具的安装配置、基本应用和一些高级话题。最新的Ant下载地址是 <A href="http://jakarta.apache.org/ant/" target=_blank>http://jakarta.apache.org/ant/ </A>。 <BR><BR>Ant是一种基于Java的Build工具。理论上来说，它有些类似于C中的make，但比make优越。现在存在的大多数Build工具，如make、gnumake、nmake、jam等都存在这样或那样的不足，比如依赖于特定的平台、配置文件过于复杂或者对格式无法检查而容易出错等。与这些工具相比较，Ant的两个特性决定了它是一款优秀的Build工具： <BR><BR>1. 基于Java的实现。具有良好的跨平台性，同时可以通过增加新的Java类来扩展Ant的功能，而无需去了解不同平台上不同的脚本语言。 <BR><BR>2.基于XML的配置文件。Ant以XML树来描述Target/Task的关系，文件结构清晰、易读易写，并且利用XML对格式的控制来避免由于配置文件的错误造成的Build操作失败。 <BR><BR>安装与配置 <BR><BR>Ant的安装非常简单，把从网上下载的jakarta-ant-1.5.1-bin.zip解开到一个目录下即可（以下假定安装在目录D:\jakarta-ant-1.5.1）。接下来需要进行环境变量配置： <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>SET ANT_HOME=D:\jakarta-ant-1.5.1 //注意是Ant的安装目录，不是bin子目录<BR>SET PATH=%PATH%;%ANT_HOME%\bin;</TD></TR></TBODY></TABLE><BR><BR>在配置环境变量之前，请确认已经正确设置了JAVA_HOME系统变量。输入ant命令，看到如下输出说明已成功安装了Ant工具： <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>Buildfile: build.xml does not exist!<BR>Build failed</TD></TR></TBODY></TABLE><BR><BR>提示信息表明在当前目录不存在build.xml配置文件，但这本身已经说明Ant成功运行了。 <BR><BR>快速入门 <BR><BR>下面用一个最简单也是最经典的例子-HelloWorld来感受一下Ant吧。 <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>//HelloWorld.java<BR>package com.sharetop.antdemo;<BR>public class HelloWorld {<BR>public static void main( String args[] ) {<BR>System.out.println("Hello world. ");<BR>}<BR>}</TD></TR></TBODY></TABLE><BR><BR>要让Ant编译这个文件，首先需要编写一个Build配置文件。在一般情况下，这个文件被命名为build.xml。 <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>&lt;?xml version="1.0" encoding="UTF-8" ?&gt;<BR>&lt;project name="HelloWorld" default="run" basedir="." &gt;<BR>&lt;property name="src" value="src"/&gt;<BR>&lt;property name="dest" value="classes"/&gt;<BR>&lt;property name="hello_jar" value="hello.jar" /&gt;<BR>&lt;target name="init"&gt;<BR>&lt;mkdir dir="${dest}"/&gt;<BR>&lt;/target&gt;<BR>&lt;target name="compile" depends="init"&gt;<BR>&lt;javac srcdir="${src}" destdir="${dest}"/&gt;<BR>&lt;/target&gt;<BR>&lt;target name="build" depends="compile"&gt;<BR>&lt;jar jarfile="${hello_jar}" basedir="${dest}"/&gt;<BR>&lt;/target&gt;<BR>&lt;target name="run" depends="build"&gt;<BR>&lt;java classname="com.sharetop.antdemo.HelloWorld" classpath="${hello_jar}"/&gt;<BR>&lt;/target&gt;<BR>&lt;/project&gt;</TD></TR></TBODY></TABLE><BR><BR>来看一下这个文件的内容，它描述了以下信息：工程的名字为HelloWorld，工程有四个target，分别是init、compil、build和run，缺省是run。compile只有一个任务javac，源文件位于src目录下，输出的类文件要放在classes目录下。build的任务是jar，生成的jar文件为hello.jar，它打包时以classes为根目录。而run则是执行这个HelloWorld类，用hello.jar作为classpath。这四个target之间有一个依赖关系，这种关系用depends来指定。即如果Target A依赖于Target B，那么在执行Target A之前会首先执行Target B。所以从下面运行缺省Target（run）的输出看，这四个Target的执行顺序是：init→compile→build→run。文件目录结构如图1所示。HelloWorld.java文件在src\com\sharetop\antdemo子目录下。 <BR>
<P align=center><IMG src="http://www.ddvip.net/program/java/index10/img_java_s/70684.gif"> <BR>图1 ant_demo应用的目录结构 </P><BR>在命令行输入命令：ant，然后运行，可以看到如下输出： <BR><BR>如果配置文件名不是build.xml，比如是build_front.xml，那么，可以使用-buildfile命令参数指定： <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>G:\myDoc\ant_demo&gt;ant -buildfile build_front.xml </TD></TR></TBODY></TABLE><BR><BR>也可以单独执行指定的某个target，比如，只编译不打包执行，可以使用下面输入命令即可： <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>G:\myDoc\ant_demo&gt;ant compile </TD></TR></TBODY></TABLE><BR>在相应的目录下会找到编译出的HelloWorld.class文件。 <BR><BR>再看看上面的build.xml配置文件，文件开头定义了3个属性，分别指定了源文件输出路径、类文件输出路径和生成的Jar文件名，后面对这些路径的引用都通过一个${property name}来引用。所以，要注意这样一个原则“目录的定义与目录的引用应该分开”。<BR>基本应用 <BR><BR><STRONG>建立工程的目录 </STRONG><BR><BR>一般要根据工程的实际情况来建立工程的目录结构。但是，有一些比较通用的组织形式可供参考，比如所有的jakarta项目都使用类似的目录结构。下面让我们来看一下这种目录结构的特点。 <BR><BR>表1 <BR><BR>
<TABLE borderColorDark=#ffffff border=1>
<TBODY>
<TR>
<TD>目录 </TD>
<TD>文件 </TD></TR>
<TR>
<TD>bin </TD>
<TD>公共的二进制文件，以及运行脚本 </TD></TR>
<TR>
<TD>build </TD>
<TD>临时创建的文件，如类文件等 </TD></TR>
<TR>
<TD>dist </TD>
<TD>目标输出文件，如生成Jar文件等。 </TD></TR>
<TR>
<TD>doc/javadocs </TD>
<TD>文档。 </TD></TR>
<TR>
<TD>lib </TD>
<TD>需要导出的Java包 </TD></TR>
<TR>
<TD>src </TD>
<TD>源文件 </TD></TR></TBODY></TABLE><BR>对于一个简单的工程，一般包括表1的几个目录。其中bin、lib、doc和src目录需要在CVS的控制之下。当然在这样的目录结构上，也可以做一些调整，例如，可以建立一个extra目录来放置需要发布的Jar文件、Inf文件及图像文件等。同样，如果开发Web应用可以建立一个Web目录放置JSP、HTML等文件。 <BR><BR>如果我们开发的是一个比较复杂的项目，包括多个子项目，并且各个子项目是由不同的开发人员来完成的，那么要如何来设计它的目录结构？首先有一点是需要确定的，不同的子项目应该拥有不同的Build文件，并且整个项目也应该有一个总的Build文件。可以通过Ant任务或是AntCall任务调用子项目的Build文件，如下例： <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>&lt;target name="core" depends="init"&gt;<BR>&lt;ant dir="components" target="core"/&gt;<BR>&lt;ant dir="waf/src" target="core"/&gt;<BR>&lt;ant dir="apps" target="core"/&gt; <BR>&lt;/target&gt;</TD></TR></TBODY></TABLE><BR><BR>在各个子项目的耦合不是非常紧密的情况下，各个子项目应该有各自独立的目录结构，也就是说它们可以有自己的src、doc、build、dist等目录及自己的build.xml文件，但是可以共享lib和bin目录。而对于那些耦合紧密的子项目，则推荐使用同一个src目录，但是不同的子项目有不同的子目录，各个子项目的build.xml文件可以放在根目录下，也可以移到各个子项目的目录下。 <BR><BR><STRONG>编写Build文件 </STRONG><BR><BR>要用好Ant工具，关键是要编写一个build.xml文件。要编写出一个结构良好、灵活可扩展的Build文件，有两个问题要考虑，一是了解Build文件的基本结构，二是了解Ant定义的大量任务。 <BR><BR>Ant的Build文件是一个标准的XML文件，它包含一个根节点Project，每个Project定义了至少一个或多个Target，每个Target又是一系列Task的集合。它们之间的关系如图2所示。 <BR>
<P align=center><IMG src="http://www.ddvip.net/program/java/index10/img_java_s/70685.gif"><BR>图2 build.xml文件的结构</P><BR>每个Task是一段可被执行的代码，比如，前例中的javac、jar就是两个最常用的Task。Ant定义了大量的核心Task，我们要考虑的第二个问题正是如何去掌握这大量的Task。其实唯一的方法就是边学习边实践，这方面最好的参考就是官方的Ant使用手册。 <BR><BR><STRONG>外部文件的使用 </STRONG><BR><BR>使用外部的Property文件可以保存一些预设置的公共属性变量。这些属性可以在多个不同的Build文件中使用。 <BR><BR>可以将一个外部的XML文件导入Build文件中，这样多个项目的开发者可以通过引用来共享一些代码，同样，这也有助于Build文件的重用，示例代码如下所示： <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>&lt;!DOCTYPE project [<BR>&lt;!ENTITY share-variable SYSTEM "file:../share-variable.xml"&gt;<BR>&lt;!ENTITY build-share SYSTEM "file:../build-share.xml"&gt;<BR>]&gt;<BR>&lt;project name="main" default="complie" basedir="."&gt;<BR>&amp;share-variable;<BR>&amp;build-share;<BR>... ...</TD></TR></TBODY></TABLE><BR><BR>在J2EE项目中的应用 <BR><BR>只要掌握了Ant的使用方法，在J2EE项目中的应用与在其它项目中的应用并没有太大的不同，但是仍有几点是需要注意的。 <BR><BR>一是要清楚War和Jar文件的目录结构，主要是War的配置文件web.xml文件的位置和EJB的配置文件（ejb-jar.xml和weblogic-ejb-jar.xml等）的位置，在调用Jar任务打包文件时一定要记得把它们也包含进来。一般在编译之前就要注意把这些需打包的文件拷入相应目录下。二是在J2EE项目中可能会涉及到一些特殊的任务，比如在Weblogic中会调用ejbc预编译EJB的代码存根，或者需要在Ant中同时发布Jar到相应的服务器中等。可以用两种途径实现这些任务，一是扩展Ant任务实现这些任务，二是直接用Java任务来执行这些命令。下面是打包、发布一个EJB的build.xml配置文件片断，代码如下： <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>&lt;target name="deploy_HelloEJB" depends="compile"&gt;<BR>&lt;delete dir="${temp}/ejb_make"/&gt; &lt;!-- 首先删除临时目录 --&gt;<BR>&lt;delete file="${temp}/helloEJB.jar"/&gt;<BR>&lt;!-- 删除WebLogic域中老版本的EJB --&gt;<BR>&lt;delete file="${weblogic.deploy.dest}/helloEJB.jar"/&gt; <BR>&lt;!-- 创建META-INF目录，放置ejb-jar.xml和weblogic-ejb-jar.xml --&gt;<BR>&lt;mkdir dir="${temp}/ejb_make/META-INF"/&gt; <BR>&lt;!-- 拷贝ejb-jar.xml和weblogic-ejb-jar.xml 到临时目录--&gt;<BR>&lt;copy todir="${temp}/ejb_make/META-INF"&gt;<BR>&lt;fileset dir="etc/baseinfo"&gt;<BR>&lt;include name="*.xml"/&gt;<BR>&lt;/fileset&gt;<BR>&lt;/copy&gt;<BR>&lt;!-- 拷贝所有的helloEJB类到临时目录 --&gt;<BR>&lt;copy todir="${temp}/ejb_make/"&gt;<BR>&lt;fileset dir="${dest.classes}/"&gt; &lt;!-- dest.classes是输出的类文件目录 --&gt;<BR>&lt;include name="${dest.classes}/helloEJB/**"/&gt;<BR>&lt;/fileset&gt;<BR>&lt;/copy&gt;<BR>&lt;!-- 将所有这些文件打包成helloEJB.jar --&gt;<BR>&lt;jar jarfile="${temp}/helloEJB.jar" basedir="${temp}/ejb_make"/&gt;<BR>&lt;!-- 进行weblogic.ejbc编译 --&gt;<BR>&lt;java classpath="${wl_cp}" classname="weblogic.ejbc" fork="yes" &gt;<BR>&lt;classpath&gt;<BR>&lt;fileset dir="lib"&gt;<BR>&lt;include name="*.jar" /&gt;<BR>&lt;/fileset&gt;<BR>&lt;/classpath&gt;<BR>&lt;arg value="${temp}/helloEJB.jar" /&gt;<BR>&lt;arg value="${temp}/helloEJB_deploy.jar" /&gt;<BR>&lt;/java&gt;<BR>&lt;!-- 拷贝/发布到WebLogic的{DOMAIN}\applications目录 --&gt;<BR>&lt;copy file="${temp}/helloEJB_deploy.jar" todir="${weblogic.deploy.dest}"/&gt; <BR>&lt;/target&gt;</TD></TR></TBODY></TABLE><BR><BR>用Ant配合JUnit实现单元测试 <BR><BR>Ant 提供了JUnit任务,可以执行单元测试代码。如何使用JUnit，以及如何编写测试用例(TestCase)，感兴趣的读者可以参阅JUnit的相关文档。在Ant中使用JUnit的方法非常简单，首先需要把junit.jar拷入ANT_HOME\lib下，确认在这个目录下有optional.jar，因为JUnit是Ant的扩展任务，需要引用这个扩展包。然后就是在Build文件中加入JUnit的任务，代码如下： <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>&lt;target name="run" depends="client"&gt;<BR>&lt;junit printsummary="yes" fork="yes" haltonfailure="yes"&gt;<BR>&lt;classpath&gt;<BR>&lt;pathelement location="client.jar" /&gt;<BR>&lt;/classpath&gt;<BR>&lt;formatter type="plain" /&gt;<BR>&lt;test name="com.sharetop.antdemo.HelloWorldTest" /&gt;<BR>&lt;/junit&gt;<BR>&lt;/target&gt;</TD></TR></TBODY></TABLE><BR><BR>高级话题 <BR><BR><STRONG>为Ant开发扩展任务 </STRONG><BR><BR>为Ant实现扩展任务其实是非常容易的，只需按照以下几个步骤即可： <BR><BR>1. 创建一个Java类继承org.apache.tools.ant.Task类； <BR><BR>2. 对每个属性实现set方法。Ant会根据需要自动完成类型转换； <BR><BR>3. 如果扩展的任务需要嵌套其它的Task，那么这个Java类必需实现接口org.apache.tools.ant.TaskContainer； <BR><BR>4. 如果扩展的任务要支持Text，需要增加一个方法void addText(String)； <BR><BR>5. 对每个嵌套的元素，实现create、add 或 addConfigured 方法； <BR><BR>6. 实现public void execute方法； <BR><BR>7. 在build.xml文件中使用 &lt;taskdef&gt; 来引用自定义的Task。 <BR><BR>下面以一个简单的例子来说明如何为Ant增加一个hello任务，它可以连续打印多条信息，打印的次数由属性count指定，而打印的内容则由它内嵌的一个helloinfo任务的message属性指定，看上去这非常类似JSP中自定义标签的一些概念，实现代码如下： <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>//HelloInfoTask.java<BR>package com.sharetop.antdemo;<BR>import org.apache.tools.ant.*;<BR>public class HelloInfoTask {<BR>private String msg;<BR>public void execute() throws BuildException {<BR>System.out.println(msg);<BR>}<BR>public void setMessage(String msg) {<BR>this.msg = msg;<BR>}<BR>}</TD></TR></TBODY></TABLE><BR><BR>下面是外部Task类的代码： <BR><BR>
<TABLE cellSpacing=0 width=365>
<TBODY>
<TR>
<TD class=code width=361>//HelloTask.java<BR>package com.sharetop.antdemo;<BR>import org.apache.tools.ant.*;<BR>public class HelloTask extends Task implements org.apache.tools.ant.TaskContainer <BR>{<BR>private Task info;<BR>private int count;<BR>public void execute() throws BuildException {<BR>for(int i=0;i&lt;count;i++)<BR>info.execute();<BR>}<BR>public void setCount(int c){<BR>this.count=c;<BR>}<BR>public void addTask(Task t){<BR>this.info=t;<BR>}<BR>}</TD></TR></TBODY></TABLE><BR><BR>实现了这两个Task，在build.xml文件中定义它的task name，就可以在Target中执行它了。如果你不想使用 &lt;taskdef&gt; 标签来定义Task，也可以通过修改default.properties文件来实现引入新Task，这个文件位于org.apache.tools.ant.taskdefs 包里。下例是一个使用 标签来引入新Task的Build文件部分： <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>&lt;target name="hello" depends="client"&gt;<BR>&lt;taskdef name="hello" <BR>classname="com.sharetop.antdemo.HelloTask" classpath="client.jar"/&gt;<BR>&lt;taskdef name="helloinfo"<BR>classname="com.sharetop.antdemo.HelloInfoTask" classpath="client.jar"/&gt;<BR>&lt;hello count="3" &gt;<BR>&lt;helloinfo message="hello world" /&gt;<BR>&lt;/hello&gt;<BR>&lt;/target&gt;</TD></TR></TBODY></TABLE><STRONG>在自己的程序中调用Ant <BR><BR></STRONG>Ant的任务其实就是一段功能代码。Ant内置的大量任务对于我们开发Java应用具有非常大的意义，为什么我们不能直接使用呢？ <BR><BR>因为尽管在程序中调用Ant的任务并不复杂，而且我们知道Ant的任务其实都是一些Java类，调用的方法无非就是执行这些类而已，不过在执行之前需要对它做一些初始化的工作，所以我们需要引用一个Task类的子类来实现这个功能，比如如下代码： <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>package com.sharetop.antdemo;<BR>import org.apache.tools.ant.*;<BR>import org.apache.tools.ant.taskdefs.*;<BR>import java.io.File;<BR>public class RunAntTask {<BR>public RunAntTask() {<BR>}<BR>public static void main(String args[]){<BR>AntJAR j = new AntJAR();<BR>j.setBasedir(new File("./classes"));<BR>j.setJarfile(new File("aaa.jar"));<BR>j.execute();<BR>}<BR>}<BR>final class AntJAR extends Jar {<BR>public AntJAR() {<BR>project = new Project();<BR>project.init();<BR>taskType = "jar";<BR>taskName = "jar";<BR>}<BR>}</TD></TR></TBODY></TABLE><BR><BR>注意AntJAR类的构造方法，先创建了Project并初始化它，这是直接调用Task的必需条件。 <BR><BR>如果要在自己的程序中执行Ant，需要了解的是Ant定义的几个BuildEvent，它包括： <BR><BR>◆ Build started <BR><BR>◆ Build finished <BR><BR>◆ Target started <BR><BR>◆ Target finished <BR><BR>◆ Task started <BR><BR>◆ Task finished <BR><BR>◆ Message logged <BR><BR>我们需要做的是实现BuildListener接口来处理各种事件，而执行Ant的方法与上面给的例子非常类似，以实际开发的AntBuilder软件的部分代码为例： <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>public void buildTarget(String targetName,String buildFileName) {<BR>try {<BR>Project p = new Project();<BR>p.init();<BR>File f = new File(buildFileName);<BR>p.setUserProperty("ant.file",f.getAbsolutePath());<BR>ProjectHelper.configureProject(p,f);<BR>p.addBuildListener(this);<BR>if( targetName==null )<BR>p.executeTarget(p.getDefaultTarget());<BR>else<BR>p.executeTarget(targetName);<BR>}<BR>catch (Exception ex) {<BR>jTextArea1.append(ex.getMessage());<BR>}<BR>}</TD></TR></TBODY></TABLE><BR><BR>创建Project并初始化，设置它的配置文件（build.xml），执行它缺省的或指定的Target，然后在实现了BuildListenser接口的监听器类中对你感兴趣的事件作处理，代码如下： <BR><BR>
<TABLE cellSpacing=0>
<TBODY>
<TR>
<TD class=code>public void buildStarted(BuildEvent event){ /* nothing*/ }<BR>public void buildFinished(BuildEvent event) { /* nothing*/ }<BR>public void targetStarted(BuildEvent event) {<BR>this.jTextArea1.append(event.getTarget().getName()+": \n\r");<BR>}<BR>public void targetFinished(BuildEvent event) {/* nothing*/ }<BR>public void taskStarted(BuildEvent event) {/* nothing*/ }<BR>public void taskFinished(BuildEvent event) { /* nothing*/ }<BR>public void messageLogged(BuildEvent event) {<BR>int prior = event.getPriority();<BR>switch(prior){<BR>case Project.MSG_ERR : <BR>this.jTextArea1.append("["+event.getTask().getTaskName()+"]Err:"<BR>+event.getMessage());<BR>break;<BR>case Project.MSG_INFO:<BR>this.jTextArea1.append("["+event.getTask().getTaskName()+"]"+event.getMessage<BR>());<BR>break;<BR>case Project.MSG_WARN:<BR>this.jTextArea1.append("["+event.getTask().getTaskName()+"]"<BR>+event.getMessage());<BR>break;<BR>case Project.MSG_VERBOSE:<BR>this.jTextArea1.append(event.getMessage());<BR>break;<BR>}<BR>}</TD></TR></TBODY></TABLE><BR><BR>Build.xml文件的写法每个公司都有不同，这里没有太大的参考价值，所以略去。（全文完）<img src ="http://www.blogjava.net/surffish/aggbug/22852.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/surffish/" target="_blank">surffish</a> 2005-12-07 14:29 <a href="http://www.blogjava.net/surffish/archive/2005/12/07/22852.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>