﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-庄周梦蝶，孰蝶是我，我是孰蝶？一梦至今，蝶我已难分-随笔分类-java</title><link>http://www.blogjava.net/killme2008/category/19800.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 05 May 2008 14:53:44 GMT</lastBuildDate><pubDate>Mon, 05 May 2008 14:53:44 GMT</pubDate><ttl>60</ttl><item><title>使用Rope来高效处理长字符串</title><link>http://www.blogjava.net/killme2008/archive/2008/05/05/198532.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Mon, 05 May 2008 10:41:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/05/05/198532.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/198532.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/05/05/198532.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/198532.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/198532.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 前段时间看了这篇文章《<a href="http://www.ibm.com/developerworks/cn/java/j-ropes/index.html">Ropes：理论与实践</a>》。这两天为了提高工作中某个系统对外接口的效率，才认真学习了一番。本质上Ropes是将字符串表示为一棵二叉树，特别适用于长字符串的处理，貌似c++ STL库中也有这么个实现。具体实现和原理还是看这篇<a href="http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf">paper</a>。《<a href="http://www.ibm.com/developerworks/cn/java/j-ropes/index.html">Ropes：理论与实践</a>》一文中给出的测试数据相当惊人，Ropes比之String和StringBuffer在append,insert,delete等操作上的效率都有一个数量级以上的差距。跑下作者给出的测试程序，其实在测试的字符串不是很长的情况下，这个差距并没有那么大，这也从侧面说明了Rope的应用范围：即只有在大量修改大型字符串的应用程序中才能看到明显的性能提升。那么是否可以用Rope替代StringBuffer做append生成字符串（比如我要的生成xml)。作者也说啦：<br />
&nbsp; &#8220;由于 <code>Rope</code> 的附加性能通常比 <code>StringBuffer</code> 好，这时使用 rope
是否有意义呢？答案还是否。不论何时将输入的数据组合在一起形成格式化输出时，最漂亮最有效的方法是使用模板引擎（例如 StringTemplate
或 FreeMarker）。这种方法不仅能干净地将表示标记与代码分开，而且模板只进行一次编译（通常编译为 JVM
字节码），以后可以重用，从而使它们拥有极佳的性能特征。&#8221;<br />
<br />
&nbsp;&nbsp;&nbsp; 我用Rope for java替代了StringBuffer做XML生成，效率提升在5%-30%左右，xml字符串不是很长，这个提升显然有限，也带来了不必要的复杂度。因此最后还是用Velocity模板引擎来生成XML，测试的结果效率并没有多少改善，但是显然更容易维护和开发了。回到Rope的话题，我用Ruby实现了个版本，Rubyforge上有一个Rope的实现，但是看了源码，与paper所述算法有点差异，因此照着Rope for java也实现了一个<a href="http://code.google.com/p/rope4r/">Rope4r</a>。测试的结果证明在长字符串的累积操作上，Rope4r的append比之String的+=性能可以快上3倍左右，而如果采用String的&lt;&lt;操作，不是immutable的，当然是最快了；比较郁闷的是slice和insert操作都比String的慢上几倍，因为Ruby的String、Array的内建对象都是直接用c写成并做了优化的，我猜测原因在这。<br />
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/198532.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-05-05 18:41 <a href="http://www.blogjava.net/killme2008/archive/2008/05/05/198532.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一切为了跨平台</title><link>http://www.blogjava.net/killme2008/archive/2008/04/22/194849.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 22 Apr 2008 10:12:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/04/22/194849.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/194849.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/04/22/194849.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/194849.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/194849.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 推荐两篇blog：<br />
<a href="http://blog.csdn.net/haoel/archive/2008/03/27/2224055.aspx">《java NIO 类库selector机制解析（上）》</a><br />
<a href="http://blog.csdn.net/haoel/archive/2008/03/27/2224069.aspx">《java NIO 类库selector机制解析（下）》</a><br />
<br />
&nbsp;&nbsp;&nbsp; 有一个奇怪的现象引出的话题，为了<font size="3"><font face="Times New Roman">Selector.wakeup功能做到跨平台，</font></font><font size="3"><span style="font-family: 宋体;" lang="ZH-CN">每个</span><font face="Times New Roman">Selector.open()</font><span style="font-family: 宋体;" lang="ZH-CN">时，在</span><font face="Times New Roman">Windows</font><span style="font-family: 宋体;" lang="ZH-CN">会建立一对自己和自己的</span><font face="Times New Roman">loopback</font><span style="font-family: 宋体;" lang="ZH-CN">的</span><font face="Times New Roman">TCP</font><span style="font-family: 宋体;" lang="ZH-CN">连接；在</span><font face="Times New Roman">Linux</font><span style="font-family: 宋体;" lang="ZH-CN">上会开一对</span><font face="Times New Roman">pipe</font><span style="font-family: 宋体;" lang="ZH-CN">（</span><font face="Times New Roman">pipe</font><span style="font-family: 宋体;" lang="ZH-CN">在</span><font face="Times New Roman">Linux</font><span style="font-family: 宋体;" lang="ZH-CN">下一般都是成对打开）。</span></font>java为了跨平台真是无所不用其极，此中冷暖谁知啊。<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/194849.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-04-22 18:12 <a href="http://www.blogjava.net/killme2008/archive/2008/04/22/194849.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用jprofiler监控jruby脚本</title><link>http://www.blogjava.net/killme2008/archive/2008/03/24/188253.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Mon, 24 Mar 2008 07:26:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/03/24/188253.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/188253.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/03/24/188253.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/188253.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/188253.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; jruby本质上也是启动一个jvm，然后去读Ruby脚本并解释执行（也可以编译），因此jprofiler理所当然也可以去监控jruby脚本的执行。<br />
执行&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">jruby&nbsp;hello.rb</span></div>
等价于执行：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">java&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">Xmx378m&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">Xss1024k&nbsp;&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">Djruby.home</span><span style="color: #000000;">=/</span><span style="color: #000000;">usr</span><span style="color: #000000;">/</span><span style="color: #000000;">local</span><span style="color: #000000;">/</span><span style="color: #000000;">jruby </span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -</span><span style="color: #000000;">Djruby.lib</span><span style="color: #000000;">=/</span><span style="color: #000000;">usr</span><span style="color: #000000;">/</span><span style="color: #000000;">local</span><span style="color: #000000;">/</span><span style="color: #000000;">jruby</span><span style="color: #000000;">/</span><span style="color: #000000;">lib&nbsp;Djruby.script</span><span style="color: #000000;">=</span><span style="color: #000000;">jruby&nbsp;org.jruby.Main&nbsp;hello.rb</span></div>
这一点，你可以通过ps aux |grep jruby 看到。因此配置jprofiler就简单了，在VM arguments加上这些参数（可以包括jruby的参数），比如我的VM arguments配置如下：<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">-</span><span style="color: #000000;">server&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">Xmx378m&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">Xss1024k&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">Djruby.script</span><span style="color: #000000;">=</span><span style="color: #000000;">jruby&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">Djruby.thread.pooling</span><span style="color: #000000;">=</span><span style="color: #000000;">true <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #000000;">-</span><span style="color: #000000;">Djruby.jit.threshold</span><span style="color: #000000;">=</span><span style="color: #000000;">0&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">Djruby.compile.fastest</span><span style="color: #000000;">=</span><span style="color: #000000;">true </span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -</span><span style="color: #000000;">Djruby.home</span><span style="color: #000000;">=</span><span style="color: #000000;">D:\jruby\jruby</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">.1RC2&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">Djruby.lib</span><span style="color: #000000;">=</span><span style="color: #000000;">D:\jruby\jruby</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">.1RC2\lib</span></div>
<br />
Main class or executable JAR填上：org.jruby.Main。然后就是Arguments一栏填上你的脚本位置：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">D:\ruby\lib\hello.rb</span></div>
<br />
最后，别忘了将jruby/lib目录下的bsf.jar和jruby.jar加入Class Path。<br />
<br />
大功告成，你可以用jprofiler去观察GC、线程和锁、Heap等等了。<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/188253.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-03-24 15:26 <a href="http://www.blogjava.net/killme2008/archive/2008/03/24/188253.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Grizzly——不走寻常路的nio框架</title><link>http://www.blogjava.net/killme2008/archive/2008/02/23/181623.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sat, 23 Feb 2008 11:13:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/02/23/181623.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/181623.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/02/23/181623.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/181623.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/181623.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 在《程序员》最新一期有个专题介绍java开源nio框架，其中谈到了mina和grizzly。mina我还算比较熟悉，写过一些代码，也尝试去读过源码。而grizzly是第一次听说，这个项目是sun的一个开源nio框架，是2004年在GlassFish项目中诞生的，一开始是一个http web server，用于取代Tomcat的Coyote Connector和Sun WebServer，2007年7月1.5版本发布并宣布成为开源项目，项目主页在<a href="https://grizzly.dev.java.net">https://grizzly.dev.java.net</a><br />
&nbsp;&nbsp;&nbsp; <strong>grizzly与mina</strong>的性能比较（基于2007年JavaOne会议上的ppt)<br />
<img src="http://www.blogjava.net/images/blogjava_net/killme2008/grizzly1.jpg" alt="" border="0" /><br />
<br />
&nbsp;&nbsp;&nbsp; <strong>GlassFish vs Tomcat</strong><br />
<img src="http://www.blogjava.net/images/blogjava_net/killme2008/grizzly2.jpg.jpg" alt="" border="0" /><br />
<br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; grizzly的设计与一般的nio框架相比是比较不同的，主要不同点在于<strong>读和写都是采用blocking方式，并且使用临时selector</strong>；线程模型可配置，不过据作者介绍在跑一个selector主线程处理ACCEPT，用线程池处理read和write性能表现最好，这点不出意料。<br /><img src ="http://www.blogjava.net/killme2008/aggbug/181623.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-02-23 19:13 <a href="http://www.blogjava.net/killme2008/archive/2008/02/23/181623.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>保持java线程间可见性的5种方式</title><link>http://www.blogjava.net/killme2008/archive/2008/02/23/181560.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sat, 23 Feb 2008 02:44:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/02/23/181560.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/181560.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/02/23/181560.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/181560.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/181560.html</trackback:ping><description><![CDATA[<table>
    <tbody>
        <tr>
            <th>Primitive </th>
            <th>Writes up to and including&#8230; </th>
            <th>...are made visible to&#8230;</th>
        </tr>
        <tr>
            <td> Object </td>
            <td> the end of a synchronized block or method </td>
            <td> a thread entering a synchronized block or method for the same object. </td>
        </tr>
        <tr>
            <td> Volatile field </td>
            <td> a write to a volatile field </td>
            <td> any thread reading that volatile field. </td>
        </tr>
        <tr>
            <td> Thread </td>
            <td> a call to <code>Thread.start</code> </td>
            <td> the newly started thread. </td>
        </tr>
        <tr>
            <td> Thread </td>
            <td> the final write made by a dying thread </td>
            <td> any thread which <em>successfully</em> calls <code>Thread.join</code> on that thread. </td>
        </tr>
        <tr>
            <td> Final field </td>
            <td> the initialization of a final field (but only those writes affecting the field and any object it references) </td>
            <td> any thread, provided that the constructor of the object containing the field doesn&#8217;t write the value of <code>this</code> anywhere eventually visible to other threads</td>
        </tr>
    </tbody>
</table>
<br />
<br />
&nbsp; 这些在《java并发编程实践》一书中已经有详细解释，特别是对于ReentrantLock、volatile域以及final域的讨论。今天在MenTaLguY的blog上看到这张表，摘录下。<img src ="http://www.blogjava.net/killme2008/aggbug/181560.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-02-23 10:44 <a href="http://www.blogjava.net/killme2008/archive/2008/02/23/181560.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java nio之Buffer(一)</title><link>http://www.blogjava.net/killme2008/archive/2008/02/22/181357.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Fri, 22 Feb 2008 06:31:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/02/22/181357.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/181357.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/02/22/181357.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/181357.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/181357.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; Buffer是一个包装了基本数据元素数组的对象，它以及它的子类定义了一系列API用于处理数据缓存。<br />
<img src="http://www.blogjava.net/images/blogjava_net/killme2008/buffer.JPG" alt="" border="0" /><br />
一、属性<br />
Buffer有四个基本属性：<br />
1、capacity&nbsp; 容量，buffer能够容纳的最大元素数目，在Buffer创建时设定并不能更改<br />
2、limit buffer中有效位置数目<br />
3、position 下一个读或者写的位置<br />
4、mark&nbsp; 用于记忆的标志位，配合reset()使用，初始值未设定，调用mark后将当前position设为值<br />
<br />
四者关系：0 &lt;= mark &lt;= position &lt;= limit &lt;= capacity<br />
<br />
二、API<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">package</span><span style="color: #000000;">&nbsp;java.nio;<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">abstract</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Buffer&nbsp;{<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;capacity(&nbsp;)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;position(&nbsp;)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Buffer&nbsp;position&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;newPosition)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;limit(&nbsp;)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Buffer&nbsp;limit&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;newLimit)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Buffer&nbsp;mark(&nbsp;)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Buffer&nbsp;reset(&nbsp;)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Buffer&nbsp;clear(&nbsp;)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Buffer&nbsp;flip(&nbsp;)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Buffer&nbsp;rewind(&nbsp;)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;remaining(&nbsp;)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;hasRemaining(&nbsp;)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">abstract</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;isReadOnly(&nbsp;);<br />
}</span></div>
<br />
支持链式调用，如：buffer.mark().position(5).reset( );<br />
注意isReadOnly()方法决定了buffer是否可写。<br />
<br />
三、操作<br />
&nbsp; 以ByteBuffer为例，<br />
1、访问，通过get(),get(index),其中get()从当前position位置读取，get(index)从index位置读取，不改变当前position,下面要说到的put也一样。<br />
2、填充，通过put(byte),put(index,byte)，按照绝对位置填充也是不改变当前position属性<br />
<br />
3、flipping，试想，我们将填充完毕的buffer传递给socket输出，那么socket读取是依据position属性确定，就会从结尾后一位开始读，这样肯定是不正确的，如果要正确的读取我们先要：<br />
&nbsp; buffer.limit(buffer.position( )).position(0);<br />
将limit设为position,
将position设为0，这个操作就叫flipping，API直接提供了这个操作：<br />
&nbsp; buffer.flip( );<br />
特别注意，<strong>flip()方法会改变limit属性，将limit属性从capacity设置为当前position。</strong>rewind()方法与flip()类似，但是仅将position设为0，而不改变limit，通常用于重新读取已经被flip的buffer。<strong>flip()另一个注意点是，两次调用buffer的flip方法，将使得position和limit属性都为0。</strong><br />
<br />
4、迭代取元素：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;buffer.hasRemaining(&nbsp;),&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)&nbsp;{<br />
myByteArray&nbsp;[i]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;buffer.get(&nbsp;);<br />
}<br />
<br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;count&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;buffer.remaining(&nbsp;);<br />
</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;count,&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)&nbsp;{<br />
myByteArray&nbsp;[i]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;buffer.get(&nbsp;);<br />
}</span></div>
ByteBuffer不是线程安全的，前一种方式适合并发访问，后一种方式效率更高。这两种方式都是一个一个取，效率都比批量取低。<br />
<br />
5.clear()方法，将buffer重设为空状态，也就是设置limit=capacity,position=0，以便重复利用。<br />
<br />
6.compact()方法，用于压缩buffer，这个方法在多次重复调用时是比较低效。<br />
<br />
7.mark(),初始是未定义的，这适合如果调用reset将抛出InvalidMarkException。调用makr()后，将当前position设为mark以便reset时返回。注意，rewind( ), clear( ), and flip( )方法都将丢弃已经创建的mark。调用limit(index),positioon(index)，如果index的值小于当前mark，mark也将被丢弃。<br />
<br />
8.比较，可以通过equals()和compateTo()方法来比较两个buffer，前一个返回boolean，后一个返回0，-1，1。两个buffer equal的条件是：<br />
1）类型相同<br />
2）剩余元素的数目相等<br />
3）剩余元素也一一相等<br />
<br />
9、批量移动数据，为了更有效地进行数据传送，批量的数据存取肯定是不能少的，Buffer及其子类都有提供类似的方法，比如CharBuffer:<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;CharBuffer&nbsp;get&nbsp;(</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;[]&nbsp;dst)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;CharBuffer&nbsp;get&nbsp;(</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;[]&nbsp;dst,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;offset,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;length)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;CharBuffer&nbsp;put&nbsp;(</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[]&nbsp;src)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;CharBuffer&nbsp;put&nbsp;(</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;[]&nbsp;src,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;offset,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;length)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;CharBuffer&nbsp;put&nbsp;(CharBuffer&nbsp;src)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;CharBuffer&nbsp;put&nbsp;(String&nbsp;src)<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;CharBuffer&nbsp;put&nbsp;(String&nbsp;src,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;start,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;end)</span></div>
<br />
四、创建Buffer<br />
&nbsp;&nbsp;&nbsp; Buffer以及其子类都无法直接new，而必须把通过他们提供的工厂方法来创建。通常有两种方式：<br />
1、allocate，例如<br />
CharBuffer charBuffer = CharBuffer.allocate (100);<br />
将在堆上分配一个可以存储100个字符的数组作为backing store。<br />
<br />
2、wrap，包装一个已有的数组：<br />
char [] myArray = new char [100];<br />
CharBuffer charbuffer = CharBuffer.wrap (myArray);<br />
注意,这样的方式创建的Buffer，将不会在堆上创建新的数组，而是直接利用myArray做backing store，这意味着任何对myArray或者buffer的修改都将影响到buffer或者myArray。可以通过public final boolean hasArray( )方法来判断是否拥有一个数组，通过array()方法取得这个数组。<br />
<br />
五、复制Buffer<br />
&nbsp;&nbsp; 其实这个复制也是&#8220;浅拷贝&#8221;，通过duplicate()方法将返回一个新创建的buffer，这个新buffer与原来的Buffer<strong>共享数据，一样的capacity，但是有自己的position、limit和mark属性。</strong>通过asReadOnlyBuffer()方法复制的buffer与duplicate()类似，但是是<strong>只读</strong>的，不能调用put。比较特别的是slice()方法，故名思议，类似切割一个Buffer出来，与duplicate类似，但是它将从原来Buffer的当前position开始，并且capacity等于原来Buffer的剩余元素数目，也就是(limit-position)。<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/181357.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-02-22 14:31 <a href="http://www.blogjava.net/killme2008/archive/2008/02/22/181357.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JRuby 1.1 RC2  Released</title><link>http://www.blogjava.net/killme2008/archive/2008/02/18/180388.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Mon, 18 Feb 2008 01:43:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/02/18/180388.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/180388.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/02/18/180388.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/180388.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/180388.html</trackback:ping><description><![CDATA[<p>修正了很多bug，我关注的
JRUBY-1686也得到了修正，距离1.1的发布不远了。</p>
<p>The JRuby community is pleased to announce the release of JRuby 1.1 RC 2</p>
<p>Homepage: <a href="http://www.jruby.org/" rel="nofollow">http://www.jruby.org/</a><br />
Download: <a href="http://dist.codehaus.org/jruby/" rel="nofollow">http://dist.codehaus.org/jruby/</a></p>
<p>JRuby 1.1RC2 is the second release candidate of JRuby 1.1.&nbsp; JRuby 1.1<br />
represents a concerted focus on speed and refinement.&nbsp; <a title="" href="http://www.ruby-lang.org" >ruby</a> code can<br />
completely compile in an Ahead Of Time (AOT) or Just In Time (JIT) mode;<br />
yielding a faster <a title="" href="http://www.ruby-lang.org" >ruby</a>!&nbsp; It also uses less memory than our previous releases.</p>
<p>We need people to download JRuby 1.1RC2 and give us feedback.&nbsp; Test your<br />
applications and help us make JRuby 1.1 a great release.</p>
<p>Highlights:<br />
- 260 issues resolved since JRuby 1.1RC1<br />
- Large IO refactoring<br />
<strong>
- Memory improvements for JIT'd methods:<br />
&nbsp; - Control total number of methods JIT'd<br />
&nbsp; - Support a JIT cache between runtimes to return permgen<br />
&nbsp; - Reduce codesize of generated methods (50-70% reduction)</strong></p><img src ="http://www.blogjava.net/killme2008/aggbug/180388.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-02-18 09:43 <a href="http://www.blogjava.net/killme2008/archive/2008/02/18/180388.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JRuby中使用接口和抽象类</title><link>http://www.blogjava.net/killme2008/archive/2008/02/15/180078.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Fri, 15 Feb 2008 06:34:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/02/15/180078.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/180078.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/02/15/180078.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/180078.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/180078.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 要在JRuby中实现java接口，接口<strong>include</strong>进来，实现接口方法即可，例如实现java.lang.Runnable接口做线程处理：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">require 'java'<br />
include_class 'java.lang.Runnable'<br />
class</span><span style="color: #000000;">&nbsp;TestRunnable<br />
&nbsp;&nbsp;&nbsp;&nbsp;include&nbsp;Runnable<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;initialize(name)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@name</span><span style="color: #000000;">=</span><span style="color: #000000;">name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;run<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;</span><span style="color: #800000;">"</span><span style="color: #800000;">hello,</span><span style="color: #800000;">"</span><span style="color: #000000;">+</span><span style="color: #000000;">@name<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
end<br />
</span></div>
<br />
&nbsp;&nbsp;&nbsp; 要在JRuby中继承抽象类，实现其中的抽象方法，方法稍微麻烦点，需要cglib，到<a href="http://sourceforge.net/project/showfiles.php?group_id=56933">这里</a>下载cglib-nodep-2.1_3.jar，写个通用库abstract_class.rb方便处理:<br />
<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">load&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">cglib-nodep-2.1_3.jar</span><span style="color: #800000;">'</span><span style="color: #000000;"><br />
<br />
</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Object<br />
&nbsp;&nbsp;include&nbsp;Java<br />
&nbsp;&nbsp;include_class&nbsp;</span><span style="color: #800000;">"</span><span style="color: #800000;">net.sf.cglib.proxy.Enhancer</span><span style="color: #800000;">"</span><span style="color: #000000;"><br />
&nbsp;&nbsp;include_class&nbsp;</span><span style="color: #800000;">"</span><span style="color: #800000;">net.sf.cglib.proxy.NoOp</span><span style="color: #800000;">"</span><span style="color: #000000;"><br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;&lt;</span><span style="color: #000000;">self<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;method_missing(mname,&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">args,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">block)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unless&nbsp;mname&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;:abstract_impl&nbsp;</span><span style="color: #0000ff;">and</span><span style="color: #000000;">&nbsp;respond_to?(:java_class)&nbsp;</span><span style="color: #0000ff;">and</span><span style="color: #000000;">&nbsp;JavaLang::reflect::Modifier.isAbstract(JavaLang::Class.for_name(java_class.name).modifiers)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;generate_abstract_impl(args,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">block)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;generate_abstract_impl(args,&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">block)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factory&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;Enhancer.new<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factory.setSuperclass(java_class)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factory.setInterfaces(java_class.interfaces.to_java(</span><span style="color: #800000;">"</span><span style="color: #800000;">java.lang.Class</span><span style="color: #800000;">"</span><span style="color: #000000;">))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factory.setCallback(NoOp::INSTANCE)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;object_args&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;args.map&nbsp;{&nbsp;</span><span style="color: #000000;">|</span><span style="color: #000000;">arg</span><span style="color: #000000;">|</span><span style="color: #000000;">&nbsp;Java.ruby_to_java(arg)&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class_arguments&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;object_args.map&nbsp;{</span><span style="color: #000000;">|</span><span style="color: #000000;">arg</span><span style="color: #000000;">|</span><span style="color: #000000;">&nbsp;arg.java_class}.to_java(</span><span style="color: #800000;">"</span><span style="color: #800000;">java.lang.Class</span><span style="color: #800000;">"</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;generated_class&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;factory.create(class_arguments,&nbsp;object_args.to_java(</span><span style="color: #800000;">"</span><span style="color: #800000;">java.lang.Object</span><span style="color: #800000;">"</span><span style="color: #000000;">))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ruby_class&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;Class.new(generated_class.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ruby_class.class_eval(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">block)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;ruby_class.new(</span><span style="color: #000000;">*</span><span style="color: #000000;">args)<br />
&nbsp;&nbsp;&nbsp;&nbsp;end<br />
&nbsp;&nbsp;end<br />
&nbsp;&nbsp;<br />
end</span></div>
<br />
&nbsp;&nbsp;&nbsp; 使用的话，require一下abstract_class，例如我们要继承java.util.TimerTask，实现其中的run方法：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">$:.unshift&nbsp;File.join(File.dirname(</span><span style="color: #800080;">__FILE__</span><span style="color: #000000;">),</span><span style="color: #800000;">'</span><span style="color: #800000;">.</span><span style="color: #800000;">'</span><span style="color: #000000;">)<br />
require&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">java</span><span style="color: #800000;">'</span><span style="color: #000000;"><br />
require&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">abstract_class</span><span style="color: #800000;">'</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.TimerTask<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.Timer<br />
timer_task&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;TimerTask.abstract_impl&nbsp;do<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;run<br />
&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;</span><span style="color: #800000;">"</span><span style="color: #800000;">timer&nbsp;task</span><span style="color: #800000;">"</span><span style="color: #000000;"><br />
&nbsp;&nbsp;end<br />
end<br />
<br />
Timer.new.schedule(timer_task,&nbsp;</span><span style="color: #000000;">1000</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">1000</span><span style="color: #000000;">)<br />
</span></div>
<br />
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/180078.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-02-15 14:34 <a href="http://www.blogjava.net/killme2008/archive/2008/02/15/180078.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JRuby的性能优化</title><link>http://www.blogjava.net/killme2008/archive/2008/01/31/178725.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Thu, 31 Jan 2008 10:58:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/01/31/178725.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/178725.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/01/31/178725.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/178725.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/178725.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 越来越觉的JRuby是个很有前途的项目，结合Ruby的性感语法和java极其丰富的类库，况且有团队持续不断地修正bug、改进性能，这样的玩意完全有成为&#8220;少男杀手&#8221;的潜质。JRuby wiki上列出了性能优化的四条建议：<br />
1、调优编译器，JRuby早就弃暗投明跟随XRuby走上了编译这条牛B的道路，将Ruby Script编译成字节码，因此这个环节是断断不能忽略的。<br />
两种编译方式：<br />
AOT模式：直接生成class文件，脱了Ruby这层皮，咱就是人见人&#8220;爱&#8221;的java了。<br />
JIT模式：充分利用成熟的jit技术，咱不全脱，朦胧美才是真的美。默认从0.9.9版本开始就是开启的，关闭的话（要我说还不如全脱）<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">jruby&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">J</span><span style="color: #000000;">-</span><span style="color: #000000;">Djruby.jit.enabled</span><span style="color: #000000;">=</span><span style="color: #0000ff;">false</span></div>
<br />
<br />
2、关闭ObjectSpace<br />
ObjectSpace是Ruby用来操作所有运行时对象的模块，这个功能相当牛x。这个的实现在c ruby里是比较容易的，但是对于JRuby代价就比较昂贵了，其实就大部分情况下你基本用不到这个东东，那么最好就是关闭它，JRuby提供了<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">jruby&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">J</span><span style="color: #000000;">-</span><span style="color: #000000;">Djruby.objectspace.enabled</span><span style="color: #000000;">=</span><span style="color: #0000ff;">false</span></div>
选项来关闭它。<br />
<br />
3、开启线程池<br />
我们知道，在c ruby中的线程是绿色的轻量级线程，因此运行时就动不动开个百来十个&#8220;线程&#8221;跑一跑充下款爷；然而在JRuby中，线程的实现那可是实打实的本地线程（也就是Ruby线程与java线程一比一），你这么动不动上百个线程那不慢才怪了。因此JRuby提供了线程池选项，运行时尽可能地满足你的要求开线程，但是当短命的Ruby线程重复创建的时候，这些线程将被复用，这在大多数情况下能提高性能表现，特别是在每次调用都启动一个线程的情况下。不过具体效果还是要测试的实际数据说话。<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">jruby&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">J</span><span style="color: #000000;">-</span><span style="color: #000000;">Djruby.thread.pooling</span><span style="color: #000000;">=</span><span style="color: #0000ff;">true</span><span style="color: #000000;"> <br />
</span></div>
<br />
<br />
4、使用Java "server"模式虚拟机，地球淫都知道<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">jruby&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">J</span><span style="color: #000000;">-</span><span style="color: #000000;">server&nbsp;myscript.rb</span></div>
<br />
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/178725.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-01-31 18:58 <a href="http://www.blogjava.net/killme2008/archive/2008/01/31/178725.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>介绍下smartclient</title><link>http://www.blogjava.net/killme2008/archive/2008/01/08/173663.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 08 Jan 2008 07:48:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/01/08/173663.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/173663.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/01/08/173663.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/173663.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/173663.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; <a href="http://www.smartclient.com/">smartclient</a>是一个企业级的ajax框架，包括非常出色的UI库、工具库和客户端服务端数据绑定等功能。smartclient本来是一个商业产品，
2007年11月7号才以LGPL协议开源。除了一些所见即所得的构建工具和企业级的可选组件外，其他都开源了。这个记的javaeye和infoq都有报道。<br />
&nbsp;&nbsp;&nbsp; 在接触smartclient以前，我还没有使用过类似的ajax ui库，比如现在很火的ext。smartclient给我的第一印象是非常漂亮的ui效果，有兴趣可以去它的官方<a href="http://www.smartclient.com/featureExplorer.jsp">demo</a>看看。smartclient的demo和文档做的非常出色，入手开发也非常容易。<br />
第一步：<a href="http://www.smartclient.com/product/download.jsp">下载LGPL版本</a>，并解压缩<br />
第二步：运行解压后目录下的\SmartClient_60_LGPL\smartclientSDK\start_embedded_server.bat，SDK自带了一个内嵌的tomcat<br />
第三步：访问 http://localhost:8080<br />
<br />
你将见到：<br />
<img src="http://www.blogjava.net/images/blogjava_net/killme2008/smartclient.jpg" alt="" border="0" /><br />
<br />
这些demo本身就是用smartclient制作的。开发过程中你需要做就是查看examples和文档中的reference（api文档），基本没有解决不了的问题。<br />
<br />
人见人爱的Hello World例子：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">isc.Label.create({<br />
&nbsp;&nbsp;&nbsp;&nbsp;height:&nbsp;</span><span style="color: #000000;">50</span><span style="color: #000000;">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;styleName:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">helloWorldText</span><span style="color: #000000;">"</span><span style="color: #000000;">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;padding:&nbsp;</span><span style="color: #000000;">4</span><span style="color: #000000;">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;backgroundColor:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">#ffffd0</span><span style="color: #000000;">"</span><span style="color: #000000;">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;align:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">center</span><span style="color: #000000;">"</span><span style="color: #000000;">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;valign:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">center</span><span style="color: #000000;">"</span><span style="color: #000000;">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;wrap:&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;showEdges:&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;showShadow:&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;contents:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">Hello&nbsp;world!</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />
})<br />
</span></div>
<br />
效果：<br />
<img src="http://www.blogjava.net/images/blogjava_net/killme2008/smartclient2.jpg" alt="" border="0" /><br />
<br />
&nbsp;&nbsp;&nbsp; smartclient除了完整的UI组件，还包括丰富的动态效果库以及可选的皮肤等高级主题，不再展开了，毕竟贴图是在是挺麻烦的事情：）还不如有兴趣的自己翻demo。说了这么多优点，那么缺点是啥？你可能猜到了，性能！所有js UI库无法避免的问题，不过我没有其他UI库的使用经验，倒是不能给出个比较数据。我们写的东西的性能也只是堪堪能够接受。<br />
&nbsp;&nbsp; smartclient跟dwr可以说是天生一对，smartclient UI组件的数据源可以是xml也可以是json，如果采用json做交换格式，可以与dwr无缝结合，真正实现One Page,One Application（我们就是这样做的^_^)。<br />
<br />
<br />
<br />
<br />
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/173663.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-01-08 15:48 <a href="http://www.blogjava.net/killme2008/archive/2008/01/08/173663.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>介绍一个轻量级java的swf处理库</title><link>http://www.blogjava.net/killme2008/archive/2008/01/04/172690.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Fri, 04 Jan 2008 03:46:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/01/04/172690.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/172690.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/01/04/172690.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/172690.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/172690.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 提取swf文件元信息、压缩swf、解压swf都可以处理，来自于http://www.brooksandrus.com/blog/category/java/，或者直接<a href="http://www.blogjava.net/Files/killme2008/swf.rar">这里</a>下载。<br />
<br />
一个小例子：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SWFHeader&nbsp;header&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;SWFHeader(</span><span style="color: #000000;">"G:\\mplayer\\test.swf"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">signature:&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;header.getSignature());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">version:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;header.getVersion());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">compression:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;header.getCompressionType());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">size:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;header.getSize());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">nbits:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;header.getNbits());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">xmax:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;header.getXmax());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">ymax:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;header.getYmax());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">width:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;header.getWidth());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">height:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;header.getHeight());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">frameRate:&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;header.getFrameRate());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">frameCount:&nbsp;&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;header.getFrameCount());</span></div>
&nbsp;<br />
压缩、解压缩，需要注意生成的文件将覆盖原文件：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000;">//</span><span style="color: #008000;">压缩</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">SWFCompressor&nbsp;compressor</span><span style="color: #000000;">=</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;SWFCompressor(</span><span style="color: #000000;">"</span><span style="color: #000000;">G:\\mplayer\\test.swf</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">解压缩</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">SWFDecompressor&nbsp;decompressor</span><span style="color: #000000;">=</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;SWFDecompressor(</span><span style="color: #000000;">"</span><span style="color: #000000;">G:\\mplayer\\test.swf</span><span style="color: #000000;">"</span><span style="color: #000000;">);</span></div>
<br />
<br />
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/172690.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-01-04 11:46 <a href="http://www.blogjava.net/killme2008/archive/2008/01/04/172690.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PPT转图片(更新）</title><link>http://www.blogjava.net/killme2008/archive/2008/01/04/172680.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Fri, 04 Jan 2008 03:26:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2008/01/04/172680.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/172680.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2008/01/04/172680.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/172680.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/172680.html</trackback:ping><description><![CDATA[update:2008-05-05，POI已经可以处理这个需求：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">package</span><span style="color: #000000;">&nbsp;net.rubyeye.test;<br />
<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.io.FileOutputStream;<br />
<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;org.apache.poi.hslf.HSLFSlideShow;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;org.apache.poi.hslf.model.Picture;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;org.apache.poi.hslf.usermodel.PictureData;<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;org.apache.poi.hslf.usermodel.SlideShow;<br />
<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;PPTToImageConverter&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;main(String[]&nbsp;args)&nbsp;</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;Exception&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SlideShow&nbsp;ppt&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;SlideShow(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;HSLFSlideShow(</span><span style="color: #000000;">"</span><span style="color: #000000;">D:/test.ppt</span><span style="color: #000000;">"</span><span style="color: #000000;">));<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;extract&nbsp;all&nbsp;pictures&nbsp;contained&nbsp;in&nbsp;the&nbsp;presentation</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PictureData[]&nbsp;pdata&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;ppt.getPictureData();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;pdata.length;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PictureData&nbsp;pict&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pdata[i];<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;picture&nbsp;data</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">byte</span><span style="color: #000000;">[]&nbsp;data&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pict.getData();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;type&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pict.getType();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;ext;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">switch</span><span style="color: #000000;">&nbsp;(type)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;Picture.JPEG:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ext&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">.jpg</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;Picture.PNG:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ext&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">.png</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;Picture.WMF:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ext&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">.wmf</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;Picture.EMF:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ext&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">.emf</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">case</span><span style="color: #000000;">&nbsp;Picture.PICT:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ext&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">.pict</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">default</span><span style="color: #000000;">:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">continue</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileOutputStream&nbsp;out&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;FileOutputStream(</span><span style="color: #000000;">"</span><span style="color: #000000;">D:/test/pict_</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;ext);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.write(data);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.close();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span></div>
<br />
&nbsp;&nbsp;  原文：<br />
&nbsp;&nbsp; 小结下最近做的东西吧。因为是做一个素材管理的东西，因此需要处理各种各样的素材，音频、视频、图片、pdf、ppt等等。遇到一个需求就是将PPT转成图片组，google一下，在java里是可以jcom之类的开源库实现，本质上都是通过jni调用office的COM接口来实现。我们就需要这么一个小功能，拖这么大个开源库进来实在没有必要。最后决定自己写个动态链接库，通过jni来调用。<br />
&nbsp;&nbsp;&nbsp; 先写工具类，<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;PPTUtils&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;PPTUtils()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">native</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;convertPPT2IMG(String&nbsp;pptFileName,&nbsp;String&nbsp;tmpDir);<br />
<br />
&nbsp;</span><span style="color: #0000ff;">&nbsp;&nbsp; public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;loadLibrary()&nbsp;{</span><span style="color: #008000;">//</span><span style="color: #008000;">加载动态库</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;dllFileName&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">pptDll</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;OsName&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;System.getProperty(</span><span style="color: #000000;">"</span><span style="color: #000000;">os.name</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(OsName.contains(</span><span style="color: #000000;">"</span><span style="color: #000000;">Windows</span><span style="color: #000000;">"</span><span style="color: #000000;">))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dllFileName&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">.dll</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dllFileName&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">.so</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">加载动态链接库</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.load(</span><span style="color: #000000;">dllFileName);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(Exception&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;&nbsp;&nbsp;LOG.error("can&nbsp;not&nbsp;load&nbsp;"&nbsp;+&nbsp;dllFileName&nbsp;+&nbsp;",&nbsp;"&nbsp;+&nbsp;e.getMessage());</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
}</span></div>
<br />
&nbsp;&nbsp;&nbsp; 编译一下，执行javah PPTUtils生成头文件PPTUtils.h。接下来用vc写个动态链接库，记的将MSPPT.OLB（在office安装目录下）加入工程，新建一个ppt2img.cpp：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">#include&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">stdafx.h</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />
#include&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">PPTUtils.h</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />
#include&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">msppt.h</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />
<br />
JNIEXPORT&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;JNICALL&nbsp;Java_com_starnet_dmb_util_PPTUtils_convertPPT2IMG(JNIEnv&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">env, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jclass&nbsp;clazz,&nbsp;jstring&nbsp;pptFileName,&nbsp;jstring&nbsp;tmpDir){<br />
&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">初始化com</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(CoInitialize(&nbsp;NULL&nbsp;)&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;E_INVALIDARG)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox(_T(</span><span style="color: #000000;">"</span><span style="color: #000000;">初始化Com失败!</span><span style="color: #000000;">"</span><span style="color: #000000;">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;_Application&nbsp;&nbsp;&nbsp;app;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Presentations&nbsp;&nbsp;&nbsp;prsts;<br />
&nbsp;&nbsp;&nbsp;&nbsp;_Presentation&nbsp;&nbsp;&nbsp;prst;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">jstring转成char&nbsp;*</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">ppt;<br />
&nbsp;&nbsp;&nbsp;ppt&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;env</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">GetStringUTFChars(pptFileName,</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">tmp;<br />
&nbsp;&nbsp;&nbsp;tmp</span><span style="color: #000000;">=</span><span style="color: #000000;">env</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">GetStringUTFChars(tmpDir,</span><span style="color: #000000;">0</span><span style="color: #000000;">);<br />
<br />
&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(</span><span style="color: #000000;">!</span><span style="color: #000000;">app.CreateDispatch(_T(</span><span style="color: #000000;">"</span><span style="color: #000000;">PowerPoint.Application</span><span style="color: #000000;">"</span><span style="color: #000000;">))){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AfxMessageBox(_T(</span><span style="color: #000000;">"</span><span style="color: #000000;">初始化PowerPoint失败!</span><span style="color: #000000;">"</span><span style="color: #000000;">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;prsts&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;app.GetPresentations();<br />
&nbsp;&nbsp;&nbsp;prst&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;prsts.Open(_T(ppt),</span><span style="color: #0000ff;">false</span><span style="color: #000000;">,</span><span style="color: #0000ff;">false</span><span style="color: #000000;">,</span><span style="color: #0000ff;">false</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;prst.SaveAs(_T(tmp),</span><span style="color: #000000;">17</span><span style="color: #000000;">,</span><span style="color: #0000ff;">false</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;app.ReleaseDispatch();<br />
&nbsp;&nbsp;&nbsp;app.Quit();<br />
&nbsp;&nbsp;&nbsp;env</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">ReleaseStringUTFChars(pptFileName,ppt);<br />
&nbsp;&nbsp;&nbsp;env</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">ReleaseStringUTFChars(tmpDir,tmp);<br />
&nbsp;&nbsp;&nbsp;CoUninitialize();<br />
}</span></div>
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/172680.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2008-01-04 11:26 <a href="http://www.blogjava.net/killme2008/archive/2008/01/04/172680.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>视频站点的搭建</title><link>http://www.blogjava.net/killme2008/archive/2007/12/19/168788.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Wed, 19 Dec 2007 08:46:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/12/19/168788.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/168788.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/12/19/168788.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/168788.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/168788.html</trackback:ping><description><![CDATA[&nbsp; &nbsp; 挺久没动笔写blog了，换了新工作比较忙是一个原因。最近的工作是做一个素材管理的系统，其中有个要求做视频预览，将用户上传的视频转换并在网页上预览。在网页上看视频，现在大多数视频网站都是采用flv流媒体文件，用flash做的播放器播放，我们也采用了这种方式。流程大概主要：用户上传文件-&gt;后台转换文件成flv格式-&gt;flv播放器调用flv文件。<br />
&nbsp;&nbsp;&nbsp; 转换视频、音频文件到flv格式可以使用mencoder或者ffmpeg，我们采用了mencoder，在linux上的安装参考<a href="http://hi.baidu.com/flash%5Fzb/blog/item/bbf7668de6f85912b21bbae0.html">这里</a>,安装结束后记的设置环境变量：export LD_LIBRARY_PATH=/usr/local/lib:LD_LIBRARY_PATH<br />
&nbsp;&nbsp;&nbsp; java调用的话就是通过Process：<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&nbsp;Process&nbsp;process&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;runtime.exec(cmd);</span></div>
<br />
mencoder转换视频音频成flv命令：<br />
mencoder 源文件 -o 目标文件.flv -of lavf&nbsp;&nbsp;&nbsp; -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames -oac mp3lame -lameopts abr:br=56 -ovc lavc -lavcopts vcodec=flv:vbitrate=400:mbd=2:mv0:trell:v4mv:cbp:last_pred=3:dia=4:cmp=6:vb_strategy=1 -vf scale=200:-3 -ofps 12 -srate 22050<br />
<br />
取视频元信息命令（视频比特率、长宽等信息）：<br />
mplayer -identify 文件名 -ao null -vo null -frames 0 <br />
<br />
切割视频命令：<br />
mencoder -ss 开始时间 -oac copy -ovc copy -endpos 终止时间 文件名 -o 目标文件名<br />
<br />
&nbsp;&nbsp;&nbsp; 操作flv文件（给视频打上信息、切割之类）可以采用<a href="http://rubyforge.org/projects/flvtool2/">flvtool2</a>。<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 需要注意的是通过java调用的话，一定要处理标准输出和标准错误输出，不然进程会挂在那结束不了，可以开个线程取处理。在网页播放的话，可以考虑用<a href="http://hi.baidu.com/lzxinta/blog/item/4c02d55103216d2643a75b7b.html">这个播放器</a>，具体参数看它的说明。最后一个问题，IE6的flash控件需要激活，这个问题的解决可以采用<a href="http://blog.deconcept.com/swfobject/">swfobject.js</a>。<br />
&nbsp;&nbsp;&nbsp; 有兴趣的老大们可以考虑自己搭个&#8220;土豆网&#8221;，说不定哪天拿了风投.....浮云<br /><img src ="http://www.blogjava.net/killme2008/aggbug/168788.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-12-19 16:46 <a href="http://www.blogjava.net/killme2008/archive/2007/12/19/168788.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>抽取网页数据的不同思路</title><link>http://www.blogjava.net/killme2008/archive/2007/11/22/162338.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Thu, 22 Nov 2007 04:35:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/11/22/162338.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/162338.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/11/22/162338.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/162338.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/162338.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 客户要求从Internet上的网页上抽取一定的数据，用来显示或者其他用户，这个需求很常见。这两天我们也遇到了这个需求，本来我一开始想是试用正则表达式去匹配需要的文本数据，后来经验丰富的经理给出了一个更好的思路，就是使用<a>jtidy</a>将不符合xhtml的HTML文件转化成标准的xhtml文件——本质上就是XML文件，然后利用xsl抽取并转换成我们所需要的数据的一定格式的xml文件。这样做其实就是将XSL模板当正则表达式来用，不过更清晰，当网页改变时也不需要重新编译代码，仅仅修改XSL模板就够了。过程如下：<br />
&nbsp;&nbsp;&nbsp;&nbsp; html-&gt;xhtml--xsl--&gt;数据xml<br />
<br />
&nbsp;&nbsp;&nbsp; 做的过程中，初次使用了xsl,xpath等技术，网上找了不少好资料，共享下：<br />
jtidy:&nbsp; <br />
<br />
思路来源<br />
http://www.ibm.com/developerworks/cn/xml/x-wbdm/<br />
<br />
项目地址<br />
http://jtidy.sourceforge.net/<br />
<br />
参考，解决中文问题使用<br />
http://www.blogjava.net/jhengfei/archive/2006/03/25/37312.html<br />
<br />
xsl,非常系统教程和实践:<br />
<br />
http://www.cnblogs.com/goody9807/category/36016.html<br />
<br />
xpath:<br />
<br />
http://www.yesky.com/201/171201.shtml<br />
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/162338.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-11-22 12:35 <a href="http://www.blogjava.net/killme2008/archive/2007/11/22/162338.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>再谈java的内存泄露</title><link>http://www.blogjava.net/killme2008/archive/2007/11/11/159786.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sun, 11 Nov 2007 12:18:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/11/11/159786.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/159786.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/11/11/159786.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/159786.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/159786.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 这两天看了一本老书《bitter java》，第一次系统地了解了所谓&#8220;反模式&#8221;。就书的内容来说已经过于陈旧，书中提到的magic servlet、复合jsp等等反模式已经是早就熟知的编程禁忌，而如web页面不能有太多元素这样的反模式也因为ajax的出现（异步加载）变的不是那么&#8220;反模式&#8221;了，其中又讲述了很多ejb的反模式，这些在轻量级框架流行的今天也早已经过时。不过书中有一个章节倒是挺有价值，讲述的是java的内存泄露问题，我认为是我目前读的关于这方面问题比较有价值的介绍。<br />
&nbsp;&nbsp;&nbsp; 网上关于java内存泄露的资料都过于玄乎，其实java导致内存泄露的原因很明确：长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露，尽管短生命周期对象已经不再需要，但是因为长生命周期对象持有它的引用而导致不能被回收，这就是java中内存泄露的发生场景。作者在书中提到了3个场景：<br />
1。流失监听器问题，在awt、swing编程中，给组件添加了事件监听器，这些组件的生命周期如果很长的话，监听器对象将不能被正确回收。关于GUI编程我不是很熟悉，这一点存有疑问，因为显然你触发一个按钮的事件，当然是一直期待同样的行为发生，如果删除了监听器或者使用弱引用让JVM回收不符合业务逻辑和用户体验。<br />
<br />
2。集合类，集合类仅仅有添加元素的方法，而没有相应的删除机制，导致内存被占用。这一点其实也不明确，这个集合类如果仅仅是局部变量，根本不会造成内存泄露，在方法栈退出后就没有引用了会被jvm正常回收。而如果这个集合类是全局性的变量（比如类中的静态属性，全局性的map等），那么没有相应的删除机制，很可能导致集合所占用的内存只增不减，因此提供这样的删除机制或者定期清除策略非常必要。<br />
<br />
3。单例模式。不正确使用单例模式是引起内存泄露的一个常见问题，单例对象在被初始化后将在JVM的整个生命周期中存在（以静态变量的方式），如果单例对象持有外部对象的引用，那么这个外部对象将不能被jvm正常回收，导致内存泄露，考虑下面的例子：<br />
class A{<br />
&nbsp;&nbsp;&nbsp; public A(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B.getInstance().setA(this);<br />
&nbsp;&nbsp; }<br />
&nbsp;&nbsp; ....<br />
}<br />
//B类采用单例模式<br />
class B{<br />
&nbsp;&nbsp;&nbsp;&nbsp; private A a;<br />
&nbsp;&nbsp;&nbsp;&nbsp; private static B instance=new B();<br />
&nbsp;&nbsp;&nbsp;&nbsp; public B(){}<br />
&nbsp;&nbsp;&nbsp;&nbsp; public static B getInstance(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return instance;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public void setA(A a){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.a=a;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; //getter...<br />
}<br />
<br />
显然B采用singleton模式，他持有一个A对象的引用，而这个A类的对象将不能被回收。想象下如果A是个比较大的对象或者集合类型会发生什么情况。<br />
<br />
&nbsp;&nbsp;&nbsp; 上面所讲的这些也启发我们如何去查找内存泄露问题，第一选择当然是利用工具，比如jprofiler，第二就是在代码复审的时候关注长生命周期对象：全局性的集合、单例模式的使用、类的static变量等等。<br /><img src ="http://www.blogjava.net/killme2008/aggbug/159786.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-11-11 20:18 <a href="http://www.blogjava.net/killme2008/archive/2007/11/11/159786.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>写一个简单的工作流（四）资源的处理</title><link>http://www.blogjava.net/killme2008/archive/2007/10/13/152604.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Sat, 13 Oct 2007 09:15:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/10/13/152604.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/152604.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/10/13/152604.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/152604.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/152604.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 昨天晚上搞到深夜，终于将资源模块搞定。到今天已经完成的功能包括：<br />
1.四种基本路由：顺序、选择、并行、循环<br />
2.流程定义文件和系统配置文件的读取和解析<br />
3.使用内存作为流程数据和案例数据存储的MemoryWorkFlowDAO的开发<br />
4.资源模块的开发<br />
5.并发情况下的正确性测试等<br />
<br />
&nbsp;&nbsp;&nbsp; 计划中的功能：<br />
1.一个GUI的流程定义工具，这个不急，也还没想好用什么做，web还是桌面？<br />
2.各个数据库版本的WorkFlowDAO的开发，将流程数据和案例数据保存在数据库中。<br />
3.更多的测试和example试验。<br />
<br />
&nbsp;&nbsp;&nbsp; 回到资源这个概念，工作流中工作项（work item）的由资源来驱动的，这个资源(resource)可能是用户、角色、定时时间或者某个事件消息。在标准petri网中，工作项对应于transition(变迁），变迁都是自动的，不需要所谓资源来驱动，显然，这与工作流系统不同。具体到insect workflow(我取的名字，小巧之意），每个transition都有一个resource，用于驱动自身的firing，所有的resource都实现Resource接口：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">interface</span><span style="color: #000000;">&nbsp;Resource&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;Serializable&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;start(Transition&nbsp;transition,&nbsp;Token&nbsp;token,&nbsp;Object&nbsp;args);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;ResourceType&nbsp;getType();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;getId();<br />
<br />
}</span></div>
&nbsp;&nbsp;&nbsp; 每个资源都有一个类型，以及这个类型中独一无二的id，start方法用于驱动transtion的firing。一般情况下，你不需要实现这个接口，只要继承这个接口的抽象实现类AbstractResource，AbstractResource的start方法默认实现是首先调用模板方法doAction（稍后解释）,然后检查触发条件，如果通过就直接调用transition的fire方法：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">abstract</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;AbstractResource&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;Resource&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;start(Transition&nbsp;transition,&nbsp;Token&nbsp;token,&nbsp;Object&nbsp;args) </span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doAction(transition,&nbsp;token,&nbsp;args);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(transition.getCondition()&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">!</span><span style="color: #000000;">transition.getCondition().check(token))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">throw</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ConditionException(transition.getName()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;transition没有满足触发条件</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;transition.fire(token,&nbsp;args);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">abstract</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;doAction(Transition&nbsp;transition,&nbsp;Token&nbsp;token,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object<img src="http://www.blogjava.net/Images/dot.gif" alt="" />&nbsp;args) </span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
}</span></div>
<br />
&nbsp;&nbsp;&nbsp; Transtion类的fire方法有三个操作组成：从输入库所移走token，往输出库所放入token，回调handler：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp; public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;fire(Token&nbsp;token,&nbsp;Object<img src="http://www.blogjava.net/Images/dot.gif" alt="" />&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;removeTokenFromInputs(token);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addTokenToOutputs(token);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invokeHandler(token,&nbsp;args);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
&nbsp;&nbsp;&nbsp; 那么具体的资源显然要实现AbstractResource中的doAction抽象方法，系统内置了五种资源：自动资源（AutoResource）、用户(User)、用户组(Group)、定时器(TimerResource)和事件监听器（ObserverResource）。显然，AutoResource、User和Group的doAction方法不需要做任何事情：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;User&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;AbstractResource&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;Group&nbsp;group;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" /><img src="http://www.blogjava.net/Images/dot.gif" alt="" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;doAction(Transition&nbsp;transition,&nbsp;Token&nbsp;token,&nbsp;Object<img src="http://www.blogjava.net/Images/dot.gif" alt="" />&nbsp;arg)</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}</span></div>
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 而TimerResource就需要做特殊处理了，比如我们要达到这样的效果：节点1状态已经处于就绪，可以被触发，可我们希望在就绪后延迟半分钟再触发，或者在晚上10点触发等等。这样的定时需求很常见，我采用了jdk5引入的ScheduledExecutorService来处理。系统中启动这样一个线程池，每个类似上面的请求都提交给这个线程池来处理，那么TimerResource就需要进行相应的修改：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">abstract</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;TimerResource&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;AbstractResource&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;pool_size;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;ScheduledExecutorService&nbsp;scheduledExecutorService;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;getId()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;TODO&nbsp;Auto-generated&nbsp;method&nbsp;stub</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;Common.TIMER_RESOURCE_ID;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;TimerResource()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.pool_size&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">5</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scheduledExecutorService&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;Executors.newScheduledThreadPool(pool_size);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;shutdownPool()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(scheduledExecutorService&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scheduledExecutorService.shutdown();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;start(Transition&nbsp;transition,&nbsp;Token&nbsp;token,&nbsp;Object<img src="http://www.blogjava.net/Images/dot.gif" alt="" />&nbsp;args)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;InterruptedException&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(transition.getCondition()&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">!</span><span style="color: #000000;">transition.getCondition().check(token))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">throw</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ConditionException(transition.getName()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;transition没有满足触发条件</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;transition.removeTokenFromInputs(token);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doAction(transition,&nbsp;token,&nbsp;args);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;ChangeRunner&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;Runnable&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Transition&nbsp;transition;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Token&nbsp;token;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Object[]&nbsp;args;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;ChangeRunner(Transition&nbsp;transition,&nbsp;Token&nbsp;token,&nbsp;Object<img src="http://www.blogjava.net/Images/dot.gif" alt="" />&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.transition&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;transition;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.token&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;token;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.args&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;args;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;run()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(transition.getCondition()&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">!</span><span style="color: #000000;">transition.getCondition().check(token))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">throw</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ConditionException(transition.getName()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;transition没有满足触发条件</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;transition.addTokenToOutputs(token);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;real_args[]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Object[args.length&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;real_args.length;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;real_args[i]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;args[i&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">2</span><span style="color: #000000;">];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;transition.invokeHandler(token,&nbsp;real_args);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;回调</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((WorkFlowAlgorithm)&nbsp;args[</span><span style="color: #000000;">1</span><span style="color: #000000;">]).enabledTraversing(token<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getWorkFlow());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((WorkFlowManager)&nbsp;args[</span><span style="color: #000000;">0</span><span style="color: #000000;">]).doAction(token.getId());<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.currentThread().interrupt();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
&nbsp;&nbsp;&nbsp; 注意到，start方法不再是直接调用transition的fire方法，而仅仅是进行了第一步操作：移除输入库所的place防止重复提交。后两步操作都延迟到了提交给线程池的任务中，也就是代码中的<span style="color: #000000;">ChangeRunner类中的run方法。例如TimerResource的子类DelayTimerResource用于处理延迟的触发，doAction就像这样：<br />
</span>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;DelayTimerResource&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;TimerResource&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" /><img src="http://www.blogjava.net/Images/dot.gif" alt="" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;doAction(Transition&nbsp;transition,&nbsp;Token&nbsp;token,&nbsp;Object<img src="http://www.blogjava.net/Images/dot.gif" alt="" />&nbsp;args)</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scheduledExecutorService.schedule(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ChangeRunner(transition,&nbsp;token,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;args),&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.delay,&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.timeUnit);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
&nbsp;&nbsp;&nbsp; 延迟的时间，时间单位这些信息都可以在流程定义文件中设置。事件监听器资源与此类似，ObserverResource实现了java.util.Observer接口，往输出库所放入token和回调handler两步操作被放在了update方法中提供给Subject回调。<br />
&nbsp;&nbsp;&nbsp; <br />
<br />
<br /><img src ="http://www.blogjava.net/killme2008/aggbug/152604.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-10-13 17:15 <a href="http://www.blogjava.net/killme2008/archive/2007/10/13/152604.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>写一个简单的工作流（二）</title><link>http://www.blogjava.net/killme2008/archive/2007/10/11/152093.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Thu, 11 Oct 2007 08:51:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/10/11/152093.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/152093.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/10/11/152093.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/152093.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/152093.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; hoho，今天完成了选择路由的实现，完成了配置文件的读写和解析，流程定义文件还是决定采用xml文件，不过与其他工作流引擎采用的xml完全不同，因为是基于petri网的，因此引入了place的概念，比如下面这个4个节点的顺序路由的流程：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">workflow&nbsp;</span><span style="color: #ff0000;">maxCases</span><span style="color: #0000ff;">="100"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">node&nbsp;</span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="start"</span><span style="color: #ff0000;">&nbsp;name</span><span style="color: #0000ff;">="start"</span><span style="color: #ff0000;">&nbsp;id</span><span style="color: #0000ff;">="0"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">inputs</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">place&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="1"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">inputs</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">outputs</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">place&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="2"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">outputs</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">node</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">node&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="hello"</span><span style="color: #ff0000;">&nbsp;id</span><span style="color: #0000ff;">="1"</span><span style="color: #ff0000;">&nbsp;resource</span><span style="color: #0000ff;">="user"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">conditions&nbsp;</span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="and"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">condition<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000;">class</span><span style="color: #0000ff;">="net.rubyeye.insect.workflow.impl.NullHandler"</span><span style="color: #ff0000;">&nbsp;value</span><span style="color: #0000ff;">="false"</span><span style="color: #ff0000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;variable-name</span><span style="color: #0000ff;">="name"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">conditions</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">handler<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000;">class</span><span style="color: #0000ff;">="net.rubyeye.insect.workflow.test.HelloWorldHandler"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">inputs</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">place&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="2"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">inputs</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">outputs</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">place&nbsp;</span><span style="color: #ff