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