<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>Vincent's gossip</title>
    <description></description>
    <link>http://gossip.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>圣诞，也来凑个热闹！</title>
        <author>SunMicro</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://gossip.javaeye.com">SunMicro</a>&nbsp;
          链接：<a href="http://gossip.javaeye.com/blog/150699" style="color:red;">http://gossip.javaeye.com/blog/150699</a>&nbsp;
          发表时间: 2007年12月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          中午休息的时候看了篇文章文章《Ben's Christmas day》，激发了一点Gossip情绪。也说说中美圣诞的差异。<br />    虽不是土鳖节，但也同样搞得有声有色，大有超英赶美的趋势，而且听说去年重庆的热闹程度都超过人家洛杉矶了（根据我的现场观察，很有可能）。都是图热闹，但中美圣诞的差距是相当之大，首先是目标人群的差异，在美国，凑一起的是家人，中国则多是一些死党。准确来讲，美国的圣诞更像是中国的春节（lunar new year）。<br />    中国过圣诞相对来说是比较仓促的，计划时间大概在两三周左右，而美国一般的家庭都是用半年时间来准备，而且相对于中国，美国有一套很完善的圣诞节加热系统（Completed Promotion System),这套系统将在大家吃完Thanksgiving的火鸡后全面启动。由于在Thanksgiving后，美国人民会有他们的新年假期，所以他们将有充足的时间来执行计划了大半年的Christmas Happy方案。另一方面，由于历史传统以及经济发达程度的不同，美国的圣诞节期间要卖到价廉物美的东西还是很容易的，尽管平均商品价格在节日计划执行期会有一定的上调，但商品自身的价值也在提高，而且只要圣诞节一过，商品价格立马回调到普通水平。整个Christmas Commercial System实际上更多的是在回馈社会，皆大欢喜！而中国则混杂了大量的商业臭味在里面，商品价格同期会整体上涨，但价位将从圣诞前期一直持续到春节后期，喜气洋洋的看着爽，聞起来才知道夹了点一氧化碳。<br />    不知道什么时候开始凑圣诞节热闹的，可能是是耶稣势力扩张时期，也可能是网络腾飞年代？至于原因，可能是和谐社会经济的迅猛发展，也可能是扩散在网络上的病毒导致了孤独的极速蔓延。
          <br/>
          <span style="color:red;">
            <a href="http://gossip.javaeye.com/blog/150699#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 25 Dec 2007 14:32:20 +0800</pubDate>
        <link>http://gossip.javaeye.com/blog/150699</link>
        <guid>http://gossip.javaeye.com/blog/150699</guid>
      </item>
      <item>
        <title>lambda算子中的数</title>
        <author>SunMicro</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://gossip.javaeye.com">SunMicro</a>&nbsp;
          链接：<a href="http://gossip.javaeye.com/blog/149512" style="color:red;">http://gossip.javaeye.com/blog/149512</a>&nbsp;
          发表时间: 2007年12月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          数学基础差加之受严重的功利主义思想的影响，我对数学一直是没有太大兴趣。不过最近一段时间在看《算法导论》和《SICP》，几周下来发现进度之慢，归结原因是大部分数学知识都被我遗弃了，然后看的时候不得不在案头放上离散数学、微积分、线性代数、统计学、运筹学等大学未弃之书作为速查手册，说能快起来那是在自我忽悠。<br />    做程序不能不懂数学犹如绘画不能不懂素描，基本功扎实了才好发挥。但鉴于程序员与数学家还是有本质的不同，不但要保持思维跨度在1到pow(10,15)也就是15个数量级之间还要学习相应业务知识以及应对客户，有点爱好的还要研究下声乐，绘画。这种情况下大可不必去与数学较劲。所以开发人员在数学的学习上最好是贯彻‘广度优先’这一方针，将要应对的问题和与之对应的数学知识在头脑中建立一张dynamic lookup table即可，待到用的时候在去查阅相关资料。即便不知道具体公式，但若能在求最大公约数的时候立马想到欧老前辈，也就算基本合格了。但话说回来，像这种基础的还是记住的好，不然不好意思跟人家说I'm very professional！<br />    废话一大堆，最近才看到SICP的第三章，前面有一些习题也没有来得及做，昨夜在回顾习题的时候碰上了exercise2.6，关于lambda算子中数的表示，这套形式系统中，酷就酷在可以全由lambda演算系统中的合法符号来表示数，通俗的说就是用没有一个数字的表达式来表达数字<br />SICP中的一个例子<br />看看数学中0（zero ）是如何用lambda表达式来定义的：<br /><pre name="code" class="java">(define zero (lambda(f)(lambda(z) z)))</pre><br />对于Alonzo Church来说，看上面的代码好比看英语，但对于在数学之海的岸口张望的人来说，不太直观<br />那再看看one two three<br /><pre name="code" class="java">(define one  (lambda(f)(lambda(z)(f z))))
(define two  (lambda(f)(lambda(z)(f (f z)))))
(define three  (lambda(f)(lambda(z)(f (f (f z))))))</pre><br />似曾相识？那看下面<br /><pre name="code" class="java">
int zero=0;
int one=zero+1;
int two=one+1;
int three=two+1;
</pre><br />通过这样一对比，很容易就可以得出一个Chruch数与自然数的转化式<br /><pre name="code" class="java">
;做个过度
(define f (lambda(x)(+ x 1)))
(display (f (f 0)));output 2
;转换式
(define (cn-to-n cn)
	((cn (lambda(x)(+ x 1)))0))
</pre><br />数的表达有了，接下来就是运算了，习题的要求是做了加法运算<br /><pre name="code" class="java">
(define (add x y)(+ x y))
</pre><br />一个很典型的加法，但不适用于Chruch数<br />要支持Chruch数的运算，那至少要在运算式中将其表达出来吧。<br />从前面的定义来看，lambda(f)(lambda(z)..)是跑不了的，由于Chruch数本身即是嵌套的函数表达式,那只要我能将最后的结果组合成(f (f (f ..(f z)..)))这番模样就算大功告成了<br />这个时候再琢磨一下前面的Chruch数，然后换个写法<br /><pre name="code" class="java">
(define one   (lambda(f)(lambda(z)(f ((zero f)z)))))
(define two   (lambda(f)(lambda(z)(f ((one  f)z)))))
(define three (lambda(f)(lambda(z)(f ((two  f)z)))))
</pre><br />在Chruch表达式里面(one f)就是one,(two f)就是two,从而推出(x f)=x，再考虑到函数的叠加,试着定义'5',<br /><pre name="code" class="java">
(define five (lambda(f)(lambda(z)((three f)((two f)z)))))
</pre><br />然后从特殊到一般，得出加法运算式<br /><pre name="code" class="java">
(define (add x y) 
	(lambda(f)(lambda(z)((x f)((y f) z)))))
</pre><br />习题是完成了，但凡是涉及到数学的问题都有让人去发散思维的魔力，加法都出来了，何不看看乘法，前面定义了五，现在试着定义下六<br /><pre name="code" class="java">
(define six  (lambda(f)(lambda(z)((three (two f))z))))
;依葫芦画瓢得出乘法定义
(define (mul x y) 
	 (lambda(f)(lambda(z)((x (y f))z))))
</pre><br /><br />解题过程中为求天时地利，坚持坐北朝南，并发扬一贯的连蒙带猜，猜中带推的作风，虽终得正解，但仍不能掩饰数学知识之贫乏，恶补在所难免。
          <br/>
          <span style="color:red;">
            <a href="http://gossip.javaeye.com/blog/149512#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 19 Dec 2007 19:12:32 +0800</pubDate>
        <link>http://gossip.javaeye.com/blog/149512</link>
        <guid>http://gossip.javaeye.com/blog/149512</guid>
      </item>
      <item>
        <title>JVM and Security primary summary</title>
        <author>SunMicro</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://gossip.javaeye.com">SunMicro</a>&nbsp;
          链接：<a href="http://gossip.javaeye.com/blog/89457" style="color:red;">http://gossip.javaeye.com/blog/89457</a>&nbsp;
          发表时间: 2007年06月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          早期JAVA的安全模型被称作&rdquo;沙箱（sandbox）&ldquo;，通过定义这样一个用户可配置的保护域来实现代码的安全性管理，紧接着在JDK1.4中引入了健壮的全功能安全体系，该体系仍然基于沙箱这一概念的，不过新体系的安全策略是向ProtectionDomain授权权限而不是针对单一代码段授权权限<br />
<br />
在最初的沙箱定义中，条件过于严格，导致善意的程序运行受限，新的安全平台体系中引入了代码签名和认证的信任模式，在这种模式下，可以根据代码数字签名的可信度给与适当的执行权限，使足够可信度的代码将充分发挥其作用。<br />
<br />
沙箱由四个基本部分组成:<br />
<ol>
    <li> 类装载器结构</li>
    <li> class文件验证</li>
    <li>内置与jvm的和语言本身的安全特性</li>
    <li>安全管理器和java api</li>
</ol>
<strong>1.类装载器结构<br />
<br />
</strong>jvm通过类装载器实现类的加载并同时建立不同可信度的命名空间，也叫运行时包，只有被同一类加载器所加载的类相互之间才可见，因为他们在同一命名空间，不同的类加载器会创建不同的命名空间，不同命名空间之间是不允许访问（不可见的。jvm在加载类的过程了使用双亲委托模式，既是发现需要装载某一类的时候，首先将这个任务委托给自己的上级类装载器，依次规律，一般情况下类装载任务最后将委托给启动类装载器，只有在双亲无法完成装载的情况下，才由自己完成装载。双亲委托模式首先降低了恶意代码试图利用系统对java api的信任来达到目的的可能性。设想，一个恶意类被命名为java.lang.String,试图使类加载器误以为该恶意类是java api的一部分，但双亲委托将使用启动类加载器首先寻找java.lang.String，启动类加载器的搜索范围在java api中，当在api中找到这个String类后便会进行加载，而恶意的java.lang.String将不会被加载，也就是说恶意代码无法伪造身份。若恶意代码试图将自己&ldquo;混&quot;入java API，比如，一个声明为java.lang.IamHack的类，但由于启动类装载器在api中无法找到该类，它只可能被类路径装载器或用户自定义的类装载器装载，所以与api处在不同的命名空间中，仍然无法获得足够的信任<br />
<br />
<hr size="2" width="100%" />
<strong>2.class文件验证</strong><br />
<br />
这一过程分为四个阶段<br />
<br />
⑴文件结构验证<br />
<br />
sun定义的class文件具有特定的结构，以0xCAFEBABE开头标识这是一份java特定的class文件（cafe babe,听说是对barista所作贡献的感谢）。class文件的每一个组成部分都声明了其类型和长度，检验器可以以此计算出正确的class文件总长度，从而判断是否有删减或附加额外的代码<br />
<br />
下面是一个接口的16进制标识：<br />
<div class="dp-highlighter">
<div class="bar"> </div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="number">0000000</span><span>: cafe babe </span><span class="number">0000</span><span> </span><span class="number">0032</span><span> </span><span class="number">0009</span><span> </span><span class="number">0700</span><span> </span><span class="number">0707</span><span> </span><span class="number">0008</span><span>  .......</span><span class="number">2</span><span>........  </span></span></li>
    <li class=""><span><span class="number">0000010</span><span>: </span><span class="number">0100</span><span> </span><span class="number">0564</span><span> 6f53 </span><span class="number">7468</span><span> </span><span class="number">0100</span><span> </span><span class="number">0328</span><span> </span><span class="number">2956</span><span> </span><span class="number">0100</span><span>  ...doSth...()V..  </span></span></li>
    <li class="alt"><span><span class="number">0000020</span><span>: 0a53 6f75 </span><span class="number">7263</span><span> </span><span class="number">6546</span><span> 696c </span><span class="number">6501</span><span> </span><span class="number">0009</span><span> 446f  .SourceFile...Do  </span></span></li>
    <li class=""><span><span class="number">0000030</span><span>: </span><span class="number">6572</span><span> 2e6a </span><span class="number">6176</span><span> </span><span class="number">6101</span><span> </span><span class="number">0015</span><span> </span><span class="number">6575</span><span> 746f </span><span class="number">7069</span><span>  er.java...eutopi  </span></span></li>
    <li class="alt"><span><span class="number">0000040</span><span>: 612f </span><span class="number">7365</span><span> </span><span class="number">6375</span><span> </span><span class="number">7269</span><span> </span><span class="number">7479</span><span> 2f44 6f65 </span><span class="number">7201</span><span>  a/security/Doer.  </span></span></li>
    <li class=""><span><span class="number">0000050</span><span>: </span><span class="number">0010</span><span> 6a61 </span><span class="number">7661</span><span> 2f6c 616e 672f 4f62 6a65  ..java/lang/Obje  </span></span></li>
    <li class="alt"><span><span class="number">0000060</span><span>: </span><span class="number">6374</span><span> </span><span class="number">0601</span><span> </span><span class="number">0001</span><span> </span><span class="number">0002</span><span> </span><span class="number">0000</span><span> </span><span class="number">0000</span><span> </span><span class="number">0001</span><span> </span><span class="number">0401</span><span>  ct..............  </span></span></li>
    <li class=""><span><span class="number">0000070</span><span>: </span><span class="number">0003</span><span> </span><span class="number">0004</span><span> </span><span class="number">0000</span><span> </span><span class="number">0001</span><span> </span><span class="number">0005</span><span> </span><span class="number">0000</span><span> </span><span class="number">0002</span><span> </span><span class="number">0006</span><span>  ................  </span></span></li>
    <li class="alt"><span><span class="number">0000080</span><span>: 0a                                       .  </span></span></li>
</ol>
</div>
<br />
紧接cafe babe的是虚拟机的主次版本号的16进制标识，然后是常量池中的数据个数，常量次的数据在后侧可以看到，这里包括了类名，方法名等，另外还有字符串和特征符。接下来的对类文件中字段和方法的复杂结构表示。<br />
<br />
<br />
⑵类型数据语义检查<br />
<br />
这一过程需要验证class文件中个组成部分的所属实例是否与声明类型相符合，以及该类型是否符合java语言规定的特定条件，比如final类是否被子类化或是final方法是否被覆写等。另外还有java所有类继承自java.lang.Object，常量池中条目是否合法等。<br />
<br />
<br />
⑶字节码验证<br />
<br />
型数据语义检查并不检验class字节码，字节码的检验将在这个阶段完成。JVM使用的是堆栈体系结构，在使用指令操作数（Java为单字节指令序列）必须将其装入堆栈，JVM规范中又将其称作操作码，每一个操作码后面都跟着一个或多个操作数，为JVM执行操作码时提供额外的数据。JVM依次执行每个操作码，这在JVM内部构成执行线程，每个线程被授予一个由不同栈帧构成的JAVA栈，每一个方法调用都对应内存中的一个栈帧，其中保存了方法中的局部变量和中间结果（保存中间结果的为操作数栈）。<br />
<br />
这期间要验证操作数栈中的数据是否合法，方法的调用过程是否使用了合法的参数，局部变量的访问是否被允许（访问必须在初始化之后），字节码验证的验证工作量是比较大的，其中还包括了跳转命令的检查等。经过字节码验证后。可以确保class文件的完整性。<br />
<br />
<br />
⑷符号引用验证<br />
<br />
class文件中对其引用的类，方法，变量等是以文字符号描述的，该描述保证准确定位至唯一的目标。类装载器装载一个类的时候会对其中包含的字符引用作出解析，首先是查找被引用的类，但不一定会加载，因为JVM的延迟加载会确保被引用的类在第一次使用前被加载。若找到了对应的类，则将文字描述替换为直接引用，如指针。JVM会记住这些直接引用，所遇到同样的描述，则直接替换为直接引用，从而避免重复查找。<br />
<br />
由于JAVA动态链接的特性，可能会导致二进制不兼容，尽管在改动java文件后的重新编译过程中会检查兼容性，但考虑到在运行时加载的类文件在编译时期并不会被检查，所以需要在运行时执行二进制兼容检查。<br />
<hr size="2" width="100%" />
<br />
<strong>3.JVM内置安全特性<br />
<br />
</strong>在执行期，除了符号引用验证，JVM还会对一些内建的安全特性进行检查，大致如下：<br />
<ol>
    <li>类型安全的引用转化</li>
    <li>结构化的内存访问(非指针算法)</li>
    <li>GC</li>
    <li> 数组边界检查</li>
    <li> 空引用检查（NullPoint)</li>
</ol>
强制内存的结构话访问，避免了恶意用户在了解内存分布的情况下通过指针对JVM的内部结构进行破外。当然要了解JVM的内存分布也不是易事。JVM对运行时数据空间的分配是一个黑盒过程，完全由JVM自己决定如何分配，在class中没有任何相关的信息。<br />
<br />
字节码检查的局限就是对于那些不经过字节码检查的方法（如本地方法：native method）无法验证其安全性，所以这里采用的是对动态链接库的访问控制，对于那些足有足够可信度的代码才被允许访问本地方法。具体的实现是，由安全管理器来决定代码是否有调用动态链接库的权限，因为调用本地方法必须调用动态链接库。这样一来，不可信的代码将无法通过调用本地方法来绕过字节码检查。<br />
<hr size="2" width="100%" />
<br />
<strong>4.安全管理器和java api<br />
<br />
</strong>我们建立的java application基本上可以说是畅通无阻的，其原因是默认情况下所有JAVA API的操作都是被允许的。但<br />
<br />
如果稍加限制一下<br />
<br />
新建一个policy(实际上默认既是为read，这点从java.lang.Class中定义getProtectionDomain()方法中可以看出的)<br />
<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"> </div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span>   grant codeBase </span><span class="string">&quot;file:///D:/JavaTestCode/security/securitymanager/&quot;</span><span> {  </span></span></li>
    <li class=""><span>    permission java.io.FilePermission <span class="string">&quot;D:/JavaTestCode/security/securitymanager/*&quot;</span><span>, </span><span class="string">&quot;read&quot;</span><span>;  </span></span></li>
    <li class="alt"><span>};  </span></li>
</ol>
</div>
<br />
<br />
codeBase指定要限制的类所在目录 ：URL<br />
FilePermission 中指定了要保护的文件 ：资源名称<br />
<br />
然后在运行时以<br />
<div class="dp-highlighter">
<ol class="dp-j" start="1">
    <li class="alt"><span><span>java -Djava.security.manager -Djava.security.policy=policyURL appName  </span></span></li>
</ol>
</div>
的形式指定<br />
<br />
（也可以通过在<span style="background-color: rgb(204, 255, 255);"><span style="background-color: rgb(255, 255, 255);">java.security中以policy.url.n=policyURL</span></span>的形式指定）。<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"> </div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">class</span><span> TrustlessWriter  </span></span></li>
    <li class=""><span>{  </span></li>
    <li class="alt"><span>    <span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">void</span><span> main(String[] args)</span><span class="keyword">throws</span><span> Exception  </span></span></li>
    <li class=""><span>    {  </span></li>
    <li class="alt"><span>        File data=<span class="keyword">new</span><span> File(</span><span class="string">&quot;data.txt&quot;</span><span>);  </span></span></li>
    <li class=""><span>        FileWriter writer=<span class="keyword">new</span><span> FileWriter(data);  </span></span></li>
    <li class="alt"><span>        writer.write(<span class="string">&quot;this is a test&quot;</span><span>);  </span></span></li>
    <li class=""><span>        writer.close();  </span></li>
    <li class="alt"><span>  </span></li>
    <li class=""><span>    }  </span></li>
    <li class="alt"><span>}  </span></li>
</ol>
</div>
<br />
在控制台输入：<br />
<div class="dp-highlighter">
<ol class="dp-j" start="1">
    <li class="alt"><span><span>java -Djava.security.manager -Djava.security.policy=myaccess.policy TrustlessWriter   </span></span></li>
</ol>
</div>
<br />
<span style="background-color: rgb(204, 255, 255);"> <br />
<span style="background-color: rgb(255, 255, 255);"> 结果将是抛出类似</span><font color="#ff0000" style="background-color: rgb(255, 255, 255);">java.security.AccessControlException: access denied (java.io.FilePermission data.txt write)</font><span style="background-color: rgb(255, 255, 255);">的错误信息</span><br />
<br />
<span style="background-color: rgb(255, 255, 255);"> 这里需要注意policy的格式</span><br />
<br />
<div class="code_title">policy file syntax     <br />
</div>
<div class="dp-highlighter">
<div class="bar"> </div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span>grant signedBy </span><span class="string">&quot;signer_names&quot;</span><span>, codeBase </span><span class="string">&quot;URL&quot;</span><span>,  </span></span></li>
    <li class=""><span>        principal principal_class_name <span class="string">&quot;principal_name&quot;</span><span>,  </span></span></li>
    <li class="alt"><span>        principal principal_class_name <span class="string">&quot;principal_name&quot;</span><span>,  </span></span></li>
    <li class=""><span>        ... {  </span></li>
    <li class="alt"><span>  </span></li>
    <li class=""><span>      permission permission_class_name <span class="string">&quot;target_name&quot;</span><span>, </span><span class="string">&quot;action&quot;</span><span>,  </span></span></li>
    <li class="alt"><span>          signedBy <span class="string">&quot;signer_names&quot;</span><span>;  </span></span></li>
    <li class=""><span>      permission permission_class_name <span class="string">&quot;target_name&quot;</span><span>, </span><span class="string">&quot;action&quot;</span><span>,  </span></span></li>
    <li class="alt"><span>          signedBy <span class="string">&quot;signer_names&quot;</span><span>;  </span></span></li>
    <li class=""><span>      ...  </span></li>
    <li class="alt"><span>  };  </span></li>
</ol>
</div>
<br />
codeBase 需用声明协议类型，若为本地文件话，需以file:声明，FilePermission里面则直接使用目标文件名或通配符<br />
<br />
<br />
在JAVA2平台安全体系中，访问权限被类型化为对象，也既是说访问权限在Java api中被定义，所有访问权限对象继<br />
<br />
承自抽象类java.security.Permission；<br />
<br />
所以也可以在代码中启动SecurityManager，并执行检查<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"> </div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">class</span><span> TrustlessWriter  </span></span></li>
    <li class=""><span>{  </span></li>
    <li class="alt"><span>    <span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">void</span><span> main(String[] args)</span><span class="keyword">throws</span><span> Exception  </span></span></li>
    <li class=""><span>    {  </span></li>
    <li class="alt"><span>        <span class="comment">//SecurityManager sm=new SecurityManager();</span><span>  </span></span></li>
    <li class=""><span>        FilePermission filePermission=<span class="keyword">new</span><span> FilePermission(</span><span class="string">&quot;D:/JavaTestCode/security/securitymanager/data.txt&quot;</span><span>,</span><span class="string">&quot;write&quot;</span><span>);  </span></span></li>
    <li class="alt"><span>        System.out.println(TrustlessWriter.<span class="keyword">class</span><span>.getProtectionDomain());  </span></span></li>
    <li class=""><span>        AccessController.checkPermission(filePermission);<span class="comment">//sm.checkPermission(filePermission)</span><span>  </span></span></li>
    <li class="alt"><span>        File data=<span class="keyword">new</span><span> File(</span><span class="string">&quot;data.txt&quot;</span><span>);  </span></span></li>
    <li class=""><span>        Writer writer=<span class="keyword">new</span><span> FileWriter(data,</span><span class="keyword">true</span><span>);  </span></span></li>
    <li class="alt"><span>        writer.write(<span class="string">&quot;hello!&quot;</span><span>);  </span></span></li>
    <li class=""><span>        writer.close();  </span></li>
    <li class="alt"><span>    }  </span></li>
    <li class=""><span>}  </span></li>
</ol>
</div>
<br />
<br />
此时可省略-Djava.security.manage，执行命令变为：<br />
<br />
<div class="dp-highlighter">
<ol class="dp-j" start="1">
    <li class="alt"><span><span>java -Djava.security.policy=myaccess.policy TrustlessWriter   </span></span></li>
</ol>
</div>
<span style="background-color: rgb(204, 255, 255);"></span><br />
（AccessController是在JAVA2中引入的，不过考虑到前向兼容，新的平台安全体系中仍然可以使用SecurityManager<br />
<br />
来做检查，但SecurityManager的所有check方法均调用AccessController的checkPermission）<br />
<br />
<br />
<strong>关于代码签名和认证</strong><br />
<br />
新安全平台中对足够信任度的代码放宽了限制，要获得充分信任须通过代码签名来实现，若我们对某一签名团体足够 信任，比如SUN，那么具有该团体签名的代码将被给予充分信任。一个基本的思路大致为，代码发布者创建私钥/公钥对，然后利用私钥对发布代码进行签名，代码使用方在获得代码发布者提供的公钥后对代码进行验证，确认代码确为该提供者提供以及在发布后未经非法修改。这其中存在一些潜在的危险，既是公钥是否是该代码发布者提供的，恶意用户可能替换掉合法的公钥，这会导致用户将给与恶意用户发布的代码以充分信任，目前的常见做法是通过一些权威的证书机构来发布证书而不是公钥，代码发布者被证书发布机构认证合格后，可以将自己的公钥交付证书发布机构，证书发布机构再通过私钥加密该公钥，从而生成证书序列。这样替换公钥的可能性就变得微乎其微。不过世上无绝对安全之事，通过证书机构发布的证书也不是绝对安全的途径。<br />
<br />
对代码进行签名需要将所有class文件打包入jar，然后通过jarsigner对其进行散列计算。<br />
<br />
一个简单的示例：<br />
<br />
1.首先将CredibleDoer.class打包至 credible.jar:<br />
<br />
<div class="dp-highlighter">
<ol class="dp-j" start="1">
    <li class="alt"><span><span>jar cvf credible.jar eutopia/security/CredibleDoer.</span><span class="keyword">class</span><span>   </span></span></li>
</ol>
</div>
<span style="background-color: rgb(204, 255, 255);"><br />
</span>2.创建别名为credible的密钥对，将其保存在至doerkeys：<span style="background-color: rgb(204, 255, 255);"><br />
<div class="dp-highlighter">
<ol class="dp-j" start="1">
    <li class="alt"><span><span>keytool -genkeypair -alias credible -keypass douyourwant -keystore doerkeys  </span></span></li>
</ol>
</div>
<br />
</span>3.为credible.jar进行签名：<br />
<span style="background-color: rgb(204, 255, 255);">
<div class="dp-highlighter">
<ol class="dp-j" start="1">
    <li class="alt"><span><span>jarsigner -keystore doerkeys -storepass </span><span class="number">111111</span><span> -keypass douyourwant credible.jar credible  </span></span></li>
</ol>
</div>
</span>完成对一个jar文件的签名后，会在jar产生两个文件，此处为credible.SF和credible.DSA<br />
<br />
.SF文件保存了一个所有类的列表以及了签名过程中使用的摘要算法，大致如下：<br />
<br />
<div class="code_title">credible.sf</div>
<div class="dp-highlighter">
<div class="bar"> </div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span>Signature-Version: </span><span class="number">1.0</span><span>  </span></span></li>
    <li class=""><span>SHA1-Digest-Manifest-Main-Attributes: 9QUCJMHnILftziSD8agLig+iUN8=  </span></li>
    <li class="alt"><span>Created-By: <span class="number">1.6</span><span>.</span><span class="number">0</span><span> (Sun Microsystems Inc.)  </span></span></li>
    <li class=""><span>SHA1-Digest-Manifest: Z1288OdOqrP+Kstqxv0pS10Je7o=  </span></li>
    <li class="alt"><span>  </span></li>
    <li class=""><span>Name: eutopia/security/CredibleDoer.<span class="keyword">class</span><span>  </span></span></li>
    <li class="alt"><span>SHA1-Digest: ODGgb1aB9Ht0iVwmfhGSU6pRneo=  </span></li>
</ol>
</div>
<br />
<br />
DSA文件是一个二进制密匙文件。<br />
<br />
验证完整性实验：<br />
<br />
现在通过jarsigner -verify credible.jar对该文件进行验证。若文件未经改动，一切正常<br />
<br />
若签名后再将TrustlessDoer.class加入credible.jar且不更新签名，那么验证结果将会给出警告：<br />
<br />
<font color="#ff0000" style="background-color: rgb(255, 255, 255);">警告：<br />
此 jar 包含尚未进行完整性检查的未签名条目。</font><span style="background-color: rgb(255, 255, 255);"> </span><br />
<br />
若是替换原有class文件，比如这里替换CredibleDoer.class，将会有类似下面的错误提示：<br />
<br />
<font color="#ff0000" style="background-color: rgb(255, 255, 255);">jarsigner： java.lang.SecurityException: SHA1 digest error for eutopia/security/CredibleDoer.class</font><br />
<br />
通过 k<span style="background-color: rgb(255, 255, 255);">eytool -exportcert -file credible.cer -alias credible -keystore doerkeys</span> 可以导出cer正式文件，其中保存了签名的一些基本信息以及公钥<br />
<br />
创建密钥对的算法有DiffieHellman，DSA ，RSA， EC可以通过-sigalg &lt;算法名&gt;指定算法，比如：<br />
<br style="background-color: rgb(204, 255, 255);" />
<span style="background-color: rgb(192, 192, 192);"><span style="background-color: rgb(204, 255, 255);">
<div class="dp-highlighter">
<ol class="dp-j" start="1">
    <li class="alt"><span><span>keytool -sigalg DSA -genkeypair -alias credible -keypass douyourwant -keystore doerkeys  </span></span></li>
</ol>
</div>
</span><br />
</span>参考：JavaTM Cryptography Architecture API Specification &amp; Reference的Appendix A: Standard Names以及Appendix B: Algorithms <br />
<hr size="2" width="100%" />
<br />
<strong style="background-color: rgb(255, 255, 255);">Related Data</strong><br style="background-color: rgb(255, 255, 255);" />
<br style="background-color: rgb(255, 255, 255);" />
<span style="background-color: rgb(255, 255, 255);"> 深入java虚拟机第二版</span><br style="background-color: rgb(255, 255, 255);" />
<br style="background-color: rgb(255, 255, 255);" />
<a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/permissions.html " style="background-color: rgb(255, 255, 255);">Permissions in the JavaTM 2 Standard Edition Development Kit (JDK)</a><br style="background-color: rgb(255, 255, 255);" />
<br style="background-color: rgb(255, 255, 255);" />
<a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/CryptoSpec.html" target="_blank" style="background-color: rgb(255, 255, 255);">JavaTM Cryptography Architecture API Specification &amp; Reference</a><br style="background-color: rgb(255, 255, 255);" />
<br style="background-color: rgb(255, 255, 255);" />
<a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/index.html" target="_blank" style="background-color: rgb(255, 255, 255);">Java 安全性架构文档</a><br style="background-color: rgb(255, 255, 255);" />
<a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/spec/security-spec.doc.html" style="background-color: rgb(255, 255, 255);"><br />
JavaTM 2 Platform Security Architecture</a><br style="background-color: rgb(255, 255, 255);" />
<br style="background-color: rgb(255, 255, 255);" />
<a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/PolicyFiles.html" style="background-color: rgb(255, 255, 255);">Default Policy Implementation and Policy File Syntax</a><br style="background-color: rgb(255, 255, 255);" />
<br style="background-color: rgb(255, 255, 255);" />
<a href="http://www.ibm.com/developerworks/cn/java/j-javaauth/" style="background-color: rgb(255, 255, 255);">Java 授权内幕</a><br style="background-color: rgb(255, 255, 255);" />
<br style="background-color: rgb(255, 255, 255);" />
<a href="http://www.ibm.com/developerworks/cn/java/j-pj2ee9/" style="background-color: rgb(255, 255, 255);">J2EE 探索者: 用 JAAS 和 JSSE 实现 Java 安全性</a></span>
          <br/>
          <span style="color:red;">
            <a href="http://gossip.javaeye.com/blog/89457#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 12 Jun 2007 14:35:13 +0800</pubDate>
        <link>http://gossip.javaeye.com/blog/89457</link>
        <guid>http://gossip.javaeye.com/blog/89457</guid>
      </item>
      <item>
        <title>Lambda Calculus</title>
        <author>SunMicro</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://gossip.javaeye.com">SunMicro</a>&nbsp;
          链接：<a href="http://gossip.javaeye.com/blog/72394" style="color:red;">http://gossip.javaeye.com/blog/72394</a>&nbsp;
          发表时间: 2007年04月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          &lambda;演算是一套用于研究函数定义、函数应用和递归的形式系统。它由 Alonzo Church 和 Stephen Cole&nbsp; Kleene 在 20 世纪三十<br />
<br />
年代引入，Church 运用 lambda 演算在 1936 年给出 判定性问题 (Entscheidungsproblem) 的一个否定的答案。这种演算可以<br />
<br />
用来清晰地定义什么是一个可计算函数。关于两个 lambda 演算表达式是否等价的命题无法通过一个通用的算法来解决，这是<br />
<br />
不可判定性能够证明的头一个问题，甚至还在停机问题之先。Lambda 演算对函数式编程有巨大的影响，特别是Lisp 语言。<br />
<br />
Lambda 演算可以被称为最小的通用程序设计语言。它包括一条变换规则 (变量替换) 和一条函数定义方式，Lambda 演算之通<br />
<br />
用在于，任何一个可计算函数都能用这种形式来表达和求值。因而，它是等价于图灵机的。<br />
<br />
尽管如此，Lambda 演算强调的是变换规则的运用，而非实现它们的具体机器。可以认为这是一种更接近软件而非硬件的方<br />
<br />
式。 <br />
<br />
<strong>有界vs自由<br />
<br />
</strong>
<div class="code_title">python 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-py" start="1">
    <li class="alt"><span><span>(</span><span class="keyword">lambda</span><span>&nbsp;x,y:x+y)+x+y+z&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<br />
lambda表达式中的x，y与外部x，y显然是不同的，为了区别两者，引入了有界和自由的概念。lambda只能处理有界的标识<br />
<br />
符。<br />
<br />
当一个标识符出现在了lambda的参数里面，并包含在了这个lambda表达式中，那么就称其有界限，反之无界。<br />
<br />
<div class="code_title">python 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-py" start="1">
    <li class="alt"><span><span>(</span><span class="keyword">lambda</span><span>&nbsp;x,y:x+y)+x+y+z&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<br />
<br />
x,y被包含在了lambda表达式中，所以其有界，而z没有那么他就是自由标识符,虽然y在lambda的参数中，但并没有在表达式中<br />
<br />
出现。那么他就是自由的<br />
<br />
<strong>有界和自由是一个相对的概念<br />
</strong><br />
<div class="code_title">python 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-py" start="1">
    <li class="alt"><span><span>(</span><span class="keyword">lambda</span><span>&nbsp;x:(</span><span class="keyword">lambda</span><span>&nbsp;y,z:y+2))&nbsp; <br />
    </span></span></li>
</ol>
</div>
<br />
相对于内嵌的lambda，z是自由的，因为在内嵌的表达式中并没有z出现，然后相对于整个lambda表达式，它又是有界的。<br />
<strong><br />
&ldquo;free（x）&rdquo;代表表达式x所有的自由变量集合</strong><br />
<br />
判定lambda表达式完全合法的标准是它的所有变量都是有界的。<br />
<br />
上例中<em>(lambda x,y:x+2)</em>虽然可以在程序中正常执行，但其实是一个不完全合法的lambda表达式<br />
<br />
<strong>lambda算子计算规则</strong><br />
<br />
<strong><em>alpha，beta，eta</em></strong><br />
<br />
<strong>alpha(conversion)(转换规则):</strong><br />
<br />
简单来说就是重命名规则(但被绑定的变量能否由另一个变量替换有一系列的限制）：<br />
<br />
<em>lambda x,y:x+y</em>与<em>lambda m,n:m+n</em>是等价的<br />
<br />
<strong>beta(reduction)(归约)<br />
</strong><br />
将lambda表达式中的有界变量替换为应用中对应得实际值<br />
<br />
<em>(lambda x,y:x+y)(2,3)</em>等价于<em>2+3</em><br />
<br />
Beta的严格定义：<br />
<br />
<strong>lambda x . B e = B[x := e] if free(e) \subset free(B[x := e]</strong><br />
<br />
考虑这样一种情况<br />
<br />
<div class="code_title">python 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-py" start="1">
    <li class="alt"><span><span>(</span><span class="keyword">lambda</span><span>&nbsp;x:(</span><span class="keyword">lambda</span><span>&nbsp;y:x+y)(x+3)&nbsp; <br />
    </span></span></li>
</ol>
</div>
<br />
其等价的表达式现在是<br />
<br />
<em>x+x+3</em><br />
<br />
这里的问题是lambda中得有界变量与（x+3)中得自由变量有冲突，两则是不同的，需要区别<br />
<br />
<em>alpha[x/z]：(lambda x:(lambda y:x+y)(x+3)=(lambda z:(lambda y:z+y)(x+3)</em><br />
<br />
现在展开后就是<em>z+x+3</em>，正确结果<br />
<br />
<br />
<strong>eta(变换)</strong><br />
Eta表达的是外延性的概念，在这里外延性指的是，两个函数对于所有的参数得到的结果都一致，当且仅当它们是同一个函数。<br />
<br />
<br />
<font color="#ff0000">(python中的lambda不等价与该处所指的lambda）</font><br />
<a href="http://www.wikilib.com/wiki?title=Lambda_%E6%BC%94%E7%AE%97&amp;variant=zh-cn">www.wikilib.com/wiki</a>
          <br/>
          <span style="color:red;">
            <a href="http://gossip.javaeye.com/blog/72394#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 19 Apr 2007 10:34:29 +0800</pubDate>
        <link>http://gossip.javaeye.com/blog/72394</link>
        <guid>http://gossip.javaeye.com/blog/72394</guid>
      </item>
      <item>
        <title>XP basis</title>
        <author>SunMicro</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://gossip.javaeye.com">SunMicro</a>&nbsp;
          链接：<a href="http://gossip.javaeye.com/blog/72164" style="color:red;">http://gossip.javaeye.com/blog/72164</a>&nbsp;
          发表时间: 2007年04月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <img src="http://www.xprogramming.com/images/circles.jpg" alt="What is Extreme Programming?--Ron Jeffries  " /><br />
<a href="http://www.xprogramming.com/xpmag/whatisxp.htm">what is Extreme Programming</a><br />
<br />
<strong>simple design</strong>:什么是简单的设计，简单的说就是可以很容易使你团队成员理解并认同的设计，过犹不及<br />
<br />
不少人总是喜欢炫耀自己所掌握的设计模式和最新的设计技巧，而全然不考虑是否<br />
<br />
合适。简单的设计包含两个部分，其核心就我所理解既是把握现在而非充满变数的未来，第一部分：为已经<br />
<br />
定义的功能进行设计，或说是和客户协商好了的需要实现得功能，不要将自己一些自以为是的GOOD IDEA强加<br />
<br />
于设计。第二部分：创建最佳的可实现功能得设计，不管未来怎样，我们只将眼前的工作做到最好。似乎敏<br />
<br />
捷是有意在回避预测，而实际上的原因是敏捷不惧怕改变，。Kent Beck就这个问题专门有写到：&ldquo;只有在你<br />
<br />
正真需要的时候才去做&rdquo;，敏捷提倡的&ldquo;适应&rdquo;,迭代开发可以很方便的改变原来的主意，在这个前提下预测<br />
<br />
是多余和危险的，由预测所产生的内容在面对改变的时候，代价是昂贵的！<br />
<br />
<strong>refactor</strong>：目的是提高代码的质量，使项目在细节上面得到优化，其实这里的概念还比较模糊，什么是高质<br />
<br />
量的代码呢，如CodeComplete所述，不同性质的项目有不同的判定标准，是小型的桌面应用，一般的商用软<br />
<br />
件还是性命攸关的核心控制程序。这需要在稳定，可扩展，易修改等特性中寻求最佳。当然前提是代码简<br />
<br />
单易懂。<br />
<br />
<strong>test</strong>:代码要易于测试，什么样的代码才容易测试呢，当然是以测试为前提写出来的代码。Test-Driven Development说得就是<br />
<br />
&ldquo;测试先行&rdquo;，简单说来就是，先写一个测试程序，定义通过和失败的判断标准，然后以定义的通过标准为目标，实现product <br />
<br />
code.除了是porduct代码容易测试外，TDD还有助于你充分理解你的设计，试想若你对要实现的功能不明确，又如何能写出测<br />
<br />
试程序呢？<br />
<br />
<strong>pair-programming</strong>:存在有不少的争议，多数的反对意见是效率不高。XP关于Pair-Programming的描述：<br />
<br />
<font color="#ff6600">All code to be included in a production release is created by two people working together at a single computer. Pair programming increases software quality without impacting time to deliver. It is counter intuitive, but 2 people working at a single computer will add as much functionality as two working separately except that it will be much higher in quality. With increased quality comes big savings later in the project.</font><br />
<br />
很明显，是为了提高代码质量，避免潜在的错误和不当设计，因为在这个过程中其同时发生的还有Walkthrough和Inspection等<br />
<br />
活动。另外两个人一起工作，偷懒的可能性大幅减少而且解决问题的能力会加强，而且大量实践证明，pair-programming是提<br />
<br />
高软件质量和减少开发时间的有效方法，当然，前提是合理的利用。<br />
<br />
<a href="http://www.xprogramming.com/index.htm">www.xprogramming.com/index.htm</a><br />
<br />
<a href="http://www.extremeprogramming.org/index.html">www.extremeprogramming.org/index.html</a>
          <br/>
          <span style="color:red;">
            <a href="http://gossip.javaeye.com/blog/72164#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 18 Apr 2007 11:51:46 +0800</pubDate>
        <link>http://gossip.javaeye.com/blog/72164</link>
        <guid>http://gossip.javaeye.com/blog/72164</guid>
      </item>
      <item>
        <title>engineering methodologies VS agile methodologies</title>
        <author>SunMicro</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://gossip.javaeye.com">SunMicro</a>&nbsp;
          链接：<a href="http://gossip.javaeye.com/blog/71857" style="color:red;">http://gossip.javaeye.com/blog/71857</a>&nbsp;
          发表时间: 2007年04月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://www.martinfowler.com/articles/newMethodology.html#FromNothingToMonumentalToAgile">www.martinfowler.com/articles/newMethodology.html#FromNothingToMonumentalToAgile<br />
</a><br />
<strong>engineering methodologies</strong>（工程方法，又或则plan-drive methodologies,计划驱动方法），这些方法通<br />
<br />
过对开发过程进行严格而详细的规定，以期使软件开发更可预知以及获得更高的开发效率，这种强调前期计<br />
<br />
划灵感来源与其他工程领域的实践，从而得名工程方法。不过工程方法虽然存在了很长时间，但并没有引起<br />
<br />
人们太多的注意，对其主要的评批是太过于个官僚化，太多德事情需要做，会延缓整个开发进程。<br />
<br />
<strong>agile methodologies</strong>(敏捷方法）以对工程方法的反其道而行得以发展，主要是在无过程和过度过程中寻找<br />
<br />
一种平衡，即从合理的过程中获得满意的回报。<br />
<br />
敏捷方法与工程方法有一些明显的区别，其中之一反映在文档上，敏捷方法不是面向文档（document-<br />
<br />
oriented）的，其倡导的是在给定的任务中使用更少的文档，敏捷方法更象是面向代码（code-oriented）：<br />
<br />
文档的核心应该是源代码<br />
<br />
文档方面的特点并不是敏捷方法的关键所在，文档减少只是表象，其更深层次的特典是：<br />
&nbsp;<br />
&nbsp;1.敏捷方法是强调&ldquo;适应&rdquo;而不是&ldquo;预见&rdquo;，工程方法试图在代码构建之前定制一个详细的计划，若项目庞<br />
<br />
大，那么就需要在一个很长的时间跨度内作出详细计划。然后依照计划进行开发。这种方法的本质是拒绝变<br />
<br />
化的。而敏捷方法强调的是&ldquo;welcome change&rdquo;，其目的就是设计出适应变化的过程，甚至通过改变自身来<br />
<br />
适应变化。<br />
<br />
&nbsp;2.敏捷方法是面向人（people-oriented）而非面向过程（process-oriented）的，工程方法的目标是定义一<br />
<br />
个适合所有人使用的过程。 而敏捷方法则认为没有任何过程可以替代开发组的技能，所以过程的作用应该是<br />
<br />
为开发组提供支持<br />
<br />
<strong>将设计与建造分离开来？</strong><br />
<br />
&nbsp;&nbsp;&nbsp; 《代码大全》的部分比喻在<a href="http://www.martinfowler.com">Martin Fowler</a>的文章中显得有些不合适了，软件工程不同于传统的工程项目，比如土木工程。工<br />
<br />
程方法的思路类似与传统的工程项目，将设计与建造完全分开，因为在传统的工程项目了，设计与建造是两个截然不同的活<br />
<br />
动，设计是难以预计的，需要昂贵的有创造性的人员，建造过程则比较机械，只需要按部就班的工作，这样在建造过<br />
<br />
程中就能使用技能相对较低的人员。然后土木工程与软件工程存在许多不同，首先，土木工程中，设计相对与建造无论是在时<br />
<br />
间上还是经费上都要少得多。但软件工程中编码所占的时间一般要少的多，McConnell 指出在大型项目中，编码和单元测试只<br />
<br />
占15％，这几乎和桥梁工程中的比例倒过来了。即使把所有测试工作都算作是建造的一部分，设计仍要占到50％。<br />
<br />
对比软件工程和传统工程，可以得出一些结论:<br />
<br />
&nbsp;&nbsp;&nbsp; 1.在软件开发中，具体建造费用低得可以认为是没有。<br />
<br />
&nbsp;&nbsp;&nbsp; 2.软件开发中所有工作都是设计，因此需要富有创造性的才智之士。<br />
<br />
&nbsp;&nbsp;&nbsp; 3.创造性的过程是不太容易计划的，因此，可预见性或许是个不可能达到的目标。<br />
<br />
&nbsp;&nbsp;&nbsp; 4.我们应该对用传统工程来隐喻软件构造保持足够的警觉，因为它们是不同类型的活动，需要不同的过程。
          <br/>
          <span style="color:red;">
            <a href="http://gossip.javaeye.com/blog/71857#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 17 Apr 2007 13:52:29 +0800</pubDate>
        <link>http://gossip.javaeye.com/blog/71857</link>
        <guid>http://gossip.javaeye.com/blog/71857</guid>
      </item>
      <item>
        <title>Pluggable Adapters</title>
        <author>SunMicro</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://gossip.javaeye.com">SunMicro</a>&nbsp;
          链接：<a href="http://gossip.javaeye.com/blog/69351" style="color:red;">http://gossip.javaeye.com/blog/69351</a>&nbsp;
          发表时间: 2007年04月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p class="docText">    A <span class="docEmphasis"><span class="docTextHighlight">pluggable</span> <span class="docTextHighlight">adapter</span></span> is an <span class="docTextHighlight">adapter</span> that <span class="docTextHighlight">adapts</span> dynamically to one of several classes. Of course, the <span class="docTextHighlight">adapter</span> can <span class="docTextHighlight">adapt</span> only to classes that it can recognize, and usually the <span class="docTextHighlight">adapter</span> decides which class it is <span class="docTextHighlight">adapting</span> to based on differing constructors or <span class="docEmphasis">setParameter</span> methods.<br />
<br />
Java has yet another way for <span class="docTextHighlight">adapters</span> to recognize which of several classes it must <span class="docTextHighlight">adapt</span> to: <span class="docEmphasis">reflection.</span> You can use reflection to discover the names of public methods and their parameters for any class. For example, for any arbitrary object you can use the <span class="docEmphasis">getClass</span> method to obtain its class and the <span class="docEmphasis">getMethods</span> method to obtain an array of the method names.</p>
<div class="code_title">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"> </div>
<ol class="dp-j">
    <li class="alt"><span><span class="comment">/* </span> </span> </li>
    <li class=""><span><span class="comment"> *Adaptee </span> </span> </li>
    <li class="alt"><span><span class="comment"> */</span><span>  </span></span> </li>
    <li class=""><span></span><span class="keyword">class</span><span> Pathfinder   </span> </li>
    <li class="alt"><span>{   </span> </li>
    <li class=""><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> explore()   </span> </li>
    <li class="alt"><span>    {   </span> </li>
    <li class=""><span>        System.out.println(</span><span class="string">&quot;explore&quot;</span><span>);   </span> </li>
    <li class="alt"><span>    }   </span> </li>
    <li class=""><span>}   </span> </li>
    <li class="alt"><span>  </span> </li>
    <li class=""><span></span><span class="comment">/* </span>  </li>
    <li class="alt"><span><span class="comment"> *Target </span> </span> </li>
    <li class=""><span><span class="comment"> */</span><span>  </span></span> </li>
    <li class="alt"><span></span><span class="keyword">class</span><span> Digger   </span> </li>
    <li class=""><span>{   </span> </li>
    <li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> dig()   </span> </li>
    <li class=""><span>    {   </span> </li>
    <li class="alt"><span>        System.out.println(</span><span class="string">&quot;Dig&quot;</span><span>);   </span> </li>
    <li class=""><span>    }   </span> </li>
    <li class="alt"><span>}   </span> </li>
    <li class=""><span>  </span> </li>
    <li class="alt"><span></span><span class="comment">/* </span>  </li>
    <li class=""><span><span class="comment"> *Target </span> </span> </li>
    <li class="alt"><span><span class="comment"> */</span><span>  </span></span> </li>
    <li class=""><span></span><span class="keyword">class</span><span> Collector   </span> </li>
    <li class="alt"><span>{   </span> </li>
    <li class=""><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> collect()   </span> </li>
    <li class="alt"><span>    {   </span> </li>
    <li class=""><span>        System.out.println(</span><span class="string">&quot;collect&quot;</span><span>);   </span> </li>
    <li class="alt"><span>    }   </span> </li>
    <li class=""><span>}   </span> </li>
    <li class="alt"><span>  </span> </li>
    <li class=""><span></span><span class="comment">/* </span>  </li>
    <li class="alt"><span><span class="comment"> *Adapter </span> </span> </li>
    <li class=""><span><span class="comment"> */</span><span>  </span></span> </li>
    <li class="alt"><span></span><span class="keyword">class</span><span> PluggablePathfinderAdapter   </span> </li>
    <li class=""><span>{   </span> </li>
    <li class="alt"><span>    </span><span class="keyword">private</span><span> Pathfinder pathfinder;   </span> </li>
    <li class=""><span>    </span><span class="keyword">private</span><span> HashMap map=</span><span class="keyword">new</span><span> HashMap();   </span> </li>
    <li class="alt"><span>  </span> </li>
    <li class=""><span>    PluggablePathfinderAdapter(Pathfinder pathfinder)   </span> </li>
    <li class="alt"><span>    {   </span> </li>
    <li class=""><span>        </span><span class="keyword">this</span><span>.pathfinder=pathfinder;   </span> </li>
    <li class="alt"><span>    }   </span> </li>
    <li class=""><span>  </span> </li>
    <li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> adapt(String classname,String methodname)   </span> </li>
    <li class=""><span>    {   </span> </li>
    <li class="alt"><span>        </span><span class="keyword">try</span><span>  </span> </li>
    <li class=""><span>        {   </span> </li>
    <li class="alt"><span>  </span> </li>
    <li class=""><span>            Class _class=Class.forName(classname);   </span> </li>
    <li class="alt"><span>            Method method=_class.getMethod(methodname,</span><span class="keyword">null</span><span>);   </span> </li>
    <li class=""><span>            map.put(classname,method);   </span> </li>
    <li class="alt"><span>        }</span><span class="keyword">catch</span><span>(ClassNotFoundException cnfe)   </span> </li>
    <li class=""><span>        {   </span> </li>
    <li class="alt"><span>            cnfe.printStackTrace();   </span> </li>
    <li class=""><span>        }</span><span class="keyword">catch</span><span>(NoSuchMethodException nsme)   </span> </li>
    <li class="alt"><span>        {   </span> </li>
    <li class=""><span>            nsme.printStackTrace();   </span> </li>
    <li class="alt"><span>        }   </span> </li>
    <li class=""><span>    }   </span> </li>
    <li class="alt"><span>  </span> </li>
    <li class=""><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> explore(String classname)   </span> </li>
    <li class="alt"><span>    {   </span> </li>
    <li class=""><span>        </span><span class="keyword">try</span><span>  </span> </li>
    <li class="alt"><span>        {   </span> </li>
    <li class=""><span>            pathfinder.explore();   </span> </li>
    <li class="alt"><span>            map.get(classname).invoke(Class.forName(classname).newInstance(),</span><span class="keyword">null</span><span>);   </span> </li>
    <li class=""><span>        }</span><span class="keyword">catch</span><span>(Exception e)   </span> </li>
    <li class="alt"><span>        {   </span> </li>
    <li class=""><span>            e.printStackTrace();   </span> </li>
    <li class="alt"><span>        }   </span> </li>
    <li class=""><span>  </span> </li>
    <li class="alt"><span>    }   </span> </li>
    <li class=""><span>}  </span> </li>
</ol>
</div>
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"> </div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span> </span><span class="keyword">class</span><span> PluggableAdapterDemo   </span></span> </li>
    <li class=""><span>{   </span> </li>
    <li class="alt"><span>  </span> </li>
    <li class=""><span>    </span><span class="keyword">public</span><span> PluggableAdapterDemo()   </span> </li>
    <li class="alt"><span>    {   </span> </li>
    <li class=""><span>  </span> </li>
    <li class="alt"><span>    }   </span> </li>
    <li class=""><span>  </span> </li>
    <li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">void</span><span> main(String[] args)   </span> </li>
    <li class=""><span>    {   </span> </li>
    <li class="alt"><span>        Pathfinder pathfinder=</span><span class="keyword">new</span><span> Pathfinder();   </span> </li>
    <li class=""><span>        PluggablePathfinderAdapter adapter=</span><span class="keyword">new</span><span> PluggablePathfinderAdapter(pathfinder);   </span> </li>
    <li class="alt"><span>        adapter.adapt(</span><span class="string">&quot;Digger&quot;</span><span>,</span><span class="string">&quot;dig&quot;</span><span>);   </span> </li>
    <li class=""><span>        adapter.adapt(</span><span class="string">&quot;Collector&quot;</span><span>,</span><span class="string">&quot;collect&quot;</span><span>);   </span> </li>
    <li class="alt"><span>        adapter.explore(</span><span class="string">&quot;Digger&quot;</span><span>);   </span> </li>
    <li class=""><span>    }   </span> </li>
    <li class="alt"><span>  </span> </li>
    <li class=""><span>}  </span> </li>
</ol>
</div>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://gossip.javaeye.com/blog/69351#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 09 Apr 2007 21:34:00 +0800</pubDate>
        <link>http://gossip.javaeye.com/blog/69351</link>
        <guid>http://gossip.javaeye.com/blog/69351</guid>
      </item>
      <item>
        <title>Lazy Loading Singletons</title>
        <author>SunMicro</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://gossip.javaeye.com">SunMicro</a>&nbsp;
          链接：<a href="http://gossip.javaeye.com/blog/64855" style="color:red;">http://gossip.javaeye.com/blog/64855</a>&nbsp;
          发表时间: 2007年03月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          今天在论坛看见一小段代码，不得不佩服作者（<a href="http://crazybob.org/2007/01/lazy-loading-singletons.html">blog</a>）的创新精神。以前在使用Singleton的时候大多采用这样的方式：<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"> </div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">public</span><span> </span><span class="keyword">class</span><span> Singleton {  </span></span></li>
    <li class=""><span>  </span></li>
    <li class="alt"><span> <span class="keyword">static</span><span> Singleton instance;  </span></span></li>
    <li class=""><span>  </span></li>
    <li class="alt"><span>  <span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">synchronized</span><span> Singleton getInstance() {  </span></span></li>
    <li class=""><span>    <span class="keyword">if</span><span> (instance == </span><span class="keyword">null</span><span>)  </span></span></li>
    <li class="alt"><span>      instance = <span class="keyword">new</span><span> Singleton();  </span></span></li>
    <li class=""><span>    <span class="keyword">return</span><span> instance;  </span></span></li>
    <li class="alt"><span>  }  </span></li>
    <li class=""><span>  </span></li>
    <li class="alt"><span>}  </span></li>
</ol>
</div>
但这里的问题是synchronization实际上只在<span><span>getInstance()第一次调用的时候需要，这个方法在多线程频繁调用的应用中必然会成为效率的瓶颈。<br />
<br />
到了</span></span><span><span>java</span></span><span><span>1.5，Bob Lee提到了</span></span> Double-Checked Locking (DCL) ，并强调了是infamous  DCL；这种做法强调了效率<span><span>（但</span></span><span><span>Bob Lee认为</span></span><span><span></span><span class="keyword">volatile</span><span> 不比</span></span><span><span class="keyword">synchronized</span><span>快，另外这种做法会产生更多的代码，所以仍然坚持使用</span></span>plain old synchronization），并不将整个方法<span><span class="keyword">synchronized，而是只对创建</span></span><span><span>Singleton进行同步，这样，线程进入</span></span><span><span>getInstance()，发现</span></span><span><span>instance 已经创建，就会直接返回instance，而不用在方法外等待。</span></span><br />
<br />
在这种情况下，Singleton的实现代码一般是这样：<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"> </div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">static</span><span> </span><span class="keyword">volatile</span><span> Singleton instance;  </span></span></li>
    <li class=""><span>  </span></li>
    <li class="alt"><span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> Singleton getInstance() {  </span></span></li>
    <li class=""><span>  <span class="keyword">if</span><span> (instance == </span><span class="keyword">null</span><span>) {  </span></span></li>
    <li class="alt"><span>    <span class="keyword">synchronized</span><span> (Singleton.</span><span class="keyword">class</span><span>) {  </span></span></li>
    <li class=""><span>      <span class="keyword">if</span><span> (instance == </span><span class="keyword">null</span><span>)  </span></span></li>
    <li class="alt"><span>        instance == <span class="keyword">new</span><span> Singleton();  </span></span></li>
    <li class=""><span>    }  </span></li>
    <li class="alt"><span>  }  </span></li>
    <li class=""><span>  <span class="keyword">return</span><span> instance;  </span></span></li>
    <li class="alt"><span>}  </span></li>
</ol>
</div>
<br />
<span><span>接下来是</span></span> <a href="http://crazybob.org/2007/01/lazy-loading-singletons.html">Bob Lee</a>的创新做法：<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"> </div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">static</span><span> </span><span class="keyword">class</span><span> SingletonHolder {  </span></span></li>
    <li class=""><span>  <span class="keyword">static</span><span> Singleton instance = </span><span class="keyword">new</span><span> Singleton();      </span></span></li>
    <li class="alt"><span>}  </span></li>
    <li class=""><span>  </span></li>
    <li class="alt"><span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> Singleton getInstance() {  </span></span></li>
    <li class=""><span>  <span class="keyword">return</span><span> SingletonHolder.instance;  </span></span></li>
    <li class="alt"><span>}  </span></li>
</ol>
</div>
JLS将保证<span><span>Singleton instance只在第一次调用g</span></span><span><span>etInstance()的时候创建。优雅且快速！</span></span><span><span></span></span>
          <br/>
          <span style="color:red;">
            <a href="http://gossip.javaeye.com/blog/64855#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 23 Mar 2007 10:08:18 +0800</pubDate>
        <link>http://gossip.javaeye.com/blog/64855</link>
        <guid>http://gossip.javaeye.com/blog/64855</guid>
      </item>
  </channel>
</rss>