2004年12月02日

http://www.javaworld.com.tw/confluence/display/opensrc/Spring

2004年11月30日

http://blog.csdn.net/legendinfo/archive/2004/11/19/186848.aspx
http://www-900.ibm.com/developerworks/cn/webservices/ws-soapmap/part1/
http://www.huihoo.com/xml/soap/soap12.html#_Toc478383491
http://www.xml.com/pub/a/2003/02/26/binaryxml.html
http://www-900.ibm.com/developerWorks/cn/xml/x-rss20/index.shtml#resources
http://www.dormforce.net/Blog/xebec/articles/933.aspx
http://www.webasp.net/tech/article_show.asp?id=21137
http://telecom.chinabyte.com/SoftChannel/72342371961929728/20041119/1878018.shtml

2004年11月27日

cms相关网址

http://www.chedong.com/tech/cms.html

http://www.cmsreview.com/
http://www.cmsmatrix.org/matrix?wid=2&func=viewDetail&listingId=1001
http://demo.plainblack.com/demo29211.pl/getting_started

改变一生的五句话


  第一句话是:优秀是一种习惯
  
  如果说优秀是一种习惯,那么懒惰也是一种习惯。人出生的时候,除了脾气会因为天性而有所不同,其他的东西基本都是后天形成的。所以,我们的一言一行都是日积月累养成的习惯。所以我们从现在起就要把优秀变成一种习惯,使我们的优秀行为习以为常,变成我们的第二天性。
  
  第二句话是:生命是一种过程
  
  事情的结果尽管重要,但是做事情的过程更加重要,因为结果好了我们会更加快乐,但过程使我们的生命充实。
  
  第三句话是:两点之间最短的距离并不一定是直线
  
  在人与人的关系以及做事情的过程中,我们很难直截了当就把事情做好。有时我们做事情会碰到很多困难和障碍,有时候我们并不一定要硬挺、硬冲,我们可以选择有困难绕过去,有障碍绕过去,也许这样做事情更加顺利。
  
  第四句话是:只有知道如何停止的人才知道如何加快速度
  
  看着别人滑雪,觉得很容易,不就是从山顶滑到山下吗?于是自己穿上滑雪板,哧溜一下就滑下去了,结果是从山顶滑到山下,但实际上是滚到山下,摔了很多个跟斗。最后我反复练习怎么在雪地上、斜坡上停下来。练了一个星期,我终于学会了在任何坡上停止、滑行、再停止。这个时候我就发现自己会滑雪了,就敢从山顶高速地往山坡下冲。因为我知道只要我想停,一转身就能停下来。因此,只有知道如何停止的人,才知道如何高速前进。
  
  第五句话是:放弃是一种智慧,缺陷是一种恩惠
  
  当你拥有六个苹果的时候,千万不要把它们都吃掉,因为你把六个苹果全都吃掉,你也只吃到了六个苹果。如果你把六个苹果中的五个拿出来给别人吃,尽管表面上你丢了五个苹果,但实际上你却得到了其他五个人的友情和好感。当别人有了别的水果的时候,也一定会和你分享,你会从这个人手里得到一个橘子,从那个人手里得到一个梨,最后你可能就得到了六种不同的水果,六个人的友谊。所以说,放弃是一种智慧

2004年11月25日

对于一个Java服务器来说经常要处理一些图形元素,例如地图的创建或者图形和图表等。这些API基本上总是需要运行一个X-server以便能使用AWT(Abstract Window Toolkit,抽象窗口工具集)。然而,运行一个不必要的X-server并不是一种好的网络管理方式。

这个解决方案依赖于你的Java版本。如果你运行在JDK1.4上,那么你将有机会运行headless服务器。

-Djava.awt.headless=true
对于JDK1.3及更低的版本,有个来自eTeks的PJA工具包(Pure Java AWT Toolkit,纯Java AWT工具集)可以使用。它是一个在配置上与Sun的1.4版非常相似的headlessJava服务器,这种配置方式包含一组-D属性标志。


否则会报
Can’t connect to X11 window server using ‘:0.0′ as the value of the DISPLAY variable
异常

启动参数  -Djava.awt.headless=true

2004年11月10日

·
GBK中不支持这个dot, GB2312中支持
所以在 dot = new String(dot.getBytes(“ISO_8859_1″),”GBK”); 时会是?
dot = new String(dot.getBytes(“ISO_8859_1″),”GB2312″); 是正确的

2004年11月07日

按照ejb的方法用从Context中直接找到的DataSource对象中得到连接通用

性比较好。代码也很简单:

Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup(“jdbc/EmployeeDB”);
Connection conn = ds.getConnection();

在Resin中如下配置jdbc就可以了:

<resource-ref>
<res-ref-name>jdbc/EmployeeDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<init-param driver-name=”com.caucho.jdbc.mysql.Driver”/>
<init-param url=”jdbc:mysql_caucho://localhost:3306/test”/>
<init-param user=”name”/>
<init-param password=”password”/>
<init-param max-connections=”20″/>
<init-param max-idle-time=”30″/>
</resource-ref>

安装
在root权限下
configure –prefix=/usr/local/postgres
gmake
gmake install

添加用户
linux 系统命令  adduser postgres

创建数据库/删除数据库
su postgres
[postgres dir]$bin/createdb
[postgres dir]$bin/dropdb

创建用户/删除用户
[postgres dir]$bin/createuser
[postgres dir]$bin/dropuser

启动数据库
[postgres dir]$bin/pg_ctl start -D data -l log/log.dat

启动数据库 允许TCP/IP访问
[postgres dir]$bin/postmaster -D data -i &

停止数据库
[postgres dir]$bin/pg_ctl stop -D data -m smart

用户认证,  其他IP访问本机postgres 数据库
host    dbname      username       IP     IPMASK        trust

 

主题:(风景人一定要看)关于壁挂炉及温控器的几点介绍
壁挂炉的温控器介绍。
壁挂炉有一个十分有用的选配件——温度控制器。在此做一个介绍,并提请各位注意,免得收房装修后再想起它来后悔。所有壁挂炉的面板调节,只能调节出水的温度,即35摄氏度到85摄氏度的出水温度。它与室温的关系极难计算。温度控制器(简称温控器)就是解决这个问题的配件,需要多少度的室温调它就行了。例如:外出将其扭到防冻,回来将它扭到20摄氏度,壁挂炉就会按你的要求使室内无人时为5摄氏度到10摄氏度,有人时为20摄氏度。
温控器有两种:
一种为手动,标有防冻 5摄氏度 →10摄氏度 →15摄氏度 →20摄氏度 →25摄氏度→ 30摄氏度
正像空调一样你任意调节一个温度,室内就恒温在这个温度。
第二种,7天多时段编程温控器,按照你一周的生活规律,编制好程序,进行开机,关机,升温,恒温等运行,例如,早上你一上班,壁挂炉就自己关机,下午你六点到家,五点四十分壁挂炉就开始自己运行,当你走进家门,已是20摄氏度的室温了。当你入睡时,室温自动跳到16摄氏度,这一切变化都是你预先设定的。
温控器是安在人多的客厅的,和办公室的空调开关一样,它是有线连接。在装修时要留一条由壁挂炉底部到客厅的暗线管,内留两根多股的胶线。如果你没有预留,那以后就只有用明线了。
进口温控器,手动的约100——200元/个,编程的500——1000元/个,使用温控器能明显的节气10%——30%。
各个壁挂炉厂家都不生产温控器,所谓原厂都是贴牌。给依马贴牌的温控器厂是意大利依米特(IMIT),绝大数意大利品牌壁挂炉用的都是IMIT的温控器。
国外生产温控器的大厂家有西门子、霍尼韦尔、依米特(IMIT),前两家的温控器以空调制冷为主。只有依米特(IMIT)是一个壁挂炉制热温控器的专业厂。
凡是欧洲产品或合资产品都在壁挂炉底部留有温控器的接口。日、韩系列没有接口。
使用温控器的优点在于:
1、操作更加简单、明确、直接调节室温;
2、更显时尚和档次;
3、节约费用,一个供暖季足以收回成本。
例如100M2的住房,做饭、洗浴、取暖,每供暖季最高2400元,做饭、洗浴耗费占360元,取暖2040元,按节约30%计为612元。由此可见,十年能收回炉子的成本,一年能收回温控器的成本。因此安装温控器是很有必要的。手动与编程的节气效果比较,编程的节气效果优于手动的。
两种温控器,适应的人群略有不同
手动:适应于没有固定作息时间,随时都需调整室温或家中有老人、小孩。由于手动的操作简便,如同开灯、关灯一样,只要识数就行。
编程:适应于有固定作息时间的家庭,因为室温将按设定的程序变化,不会编程的人无法进行改变。编程方法是按说明书及液晶屏上的英文提示,按动不同的按钮。编一次约需10分钟,但是这种温控器节气效果最佳。
如何购买?
在没有装修、入住前不必购买,只是注意在装修时预埋好连接线即可,入住时再选择购买,一般是包安装但不包走线。因此,预留线是重要的,将来买与不买到时再说。
温控器如何布线
温控器上有一个热敏元件,它的电阻随温度而变化,当电阻变化到某一标定值的时候,继电器即能进行开关动作,同时控制壁挂炉的启停。
一、温控器安装位置的选择
1、易操作的地方;
2、能涵盖平均温度的地方;
3、人活动较多的地方(例如客厅);
4、能避开冷源、热源的地方;
也就是说安装位置要远离暖气片,远离门窗,否则暖气刚热,壁挂炉就停,门窗一开壁挂炉就启动。
安装高度在1.4米左右(与灯的开关在同一水平线上)与门窗的距离大于0.8米。
5、在选定的位置预埋方型线盒,并从此处向壁挂炉方向引出线管。
二、壁挂炉处的接线位置
1、在壁挂炉底边的左右,任意选定接线口;
2、预埋方型线盒,并配一个中间有圆孔的盒盖;
3、穿线用2×0.75及以上线径的多股双绞软线(电话线、灯头线都可以,但要两根),穿线室内预留0.5米,壁挂炉预留1米。
4、将预留线绕成团放入盒内,再用相同大小的硬泡沫封死线盒(免得有人拉动)。
三、装修完工,壁挂炉使用正常后,随时可购买安装。
四、最简单的留线方法
1、在安装温控器的位置向下开一条小槽(以能埋线的深度即可)到地面后,将线沿墙跟摆放,一直沿墙直到壁挂炉下边;
2、从壁挂炉墙下开一条小槽到要出线的位置,将线埋入即可;
3、在墙上槽内的线要用小线卡钉紧;
4、将槽涂平即可;
5、线径2×1.0为宜,只要不断就能用。
简单方法不影响木地板或地砖的铺设,只是要小心别让装修工人把线搞断。
由于户型不同,不能一一述说,不妨在装修时自己动手布线,练练手脑也是一乐。
五、温控器的选择
任何厂家的温控器都可以使用,只注意电压为6V以下。购买壁挂炉厂家的温控器好处是利于保修。否则,温控器引起壁挂炉故障,两家都不维修,你就犯难了。
温控器不存在兼容问题,手动的没有电压,编程的安装两节5号电池可用两年,电压3V。

壁挂炉是否需要净水器?
壁挂炉分为两个系统,一是供暖,二是热水。供暖系统不需净水器,原理另文专讲。卫生热水是否需要,因人而异。卫生热水结垢的地方是洗浴喷头和水龙头的出水口,如果水质硬,则每周都会在喷头或龙头出水口有水垢产生,白花花的一片。消除的方法用除垢剂滴几滴就消除了,一瓶除垢剂能用两年。对壁挂炉而言,无需净水器。我使用的一台,三千多元美国产的净水器,只用了一个月就让其下岗,原因是用1吨净化水必须浪费3吨自来水,也就是说净水器仅用于食用与矿泉水价格相近,而用于洗浴太浪费,相当于矿泉水洗澡。在实际使用中必须加压,(手动或水泵)才能将纯净水加到锅炉里,您需要另加泵才能实现理想,从理论上和实际中都没必要给壁挂炉加净水器。
垢的产生:易结垢的钙镁等以离子的形式溶解在水中,这是看不见的。它们在水中有一定的溶解度,大部分物质的溶解度随温度的升高而增大。结垢是由于溶剂的量减小而导致钙镁的化合物以化合物的形式析出。
例如,一杯自来水100克放在空气中,水中溶有1克钙镁离子,当水被蒸发后剩下90克,则90克水只能溶解0.9克钙镁离子,那么就有0.1克的钙镁离子析出形成垢,于是在玻璃杯的水面与空气的边上就会有垢产生(白色的即是)。如果没有蒸发(溶剂水减少)就不会有垢析出,壁挂炉的供温系统是密闭系统,没有蒸发现象,因此垢较难生成。
在热水系统,自来水经加热变成热水,当从喷头或水龙头流出时,由于溶剂(水)水蒸气的型式挥发,减小了溶剂(水)的量,所以就有垢析出,而在管路里确无垢生成。
因此,不必要担心壁挂炉的结垢问题。

2004年11月03日

Java中类的查找与装载出现的问题总是会时不时出现在Java程序员面前,这并不是什么丢脸的事情,相信没有一个Java程序员没遇到过ClassNotException,因此不要为被人瞅见自己也犯这样的错误而觉得不自然,但是在如果出现了ClassNotFoundException后异常后一脸的茫然,那我想你该了解一下java的类装载的体制了,同时为了进行下面的关于类装载器之间的隔离性的讨论,我们先简单介绍一下类装载的体系结构。

1. Java类装载体系结构

装载类的过程非常简单:查找类所在位置,并将找到的Java类的字节码装入内存,生成对应的Class对象。Java的类装载器专门用来实现这样的过程,JVM并不止有一个类装载器,事实上,如果你愿意的话,你可以让JVM拥有无数个类装载器,当然这除了测试JVM外,我想不出还有其他的用途。你应该已经发现到了这样一个问题,类装载器自身也是一个类,它也需要被装载到内存中来,那么这些类装载器由谁来装载呢,总得有个根吧?没错,确实存在这样的根,它就是神龙见首不见尾的Bootstrap ClassLoader. 为什么说它神龙见首不见尾呢,因为你根本无法在Java代码中抓住哪怕是它的一点点的尾巴,尽管你能时时刻刻体会到它的存在,因为java的运行环境所需要的所有类库,都由它来装载,而它本身是C++写的程序,可以独立运行,可以说是JVM的运行起点,伟大吧。在Bootstrap完成它的任务后,会生成一个AppClassLoader(实际上之前系统还会使用扩展类装载器ExtClassLoader,它用于装载Java运行环境扩展包中的类),这个类装载器才是我们经常使用的,可以调用ClassLoader.getSystemClassLoader() 来获得,我们假定程序中没有使用类装载器相关操作设定或者自定义新的类装载器,那么我们编写的所有java类通通会由它来装载,值得尊敬吧。AppClassLoader查找类的区域就是耳熟能详的Classpath,也是初学者必须跨过的门槛,有没有灵光一闪的感觉,我们按照它的类查找范围给它取名为类路径类装载器。还是先前假定的情况,当Java中出现新的类,AppClassLoader首先在类传递给它的父类类装载器,也就是Extion ClassLoader,询问它是否能够装载该类,如果能,那AppClassLoader就不干这活了,同样Extion ClassLoader在装载时,也会先问问它的父类装载器。我们可以看出类装载器实际上是一个树状的结构图,每个类装载器有自己的父亲,类装载器在装载类时,总是先让自己的父类装载器装载(多么尊敬长辈),如果父类装载器无法装载该类时,自己就会动手装载,如果它也装载不了,那么对不起,它会大喊一声:Exception,class not found。有必要提一句,当由直接使用类路径装载器装载类失败抛出的是NoClassDefFoundException异常。如果使用自定义的类装载器loadClass方法或者ClassLoader的findSystemClass方法装载类,如果你不去刻意改变,那么抛出的是ClassNotFoundException。

我们简短总结一下上面的讨论:

1.JVM类装载器的体系结构可以看作是树状结构。

2.父类装载器优先装载。在父类装载器装载失败的情况下再装载,如果都装载失败则抛出ClassNotFoundException或者NoClassDefFoundError异常。

那么我们的类在什么情况下被装载的呢?

2. 类如何被装载

在java2中,JVM是如何装载类的呢,可以分为两种类型,一种是隐式的类装载,一种式显式的类装载。

2.1 隐式的类装载

隐式的类装载是编码中最常用得方式:

A b = new A();

如果程序运行到这段代码时还没有A类,那么JVM会请求装载当前类的类装器来装载类。问题来了,我把代码弄得复杂一点点,但依旧没有任何难度,请思考JVM得装载次序:

package test;
Public class A{
    public void static main(String args[]){
        B b = new B();
    }
}

class B{C c;}

class C{}

揭晓答案,类装载的次序为A->B,而类C根本不会被JVM理会,先不要惊讶,仔细想想,这不正是我们最需要得到的结果。我们仔细了解一下JVM装载顺序。当使用Java A命令运行A类时,JVM会首先要求类路径类装载器(AppClassLoader)装载A类,但是这时只装载A,不会装载A中出现的其他类(B类),接着它会调用A中的main函数,直到运行语句b = new B()时,JVM发现必须装载B类程序才能继续运行,于是类路径类装载器会去装载B类,虽然我们可以看到B中有有C类的声明,但是并不是实际的执行语句,所以并不去装载C类,也就是说JVM按照运行时的有效执行语句,来决定是否需要装载新类,从而装载尽可能少的类,这一点和编译类是不相同的。

2.2 显式的类装载

使用显示的类装载方法很多,我们都装载类test.A为例。

使用Class类的forName方法。它可以指定装载器,也可以使用装载当前类的装载器。例如:

Class.forName(“test.A”);
它的效果和
Class.forName(“test.A”,true,this.getClass().getClassLoader());
是一样的。

使用类路径类装载装载.

ClassLoader.getSystemClassLoader().loadClass(“test.A”);

使用当前进程上下文的使用的类装载器进行装载,这种装载类的方法常常被有着复杂类装载体系结构的系统所使用。

Thread.currentThread().getContextClassLoader().loadClass(“test.A”)

使用自定义的类装载器装载类

public class MyClassLoader extends URLClassLoader{
public MyClassLoader() {
        super(new URL[0]);
    }
}
MyClassLoader myClassLoader = new MyClassLoader();
myClassLoader.loadClass(“test.A”);

MyClassLoader继承了URLClassLoader类,这是JDK核心包中的类装载器,在没有指定父类装载器的情况下,类路径类装载器就是它的父类装载器,MyClassLoader并没有增加类的查找范围,因此它和类路径装载器有相同的效果。

我们已经知道Java的类装载器体系结构为树状,多个类装载器可以指定同一个类装载器作为自己的父类,每个子类装载器就是树状结构的一个分支,当然它们又可以个有子类装载器类装载器,类装载器也可以没有父类装载器,这时Bootstrap类装载器将作为它的隐含父类,实际上Bootstrap类装载器是所有类装载器的祖先,也是树状结构的根。这种树状体系结构,以及父类装载器优先的机制,为我们编写自定义的类装载器提供了便利,同时可以让程序按照我们希望的方式进行类的装载。例如某个程序的类装载器体系结构图如下:

 

图2:某个程序的类装载器的结构

解释一下上面的图,ClassLoaderA为自定义的类装载器,它的父类装载器为类路径装载器,它有两个子类装载器ClassLoaderAA和ClassLaderAB,ClassLoaderB为程序使用的另外一个类装载器,它没有父类装载器,但有一个子类装载器ClassLoaderBB。你可能会说,见鬼,我的程序怎么会使用这么复杂的类装载器结构。为了进行下面的讨论,暂且委屈一下。

3. 奇怪的隔离性

我们不难发现,图2中的类装载器AA和AB, AB和BB,AA和B等等位于不同分支下,他们之间没有父子关系,我不知道如何定义这种关系,姑且称他们位于不同分支下。两个位于不同分支的类装载器具有隔离性,这种隔离性使得在分别使用它们装载同一个类,也会在内存中出现两个Class类的实例。因为被具有隔离性的类装载器装载的类不会共享内存空间,使得使用一个类装载器不可能完成的任务变得可以轻而易举,例如类的静态变量可能同时拥有多个值(虽然好像作用不大),因为就算是被装载类的同一静态变量,它们也将被保存不同的内存空间,又例如程序需要使用某些包,但又不希望被程序另外一些包所使用,很简单,编写自定义的类装载器。类装载器的这种隔离性在许多大型的软件应用和服务程序得到了很好的应用。下面是同一个类静态变量为不同值的例子。

package test;
public class A {
  public static void main( String[] args ) {
    try {
      //定义两个类装载器
      MyClassLoader aa= new MyClassLoader();
      MyClassLoader bb = new MyClassLoader();

      //用类装载器aa装载testb.B类
      Class clazz=aa.loadClass(“testb. B”);
      Constructor constructor=
        clazz.getConstructor(new Class[]{Integer.class});
      Object object =
     constructor.newInstance(new Object[]{new Integer(1)});
      Method method =
     clazz.getDeclaredMethod(“printB”,new Class[0]);

      //用类装载器bb装载testb.B类
      Class clazz2=bb.loadClass(“testb. B”);
      Constructor constructor2 =
        clazz2.getConstructor(new Class[]{Integer.class});
      Object object2 =
     constructor2.newInstance(new Object[]{new Integer(2)});
      Method method2 =
     clazz2.getDeclaredMethod(“printB”,new Class[0]);

      //显示test.B中的静态变量的值
      method.invoke( object,new Object[0]);
      method2.invoke( object2,new Object[0]);
    } catch ( Exception e ) {
      e.printStackTrace();
    }
  }
}

 

//Class B 必须位于MyClassLoader的查找范围内,
//而不应该在MyClassLoader的父类装载器的查找范围内。
package testb;
public class B {
    static int b ;

    public B(Integer testb) {
        b = testb.intValue();
    }

    public void printB() {
        System.out.print(“my static field b is “, b);
    }
}

 

public class MyClassLoader extends URLClassLoader{
  private static File file = new File(“c:\\classes “);
  //该路径存放着class B,但是没有class A

  public MyClassLoader() {
    super(getUrl());
  }

  public static URL[] getUrl() {
    try {
      return new URL[]{file.toURL()};
    } catch ( MalformedURLException e ) {
      return new URL[0];
    }
  }
}

程序的运行结果为:

my static field b is 1
my static field b is 2

程序的结果非常有意思,从编程者的角度,我们甚至可以把不在同一个分支的类装载器看作不同的java虚拟机,因为它们彼此觉察不到对方的存在。程序在使用具有分支的类装载的体系结构时要非常小心,弄清楚每个类装载器的类查找范围,尽量避免父类装载器和子类装载器的类查找范围中有相同类名的类(包括包名和类名),下面这个例子就是用来说明这种情况可能带来的问题。

假设有相同名字却不同版本的接口 A,

版本 1:
package test;
Intefer Same{ public String getVersion(); }
版本 2:
Package test;
Intefer Same{ public String getName(); }

接口A两个版本的实现:

版本1的实现
package test;
public class Same1Impl implements Same {
public String getVersion(){ return “A version 1″;}
}
版本2的实现
public class Same 2Impl implements Same {
public String getName(){ return “A version 2″;}
}

我们依然使用图2的类装载器结构,首先将版本1的Same和Same的实现类Same1Impl打成包same1.jar,将版本2的Same和Same的实现类Same1Impl打成包same2.jar。现在,做这样的事情,把same1.jar放入类装载器ClassLoaderA的类查找范围中,把same2.jar放入类装器ClassLoaderAB的类查找范围中。当你兴冲冲的运行下面这个看似正确的程序。

实际上这个错误的是由父类载器优先装载的机制造成,当类装载器ClassLoaderAB在装载Same2Impl类时发现必须装载接口test.Same,于是按规定请求父类装载器装载,父类装载器发现了版本1的test.Same接口并兴冲冲的装载,但是却想不到Same2Impl所希望的是版本2 的test.Same,后面的事情可想而知了,异常被抛出。

我们很难责怪Java中暂时并没有提供区分版本的机制,如果使用了比较复杂的类装载器体系结构,在出现了某个包或者类的多个版本时,应特别注意。

掌握和灵活运用Java的类装载器的体系结构,对程序的系统设计,程序的实现,已经程序的调试,都有相当大的帮助。希望以上的内容能够对您有所帮助。