<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Inside Java2Script &#187; Architecture</title>
	<atom:link href="http://inside.java2script.com/category/architecture/feed" rel="self" type="application/rss+xml" />
	<link>http://inside.java2script.com</link>
	<description>A Book about Java to JavaScript Details</description>
	<lastBuildDate>Mon, 22 Sep 2008 23:21:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Performance Matters or Not</title>
		<link>http://inside.java2script.com/2007/09/24/performance-matters-or-not.html</link>
		<comments>http://inside.java2script.com/2007/09/24/performance-matters-or-not.html#comments</comments>
		<pubDate>Mon, 24 Sep 2007 14:26:11 +0000</pubDate>
		<dc:creator>Zhou Renjian</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[GWT]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[SWT]]></category>

		<guid isPermaLink="false">http://inside.java2script.com/2007/09/24/performance-matters-or-not.html</guid>
		<description><![CDATA[Joel Spolsky had a post "Strategy Letter VI". And I did agree with him to some degree when reading the post. And I decided to write a post about these opinions related to Java2Script later in the evening. And later &#8230; <a href="http://inside.java2script.com/2007/09/24/performance-matters-or-not.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.joelonsoftware.com/">Joel Spolsky</a> had a post "<a href="http://www.joelonsoftware.com/items/2007/09/18.html">Strategy Letter VI</a>". And I did agree with him to some degree when reading the post. And I decided to write a post about these opinions related to Java2Script later in the evening. And later in evening I found that <a href="http://ajaxian.com/">Ajaxian's Ben Galbraith</a> posted his opinions but with title "<a href="http://ajaxian.com/archives/go-ajax-young-man">Go Ajax, Young Man</a>". Well, the title said something already.</p>
<p>Here follows the Java2Script performance issues and SDK concerns.</p>
<p>Right now, performance is a really big matter to Java2Script. But does performance matter a lot in the future? That is a question.</p>
<p><a href="http://j2s.sourceforge.net/">Java2Script</a> was open sourced in late of 2005. And now, 2 years has passed. And Firefox 2.0 is already released, while 2 year ago, it was still in its 1.0. And I could tell that the browser is improved a lot. OK, as I have paid lots of efforts in improving Java2Script performance, I think I would rather bet on the improvement of browser, the improvement of JavaScript engine (such as upgrading to Adobe's script engine), upgrading of CPU and machine.</p>
<p>About performance, maybe a lot of developers complain that Java is slow. In fact, a lot of developer complains that Eclipse, which is Java based, is very slow and could not stand for it. But Java is still a language used by most of the developers in the last 4 or 5 years. And JavaScript is a language that is much slower than other language. But in recent three years, it is getting hotter and hotter in the format of AJAX development. No matter how slow it is.</p>
<p>Back to Java2Script. Java2Script compile Java sources to JavaScript, and Java2Script supports a port of <a href="http://www.eclipse.org/swt/">desktop SWT library</a> in JavaScript besides supporting most common java.* classes. The compilation from Java to JavaScript is done in a Java-way, that is to say, all information in Java sources are preserved in JavaScript, so lots of Java information and features are reserved, including Java reflection. And SWT library is considered a heavy weight library for JavaScript, as it was once designed for desktop application, not for web application.</p>
<p>Now come to comparison of <a href="http://code.google.com/webtoolkit/">Google Web Toolkit (GWT)</a>. GWT is a similar project when comparing to Java2Script. It contains a Java to JavaScript compiler, and supports a set of basic java.* libraries and a set of UI library. But the compilation of Java to JavaScript is not in the same way of Java2Script. It is in a C-way. It links all related JavaScript into a big JavaScript file. And those unrelated (unused) JavaScript are left without packing into the big JavaScript file. So you can not retrieve the Java class information from the final *.js file. But as compiling in C-way, the final *.js is a lot smaller than Java2Script's *.js. And it also runs a lot faster than Java2Script's. And the UI library of GWT is a new set of APIs. It is designed for web applications in browser only. So it is more browser-oriented and much more light weighted. In such a way, GWT's performance is far faster than Java2Script. So few people cares about GWT's performance.</p>
<p>In some simple words:<br />
Java2Script is not optimized with more heavy weight SDK APIs<br />
GWT is optimized in compiling with a light weight SDK APIs.</p>
<p>In fact, GWT is 100 times more popular than Java2Script at this writing time. So that means performance do matters. But what about 2 more years later? Is there any possibilities that GWT's APIs is out and GWT's early performance optimization is lagged behind the improvement of hardware and browser? Maybe later, AJAX developments prove that those optimized compiled *.js is not the trends, and web applications oriented UI APIs is not the trends for richer applications. But no one knows now. So as Ben Galbraith said:</p>
<blockquote><p>it’s hard to dispute that in a year or two, JavaScript will be much, much faster.</p></blockquote>
<p>BTW: Java2Script 1.0.0 is to be released by the end of this September, even though performance is still a big problem (but not a <strong>huge</strong> problem now).</p>
<p>For more discussions, you may want to read <a href="http://inside.java2script.com/2007/05/14/java-to-javascript-compiler-discussion-1.html">early Java to JavaScript compiler discussions</a></p>
]]></content:encoded>
			<wfw:commentRss>http://inside.java2script.com/2007/09/24/performance-matters-or-not.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Performance of Comet and Simple Pipe</title>
		<link>http://inside.java2script.com/2007/09/13/performance-of-comet-and-simple-pipe.html</link>
		<comments>http://inside.java2script.com/2007/09/13/performance-of-comet-and-simple-pipe.html#comments</comments>
		<pubDate>Wed, 12 Sep 2007 18:10:08 +0000</pubDate>
		<dc:creator>Zhou Renjian</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Comet]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://inside.java2script.com/2007/09/13/performance-of-comet-and-simple-pipe.html</guid>
		<description><![CDATA[About one and a half months ago, I introduced Java2Script Simple Pipe, another Comet implementation. At that time, I knew there were lots of performance issues on such Comet technology. Because at that time I were busy and it was &#8230; <a href="http://inside.java2script.com/2007/09/13/performance-of-comet-and-simple-pipe.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>About one and a half months ago, I introduced <a href="http://inside.java2script.com/2007/08/01/introducing-java2scripts-simple-pipe.html">Java2Script Simple Pipe, another Comet implementation</a>. At that time, I knew there were lots of performance issues on such Comet technology. Because at that time I were busy and it was not a urgent deal for me, I didn't write test codes to test out the performances at that moment.</p>
<p>Only recently, I took some tests on performance issues. And the results said Simple Pipe's Comet implementation performs really bad!</p>
<p>Opening 10 Comet connections using Simple Pipe does not affect the whole server. But when I opened 20 Comet connections, the CPU usage is up to 100% quickly! It's not a problem of the application logics. It is a matter of Comet connection. </p>
<p>Java2Script Simple Pipe supports switching pipe mode into query mode. It is very easy, just call a static method:</p>
<blockquote class="code"><p><code>SimplePipeRequest.switchToQueryMode(250);</code></p></blockquote>
<p>After switching to query mode for the pipe, I can open up to 100+ connections to the server to receive stream data back to browser. The peak of CPU usage is about 60% ~ 70%. The average CPU usage may be about 20%-30%. It is an acceptable technology with such performances under the pressure tests.</p>
<p>( I did not test those server with special Comet optimizations. I just tested Simple Pipe on Apache Tomcat 5.5. Maybe those Comet optimized should have a better results. )</p>
]]></content:encoded>
			<wfw:commentRss>http://inside.java2script.com/2007/09/13/performance-of-comet-and-simple-pipe.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing Java2Script&#039;s Simple Pipe</title>
		<link>http://inside.java2script.com/2007/08/01/introducing-java2scripts-simple-pipe.html</link>
		<comments>http://inside.java2script.com/2007/08/01/introducing-java2scripts-simple-pipe.html#comments</comments>
		<pubDate>Wed, 01 Aug 2007 11:56:32 +0000</pubDate>
		<dc:creator>Zhou Renjian</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Browser]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://inside.java2script.com/2007/08/01/introducing-java2scripts-simple-pipe.html</guid>
		<description><![CDATA[Communications between server and browser are essential things in AJAX world. Basic Knowledge Each HTTP connection is forked by browser. And one HTTP connection may serve multiple sessions in HTTP 1.1 but server only one session in HTTP 1.0. There &#8230; <a href="http://inside.java2script.com/2007/08/01/introducing-java2scripts-simple-pipe.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Communications between server and browser are essential things in AJAX world. </p>
<p>Basic Knowledge</p>
<p>Each HTTP connection is forked by browser. And one HTTP connection may serve multiple sessions in HTTP 1.1 but server only one session in HTTP 1.0. There is no time limit or data transfer limit on each HTTP connection. This is basic knowledge of HTTP connections.</p>
<p>An HTML web page, may contains lots of resources, images, style sheets or JavaScript files, and each resources requires an HTTP session. And according technologies called AJAX, browser can load resources at any specific time.</p>
<p>What is Simple Pipe?</p>
<p>Simple Pipe is a kind of data transformation from server to browser. Once browser open up an HTTP connection to the server, the server keep the connection open. And whenever the server get data, it will flush data through the HTTP connection to browser. The data transfered through the connection is serialized and deserialized in SimpleSerializable format. </p>
<p>How to Setup a Simple Pipe?</p>
<p>Simple Pipe is currently designed for Java language. There is a class named "com.java2script.ajax.pipe.SimplePipeRequest" with a static method named "pipeRequest" which accept a parameter in type of "com.java2script.ajax.pipe.SimplePipeRunnable". The SimplePipeRunnable is will accept parameters from browser side, and then be passed to server side (Tomcat or other Servlet containers), and its action will be executed. In most cases, an other-type connection is created, and listeners are added to the connections for up-coming events. And the connection will be registered with a generated pipe key. And the pipe key will be sent back to browser side. Browser side will create another connection to the server with the given pipe key. Server will check the pipe key, and hold the HTTP connection, and flush any data from previous registered connection to browser side in format of SimpleSerializable. Browser will use IFRAME to accept the data, and return back to object instances. In keeping the HTTP connection, browser will send a notifying signal (HTTP connection) to server to make sure that browser is keeping the connection live. If browser likes to close the pipe, it will send another Simple RPC call the server to notify server that pipe should be closed. If it happens that browser exit without notifying closing pipe, server will close the pipe in a minute or so, as there is no such signals for the pipe to be kept alive.</p>
<p>As Simple Pipe is a subset of Java2Script library API, Simple Pipe may only be used in Java language. But after being converted to JavaScript by Java2Script compiler, Simple Pipe technology can be used in JavaScript language. And <a href="http://demo.java2script.org/gtalk/">JavaScript demo of Google Talk</a> is an example of Simple Pipe.</p>
<p>Code Snippets</p>
<p>SimplePipeSWTRequest#swtPipe usage:</p>
<blockquote class="code"><p><code>        SimplePipeSWTRequest.swtPipe(<span class="keyword">new</span> LoginRunnable() <span class="scope">{</span></p>
<p>            @Override<br />
            <span class="keyword">public</span> <span class="keyword">void</span> ajaxIn() <span class="scope">{</span><br />
                username = userNameText.getText().trim();<br />
                password = passwordText.getText();<br />
            <span class="scope">}</span></p>
<p>            @Override<br />
            <span class="keyword">public</span> <span class="keyword">void</span> ajaxOut() <span class="scope">{</span><br />
                <span class="keyword">if</span> (failed) <span class="scope">{</span><br />
                    MessageBox messageBox = <span class="keyword">new</span> MessageBox(MainWindow.<span class="keyword">this</span>, SWT.ICON_ERROR);<br />
                    <span class="comment">// notify error</span><br />
                    <span class="keyword">return</span>;<br />
                <span class="scope">}</span><br />
                setData(<span class="string">&quot;ConnectionKey&quot;</span>, key);<br />
                setData(<span class="string">&quot;PipeKey&quot;</span>, pipeKey);<br />
                <span class="comment">// continue to login</span><br />
            <span class="scope">}</span></p>
<p>            @Override<br />
            <span class="keyword">public</span> <span class="keyword">void</span> ajaxFail() <span class="scope">{</span><br />
                MessageBox messageBox = <span class="keyword">new</span> MessageBox(MainWindow.<span class="keyword">this</span>, SWT.ICON_ERROR);<br />
                <span class="comment">// .. notify errors</span><br />
            <span class="scope">}</span></p>
<p>            <span class="keyword">public</span> <span class="keyword">void</span> deal(PresenceSerializable ps) <span class="scope">{</span><br />
                <span class="comment">// Data received from pipe! To update presence status</span><br />
            <span class="scope">}</span></p>
<p>            @Override<br />
            <span class="keyword">public</span> <span class="keyword">void</span> deal(<span class="keyword">final</span> MessageSerializable ms) <span class="scope">{</span><br />
                <span class="comment">// Data received from pipe! To popup chatting dialog...</span><br />
            <span class="scope">}</span></p>
<p>            @Override<br />
            <span class="keyword">public</span> <span class="keyword">void</span> deal(RosterSerializable rs) <span class="scope">{</span><br />
                <span class="comment">// Data received from pipe! To update roster entries...</span><br />
            <span class="scope">}</span></p>
<p>        <span class="scope">}</span>);<br />
</code></p></blockquote>
<p>LoginRunnable</p>
<blockquote class="code"><p><code><span class="keyword">public</span> <span class="keyword">class</span> LoginRunnable <span class="keyword">extends</span> SimplePipeRunnable <span class="scope">{</span></p>
<p>    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">class</span> PresenceSerializable <span class="keyword">extends</span> SimpleSerializable <span class="scope">{</span><br />
        <span class="keyword">public</span> String name;<br />
        <span class="keyword">public</span> String email;<br />
        <span class="keyword">public</span> String status;<br />
        <span class="keyword">public</span> String type;<br />
        <span class="keyword">public</span> String mode;<br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">class</span> MessageSerializable <span class="keyword">extends</span> SimpleSerializable <span class="scope">{</span><br />
        <span class="keyword">public</span> String from;<br />
        <span class="keyword">public</span> String body;<br />
        <span class="keyword">public</span> String to;<br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">class</span> RosterSerializable <span class="keyword">extends</span> SimpleSerializable <span class="scope">{</span><br />
        <span class="keyword">public</span> String from;<br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> String username;</p>
<p>    <span class="keyword">public</span> String password;</p>
<p>    <span class="keyword">public</span> String host;</p>
<p>    <span class="keyword">public</span> <span class="keyword">int </span>port;</p>
<p>    <span class="keyword">public</span> String service;</p>
<p>    <span class="keyword">public</span> String key;</p>
<p>    <span class="keyword">public</span> <span class="keyword">boolean</span> failed;</p>
<p>    @Override<br />
    <span class="keyword">public</span> String getHttpURL() <span class="scope">{</span><br />
        <span class="keyword">return</span> TalkRunnble.TALK_URL_BASE + <span class="string">&quot;simplerpc&quot;</span>;<br />
    <span class="scope">}</span></p>
<p>    @Override<br />
    <span class="keyword">public</span> String getPipeURL() <span class="scope">{</span><br />
        <span class="keyword">return</span> TalkRunnble.TALK_URL_BASE + <span class="string">&quot;simplepipe&quot;</span>;<br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * TODO: {@link #pipeSetup()} should be ignored by Java2Script compiler<br />
	 * by default.<br />
	 * @j2sIgnore<br />
	 */</span><br />
    @Override<br />
    <span class="keyword">public</span> <span class="keyword">void</span> pipeSetup() <span class="scope">{</span><br />
        failed = <span class="keyword">false</span>;<br />
        JabberHelper instance = JabberHelper.getInstance();<br />
        key = instance.login(username, password, host, port, service);<br />
        <span class="keyword">if</span> (key == <span class="keyword">null</span>) <span class="scope">{</span><br />
            failed = <span class="keyword">true</span>;<br />
            <span class="keyword">return</span>;<br />
        <span class="scope">}</span><br />
        <span class="keyword">new</span> Thread(<span class="keyword">new</span> Runnable() <span class="scope">{</span></p>
<p>            <span class="keyword">public</span> <span class="keyword">void</span> run() <span class="scope">{</span><br />
                <span class="keyword">while</span> (<span class="keyword">true</span>) <span class="scope">{</span><br />
                    try <span class="scope">{</span><br />
                        Thread.sleep(30000);<br />
                    <span class="scope">}</span> catch (InterruptedException e) <span class="scope">{</span><br />
                        <span class="comment">//e.printStackTrace();</span><br />
                    <span class="scope">}</span><br />
                    <span class="keyword">if</span> (!isPipeLive()) <span class="scope">{</span><br />
                        pipeDestroy();<br />
                        break;<br />
                    <span class="scope">}</span><br />
                <span class="scope">}</span><br />
            <span class="scope">}</span></p>
<p>        <span class="scope">}</span>, <span class="string">&quot;Jabber Connection Monitor&quot;</span>).start();</p>
<p>        XMPPConnection conn = instance.getConnectionByKey(key);</p>
<p>        Presence presence = <span class="keyword">new</span> Presence(Presence.Type.available);<br />
        conn.sendPacket(presence);</p>
<p>        <span class="comment">//XMPPConnection conn = JabberHelper.getInstance().getConnectionByKey(key);</span><br />
        conn.addPacketListener(<span class="keyword">new</span> PacketListener() <span class="scope">{</span></p>
<p>            <span class="keyword">public</span> <span class="keyword">void</span> processPacket(Packet packet) <span class="scope">{</span><br />
                pipeThrough(packet);<br />
            <span class="scope">}</span></p>
<p>        <span class="scope">}</span>, <span class="keyword">null</span>);<br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * @j2sIgnore<br />
	 */</span><br />
    @Override<br />
    <span class="keyword">public</span> <span class="keyword">boolean</span> isPipeLive() <span class="scope">{</span><br />
        JabberHelper instance = JabberHelper.getInstance();<br />
        XMPPConnection conn = instance.getConnectionByKey(key);<br />
        <span class="keyword">return</span> <span class="keyword">super</span>.isPipeLive() &amp;&amp; conn != <span class="keyword">null</span> &amp;&amp; conn.isConnected()<br />
                &amp;&amp; !instance.isConnectionLost(key);<br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * @j2sIgnore<br />
	 */</span><br />
    @Override<br />
    <span class="keyword">public</span> <span class="keyword">void</span> pipeDestroy() <span class="scope">{</span><br />
        JabberHelper instance = JabberHelper.getInstance();<br />
        instance.logout(key); <span class="comment">// try to logout</span><br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * @j2sIgnore<br />
	 */</span><br />
    @Override<br />
    <span class="keyword">public</span> <span class="keyword">void</span> keepPipeLive() <span class="scope">{</span><br />
        JabberHelper instance = JabberHelper.getInstance();<br />
        instance.update(key);<br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * TODO: {@link #through(Object...)} should be ignored by Java2Script<br />
	 * compiler by default.<br />
	 * @j2sIgnore<br />
	 */</span><br />
    <span class="keyword">public</span> SimpleSerializable[] through(Object... args) <span class="scope">{</span><br />
        <span class="keyword">if</span> (args != <span class="keyword">null</span> &amp;&amp; args.length <span class="tag">&gt;</span> 0) <span class="scope">{</span><br />
            Packet packet = (Packet) args[0];<br />
            SimpleSerializable[] ss = <span class="keyword">new</span> SimpleSerializable[1];<br />
            <span class="keyword">if</span> (packet instanceof Presence) <span class="scope">{</span><br />
                Presence presence = (Presence) packet;<br />
                PresenceSerializable ps = <span class="keyword">new</span> PresenceSerializable();<br />
                ps.email = presence.getFrom();<br />
                Mode mode = presence.getMode();<br />
                ps.mode = mode == <span class="keyword">null</span> ? <span class="keyword">null</span> : mode.name();<br />
                Type type = presence.getType();<br />
                ps.type = type == <span class="keyword">null</span> ? <span class="keyword">null</span> : type.name();<br />
                ps.status = presence.getStatus();<br />
                ss[0] = ps;<br />
                <span class="keyword">return</span> ss;<br />
            <span class="scope">}</span> <span class="keyword">else</span> <span class="keyword">if</span> (packet instanceof Message) <span class="scope">{</span><br />
                Message message = (Message) packet;<br />
                MessageSerializable ms = <span class="keyword">new</span> MessageSerializable();<br />
                ms.from = message.getFrom();<br />
                ms.body = message.getBody();<br />
                ms.to = message.getTo();<br />
                ss[0] = ms;<br />
                <span class="keyword">return</span> ss;<br />
            <span class="scope">}</span> <span class="keyword">else</span> <span class="keyword">if</span> (packet instanceof RosterPacket) <span class="scope">{</span><br />
                RosterPacket roster = (RosterPacket) packet;<br />
                RosterSerializable rs = <span class="keyword">new</span> RosterSerializable();<br />
                rs.from = roster.getFrom();<br />
                roster.getType();<br />
                ss[0] = rs;<br />
                <span class="keyword">return</span> ss;<br />
            <span class="scope">}</span><br />
        <span class="scope">}</span><br />
        <span class="keyword">return</span> <span class="keyword">null</span>;<br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> <span class="keyword">void</span> deal(PresenceSerializable ps) <span class="scope">{</span><br />
        <span class="comment">// To be override</span><br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> <span class="keyword">void</span> deal(MessageSerializable ms) <span class="scope">{</span><br />
        <span class="comment">// To be override</span><br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> <span class="keyword">void</span> deal(RosterSerializable rs) <span class="scope">{</span><br />
        <span class="comment">// To be override</span><br />
    <span class="scope">}</span></p>
<p><span class="scope">}</span><br />
</code></p></blockquote>
<p>SimplePipeRunnable</p>
<blockquote class="code"><p><code><span class="keyword">public</span> abstract <span class="keyword">class</span> SimplePipeRunnable <span class="keyword">extends</span> SimpleRPCRunnable <span class="scope">{</span></p>
<p>    <span class="comment">/**<br />
	 * Pipe's id<br />
	 */</span><br />
    <span class="keyword">public</span> String pipeKey;</p>
<p>    <span class="keyword">private</span> <span class="keyword">boolean</span> pipeAlive;</p>
<p>    <span class="keyword">private</span> SimplePipeHelper.IPipeThrough helper;</p>
<p>    <span class="comment">/**<br />
	 *<br />
	 * @param helper<br />
	 * @j2sIgnore<br />
	 */</span><br />
    <span class="keyword">void</span> setPipeHelper(SimplePipeHelper.IPipeThrough helper) <span class="scope">{</span><br />
        <span class="keyword">this</span>.helper = helper;<br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> String getPipeURL() <span class="scope">{</span><br />
        <span class="keyword">return</span> <span class="string">&quot;simplepipe&quot;</span>; <span class="comment">// url is relative to the servlet!</span><br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">public</span> String getPipeMethod() <span class="scope">{</span><br />
        <span class="keyword">return</span> <span class="string">&quot;GET&quot;</span>;<br />
    <span class="scope">}</span></p>
<p>    @Override<br />
    <span class="keyword">public</span> <span class="keyword">void</span> ajaxRun() <span class="scope">{</span><br />
        pipeKey = SimplePipeHelper.registerPipe(<span class="keyword">this</span>);<br />
        <span class="keyword">if</span> (pipeKey != <span class="keyword">null</span>) <span class="scope">{</span><br />
            pipeSetup();<br />
            pipeAlive = <span class="keyword">true</span>;<br />
        <span class="scope">}</span> <span class="keyword">else</span> <span class="scope">{</span> <span class="comment">// failed!</span><br />
            pipeAlive = <span class="keyword">false</span>;<br />
        <span class="scope">}</span><br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * Listening on given events and pipe events from Simple RPC to client.<br />
	 */</span><br />
    <span class="keyword">public</span> abstract <span class="keyword">void</span> pipeSetup();</p>
<p>    <span class="comment">/**<br />
	 * Destroy the pipe and remove listeners.<br />
	 * After pipe is destroyed, {@link #isPipeLive()} must be false<br />
	 */</span><br />
    <span class="keyword">public</span> abstract <span class="keyword">void</span> pipeDestroy();</p>
<p>    <span class="comment">/**<br />
	 * Return whether the pipe is still live or not.<br />
	 * @return pipe is live or not.<br />
	 */</span><br />
    <span class="keyword">public</span> <span class="keyword">boolean</span> isPipeLive() <span class="scope">{</span><br />
        <span class="keyword">return</span> pipeAlive;<br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * Notify that the pipe is still alive.<br />
	 */</span><br />
    <span class="keyword">public</span> <span class="keyword">void</span> keepPipeLive() <span class="scope">{</span><br />
        <span class="comment">// to be override</span><br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * Update pipe's live status.<br />
	 *<br />
	 * @param live if live is true, just notify the pipe is still alive. if live is false<br />
	 * and {@link #isPipeLive()} is true, {@link #pipeDestroy()} will be called.<br />
	 */</span><br />
    <span class="keyword">protected</span> <span class="keyword">void</span> updateStatus(<span class="keyword">boolean</span> live) <span class="scope">{</span><br />
        <span class="keyword">if</span> (live) <span class="scope">{</span><br />
            keepPipeLive();<br />
            pipeAlive = <span class="keyword">true</span>;<br />
        <span class="scope">}</span> <span class="keyword">else</span> <span class="keyword">if</span> (isPipeLive()) <span class="scope">{</span><br />
            pipeDestroy();<br />
            pipeAlive = <span class="keyword">false</span>;<br />
        <span class="scope">}</span><br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * Convert input objects into SimpleSerializable objects.<br />
	 *<br />
	 * @param args<br />
	 * @return SimpleSerializable objects to be sent through the pipe.<br />
	 */</span><br />
    <span class="keyword">public</span> abstract SimpleSerializable[] through(Object ... args);</p>
<p>    <span class="keyword">public</span> <span class="keyword">void</span> deal(SimpleSerializable ss) <span class="scope">{</span><br />
        try <span class="scope">{</span><br />
            Class<span class="tag">&lt;</span>? <span class="keyword">extends</span> SimpleSerializable<span class="tag">&gt;</span> clazz = ss.getClass();<br />
            <span class="keyword">if</span> (<span class="string">&quot;net.sf.j2s.ajax.SimpleSerializable&quot;</span>.equals(clazz.getName())) <span class="scope">{</span><br />
                System.out.println(<span class="string">&quot;Default!&quot;</span>);<br />
            <span class="scope">}</span><br />
            Method method = <span class="keyword">null</span>;</p>
<p>            Class<span class="tag">&lt;</span>?<span class="tag">&gt;</span> clzz = getClass();<br />
            String clazzName = clzz.getName();<br />
            <span class="keyword">int </span>idx = -1;<br />
            <span class="keyword">while</span> ((idx = clazzName.lastIndexOf(<span class="string">&apos;$&apos;</span>)) != -1) <span class="scope">{</span><br />
                <span class="keyword">if</span> (clazzName.length() <span class="tag">&gt;</span> idx + 1) <span class="scope">{</span><br />
                    char ch = clazzName.charAt(idx + 1);<br />
                    <span class="keyword">if</span> (ch <span class="tag">&lt;</span> <span class="string">&apos;0&apos;</span> &amp;&amp; ch <span class="tag">&gt;</span> <span class="string">&apos;9&apos;</span>) <span class="scope">{</span> <span class="comment">// not a number</span><br />
                        break; <span class="comment">// inner class</span><br />
                    <span class="scope">}</span><br />
                <span class="scope">}</span><br />
                clzz = clzz.getSuper<span class="keyword">class</span>();<br />
                <span class="keyword">if</span> (clzz == <span class="keyword">null</span>) <span class="scope">{</span><br />
                    break; <span class="comment">// should never happen!</span><br />
                <span class="scope">}</span><br />
                clazzName = clzz.getName();<br />
            <span class="scope">}</span><br />
            <span class="keyword">if</span> (clzz != <span class="keyword">null</span>) <span class="scope">{</span><br />
                method = clzz.getMethod(<span class="string">&quot;deal&quot;</span>, clazz);<br />
                <span class="keyword">if</span> (method != <span class="keyword">null</span>) <span class="scope">{</span><br />
                    method.invoke(<span class="keyword">this</span>, ss);<br />
                    <span class="keyword">return</span>;<br />
                <span class="scope">}</span><br />
            <span class="scope">}</span><br />
        <span class="scope">}</span> catch (Exception e) <span class="scope">{</span><br />
            e.printStackTrace();<br />
        <span class="scope">}</span><br />
        <span class="comment">// default</span><br />
        System.out.println(<span class="string">&quot;Default!&quot;</span>);<br />
    <span class="scope">}</span></p>
<p>    <span class="comment">/**<br />
	 * A method used to pipe a bundle of instances through.<br />
	 *<br />
	 * Attention: Only visible inside {@link #pipeSetup()}.<br />
	 * @param args<br />
	 * @j2sIgnore<br />
	 */</span><br />
    <span class="keyword">protected</span> <span class="keyword">void</span> pipeThrough(Object ... args) <span class="scope">{</span><br />
        SimplePipeRunnable pipe = SimplePipeHelper.getPipe(pipeKey);<br />
        <span class="keyword">if</span> (pipe == <span class="keyword">null</span>) <span class="keyword">return</span>;<br />
        SimpleSerializable[] objs = pipe.through(args);</p>
<p>        <span class="keyword">if</span> (objs == <span class="keyword">null</span> || objs.length == 0) <span class="keyword">return</span>;</p>
<p>        <span class="keyword">if</span> (pipe instanceof SimplePipeRunnable) <span class="scope">{</span><br />
            SimplePipeRunnable pipeRunnable = (SimplePipeRunnable) pipe;<br />
            <span class="keyword">if</span> (pipeRunnable.helper != <span class="keyword">null</span>) <span class="scope">{</span><br />
                pipeRunnable.helper.helpThrough(pipe, objs);<br />
                <span class="keyword">return</span>;<br />
            <span class="scope">}</span><br />
        <span class="scope">}</span><br />
        <span class="keyword">for</span> (<span class="keyword">int </span>i = 0; i <span class="tag">&lt;</span> objs.length; i++) <span class="scope">{</span><br />
            pipe.deal(objs[i]);<br />
        <span class="scope">}</span><br />
    <span class="scope">}</span></p>
<p><span class="scope">}</span><br />
</code></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://inside.java2script.com/2007/08/01/introducing-java2scripts-simple-pipe.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Regarding GWT</title>
		<link>http://inside.java2script.com/2007/07/01/regarding-gwt.html</link>
		<comments>http://inside.java2script.com/2007/07/01/regarding-gwt.html#comments</comments>
		<pubDate>Sun, 01 Jul 2007 15:16:25 +0000</pubDate>
		<dc:creator>Zhou Renjian</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[GWT]]></category>

		<guid isPermaLink="false">http://inside.java2script.com/2007/07/01/regard-gwt.html</guid>
		<description><![CDATA[You must already know GWT if you learn Java2Script by "Java to JavaScript compiler". I seldom mentioned GWT in "Java2Script" topics in the past, except an article "GWT v.s. Java2Script SWT" in early days when GWT was announced. But late &#8230; <a href="http://inside.java2script.com/2007/07/01/regarding-gwt.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>You must already know <a href="http://code.google.com/webtoolkit/">GWT</a> if you learn Java2Script by "Java to JavaScript compiler".</p>
<p>I seldom mentioned GWT in "Java2Script" topics in the past, except an article "<a href="http://java2script.org/blog/2006/05/17/gwt-vs-java2script-swt/">GWT v.s. Java2Script SWT</a>" in early days when GWT was announced.</p>
<p>But late these days, I think if I compare more details between GWT and Java2Script, it may help new developers to get further understanding of both GWT and Java2Script.</p>
<p>Here is a list of similarities for GWT and Java2Script:</p>
<ol>
<li>Java to JavaScript compiler</li>
<li>Widget components (GWT v.s. SWT)</li>
<li>Support RPC (GWT's RPC v.s. Java2Script's Simple RPC)</li>
<li>Support Eclipse</li>
</ol>
<p>I think later I will discuss more details (similarities and differences, advantages and disadvantages) on the above list.</p>
]]></content:encoded>
			<wfw:commentRss>http://inside.java2script.com/2007/07/01/regarding-gwt.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Asynchrony is Everything</title>
		<link>http://inside.java2script.com/2007/06/29/asynchrony-is-everything.html</link>
		<comments>http://inside.java2script.com/2007/06/29/asynchrony-is-everything.html#comments</comments>
		<pubDate>Fri, 29 Jun 2007 14:41:21 +0000</pubDate>
		<dc:creator>Zhou Renjian</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Hacks]]></category>

		<guid isPermaLink="false">http://inside.java2script.com/2007/06/29/asynchrony-is-everything.html</guid>
		<description><![CDATA[You may know "Position is Everything" already. And I believe you should also know "Asynchony is Everything" or "Everything is Asynchronous" in RIA development. Asynchrony is not only very important in web application development but also vital in normal desktop &#8230; <a href="http://inside.java2script.com/2007/06/29/asynchrony-is-everything.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>You may know "<a href="http://www.google.com/search?q=Position%20is%20Everything">Position is Everything</a>" already. And I believe you should also know "Asynchony is Everything" or "Everything is Asynchronous" in RIA development.</p>
<p>Asynchrony is not only very important in web application development but also vital in normal desktop applications and embed systems. Asynchronous programming may help a lot in improving user experience. In normal desktop applications, if the main thread blocks UI for its long-time-consuming computing, users will feel desperately, waiting the busy-cursor to turn into default. But if such computing is run in background, user would find other things to do, such as switching focuses or typing something.</p>
<p>What about the definition of Asynchronous Computing? It is not only about asynchronous loading or asynchronous remote procedure call (RPC), it is also about local calculating. One thing should be mentioned here is UI layout computing. Lots of UI need complex layout calculating. For example, rendering a web page, rendering a 3D interfaces, or rending a complex dialog box. This CPU times required is especially obvious when it's performed in a slow computer or in a slow computing environment, such as JavaScript runtime in browsers.</p>
<p>Here, I concerns about asynchronous layout. In implementing Java2Script's SWT library, there is a huge problem for us. JavaScript is so slow that it can not finish a complex layout in less than 5 seconds. Or a complex layout requires more than 1 second will freeze browser UI, which make the user experience very bad and unacceptable. In order to overcome such problems. Java2Script introduced "Asynchronous Layout".</p>
<p>Asynchronous layout is about to split the layout jobs into small pieces of jobs and run them step by step. As you may know, in SWT, all widgets are placed inside some containers. And to make a layout over container, the bounds of parent container, which is a Composite widget, is calculated first. And then the bounds will be passed as constraints of its child widgets to make children layouts. In such layout algorithms, we could split the layout jobs into parent container layout and child widget layout jobs, queue these jobs, and monitor each job's required CPU times to avoid complex layout takes more than 200ms. If layout computing takes more than 200ms, then sleep for about 50ms before calling the next layout job.</p>
<p>Here are some snippets about Asynchronous Layout:</p>
<p>Display#readAndDispatch</p>
<blockquote class="code"><p><code><span class="keyword">public</span> <span class="keyword">boolean</span> readAndDispatch () <span class="scope">{</span><br />
    checkDevice ();<br />
    drawMenuBars ();<br />
    runPopups ();<br />
    <span class="comment">/*<br />
	if (OS.PeekMessage (msg, 0, 0, 0, OS.PM_REMOVE)) {<br />
		if (!filterMessage (msg)) {<br />
			OS.TranslateMessage (msg);<br />
			OS.DispatchMessage (msg);<br />
		}<br />
		runDeferredEvents ();<br />
		return true;<br />
	}<br />
	return runAsyncMessages (false);<br />
	*/</span><br />
    <span class="keyword">if</span> (messageProc != 0) <span class="scope">{</span><br />
        <span class="keyword">return</span> <span class="keyword">true</span>; <span class="comment">//already hooked, return directly</span><br />
    <span class="scope">}</span><br />
    messageProc = window.setInterval(<span class="keyword">new</span> RunnableCompatibility() <span class="scope">{</span><br />
        <span class="keyword">private</span> <span class="keyword">boolean</span> messageLoop = <span class="keyword">false</span>;<br />
        <span class="keyword">public</span> <span class="keyword">void</span> run() <span class="scope">{</span><br />
            runPopups ();<br />
            MESSAGE[] msgs = Display.<span class="keyword">this</span>.msgs;<br />
            <span class="keyword">if</span> (msgs.length == 0 &amp;&amp; messageLoop)<br />
            <span class="comment">/**<br />
			 * @j2sNative<br />
			 * var layoutFinished = window["j2s.swt.shell.finish.layout"];<br />
			 * if (layoutFinished != null) {<br />
			 * 	layoutFinished ();<br />
			 * }<br />
			 * this.messageLoop = false;<br />
			 */</span>    <span class="scope">{</span> <span class="scope">}</span><br />
            <span class="keyword">if</span> (msgs.length != 0) <span class="scope">{</span><br />
                messageLoop = <span class="keyword">true</span>;<br />
                MESSAGE[] defered = <span class="keyword">new</span> MESSAGE[0];</p>
<p>                <span class="keyword">int </span>defsize = 0;<br />
                <span class="keyword">for</span> (<span class="keyword">int </span>i = msgs.length - 1; i <span class="tag">&gt;</span>= 0; i--) <span class="scope">{</span><br />
                    MESSAGE m1 = msgs[i];<br />
                    <span class="keyword">if</span> (m1 == <span class="keyword">null</span>) <span class="scope">{</span><br />
                        continue;<br />
                    <span class="scope">}</span><br />
                    m1.defer = <span class="keyword">false</span>;<br />
                    <span class="keyword">for</span> (<span class="keyword">int </span>j = i - 1; j <span class="tag">&gt;</span>= 0; j--) <span class="scope">{</span><br />
                        MESSAGE m2 = msgs[j];<br />
                        <span class="keyword">if</span> (m2 != <span class="keyword">null</span> &amp;&amp; m2.control == m1.control<br />
                                &amp;&amp; m2.type == m1.type) <span class="scope">{</span><br />
                            msgs[j] = <span class="keyword">null</span>;<br />
                        <span class="scope">}</span><br />
                    <span class="scope">}</span></p>
<p>                    <span class="keyword">if</span>(m1.type == MESSAGE.CONTROL_LAYOUT)<span class="scope">{</span><br />
                        <span class="keyword">if</span>(m1.control.parent != <span class="keyword">null</span> &amp;&amp; m1.control.parent.waitingForLayout)<span class="scope">{</span><br />
                            m1.defer = <span class="keyword">true</span>;<br />
                            defered[defsize++] = m1;<br />
                        <span class="scope">}</span><br />
                    <span class="scope">}</span></p>
<p>                <span class="scope">}</span><br />
                long time = 0;</p>
<p>                <span class="keyword">for</span> (<span class="keyword">int </span>i = 0; i <span class="tag">&lt;</span> msgs.length; i++) <span class="scope">{</span><br />
                    MESSAGE m = msgs[i];</p>
<p>                    <span class="keyword">if</span>(m != <span class="keyword">null</span> &amp;&amp; m.defer)<span class="scope">{</span><br />
                        continue;<br />
                    <span class="scope">}</span><br />
                    msgs[i] = <span class="keyword">null</span>;<br />
                    <span class="keyword">if</span> (m != <span class="keyword">null</span> &amp;&amp; m.type == MESSAGE.CONTROL_LAYOUT) <span class="scope">{</span><br />
                        m.control.waitingForLayout = <span class="keyword">false</span>;<br />
                        <span class="keyword">if</span> (!m.control.isVisible()) <span class="scope">{</span> continue; <span class="scope">}</span><br />
                        Date d = <span class="keyword">new</span> Date();<br />
                        Composite c = (Composite) m.control;<br />
                        <span class="keyword">if</span>(c.waitingForLayoutWithResize)<span class="scope">{</span><br />
                            c.setResizeChildren (<span class="keyword">false</span>);<br />
                        <span class="scope">}</span><br />
                        <span class="keyword">if</span>(c.layout != <span class="keyword">null</span>)<span class="scope">{</span><br />
                            c.layout.layout (c, (c.state &amp; Composite.LAYOUT_CHANGED) != 0);<br />
                            c.state &amp;= ~(Composite.LAYOUT_NEEDED | Composite.LAYOUT_CHANGED);<br />
                        <span class="scope">}</span><br />
                        <span class="keyword">if</span>(c.waitingForLayoutWithResize)<span class="scope">{</span><br />
                            c.setResizeChildren (<span class="keyword">true</span>);<br />
                            c.waitingForLayoutWithResize = <span class="keyword">false</span>;<br />
                        <span class="scope">}</span></p>
<p>                        <span class="keyword">if</span> (m.data != <span class="keyword">null</span>) <span class="scope">{</span><br />
                            <span class="keyword">boolean</span>[] bs = (<span class="keyword">boolean</span>[]) m.data;<br />
                            c.updateLayout(bs[0], bs[1]);<br />
                        <span class="scope">}</span> <span class="keyword">else</span> <span class="scope">{</span><br />
                            c.layout();<br />
                        <span class="scope">}</span><br />
                        time += <span class="keyword">new</span> Date().getTime() - d.getTime();<br />
                        <span class="keyword">if</span> (time <span class="tag">&gt;</span> 200) <span class="scope">{</span><br />
                            <span class="keyword">for</span> (<span class="keyword">int </span>j = i + 1; j <span class="tag">&lt;</span> msgs.length; j++) <span class="scope">{</span><br />
                                msgs[j - i - 1] = msgs[j];<br />
                            <span class="scope">}</span><br />
                            <span class="keyword">int </span>length = msgs.length - i - 1;<br />
                            <span class="keyword">for</span>(<span class="keyword">int </span>j = 0; j <span class="tag">&lt;</span> defsize; j++)<span class="scope">{</span><br />
                                msgs[length + j] = defered[j];<br />
                            <span class="scope">}</span><br />
                            <span class="comment">/**<br />
							 * @j2sNativeSrc<br />
							 * msgs.length -= i + 1;<br />
							 * @j2sNative<br />
							 * a.length -= f + 1;<br />
							 */</span> <span class="scope">{</span><span class="scope">}</span><br />
                            <span class="keyword">return</span> ;<br />
                        <span class="scope">}</span><br />
                    <span class="scope">}</span><br />
                <span class="scope">}</span><br />
                <span class="comment">/**<br />
				 * @j2sNativeSrc<br />
				 * msgs.length = 0;<br />
				 * @j2sNative<br />
				 * a.length = 0;<br />
				 */</span> <span class="scope">{</span><span class="scope">}</span><br />
                 Display.<span class="keyword">this</span>.msgs = defered;<br />
<span class="comment">//				for(int j = 0; j < defsize; j++){</span><br />
<span class="comment">//					msgs[j] = defered[j];</span><br />
<span class="comment">//				}</span><br />
            <span class="scope">}</span><br />
        <span class="scope">}</span><br />
    <span class="scope">}</span>, 100);<br />
    <span class="keyword">return</span> <span class="keyword">true</span>;<br />
<span class="scope">}</span><br />
</code></p></blockquote>
<p>Composite#updateLayout</p>
<blockquote class="code"><p><code><span class="keyword">void</span> updateLayout (<span class="keyword">boolean</span> resize, <span class="keyword">boolean</span> all) <span class="scope">{</span><br />
    <span class="keyword">if</span> (isLayoutDeferred ()) <span class="keyword">return</span>;<br />
    <span class="keyword">if</span> ((state &amp; LAYOUT_NEEDED) != 0 &amp;&amp; !waitingForLayout) <span class="scope">{</span><br />
<span class="comment">//		boolean changed = (state &#038; LAYOUT_CHANGED) != 0;</span><br />
<span class="comment">//		state &#038;= ~(LAYOUT_NEEDED | LAYOUT_CHANGED);</span><br />
<span class="comment">//		if (resize) setResizeChildren (false);</span><br />
<span class="comment">//		layout.layout (this, changed);</span><br />
<span class="comment">//		if (resize) setResizeChildren (true);</span><br />
        <span class="keyword">this</span>.waitingForLayout = <span class="keyword">true</span>;<br />
        <span class="keyword">this</span>.waitingForLayoutWithResize = resize;<br />
        display.sendMessage(<span class="keyword">new</span> MESSAGE(<span class="keyword">this</span>, MESSAGE.CONTROL_LAYOUT, <span class="keyword">new</span> <span class="keyword">boolean</span>[] <span class="scope">{</span>resize, all<span class="scope">}</span>));<br />
    <span class="scope">}</span></p>
<p>    <span class="keyword">if</span> (all) <span class="scope">{</span><br />
        Control [] children = _getChildren ();<br />
        <span class="keyword">int </span>length = children.length;<br />
        <span class="keyword">for</span> (<span class="keyword">int </span>i=0; i<span class="tag">&lt;</span>length; i++) <span class="scope">{</span><br />
<span class="comment">//			children [i].updateLayout (resize, all);</span><br />
            <span class="keyword">if</span> (children[i] instanceof Composite) <span class="scope">{</span><br />
                display.sendMessage(<span class="keyword">new</span> MESSAGE(children[i], MESSAGE.CONTROL_LAYOUT, <span class="keyword">new</span> <span class="keyword">boolean</span>[] <span class="scope">{</span>resize, all<span class="scope">}</span>));<br />
            <span class="scope">}</span><br />
        <span class="scope">}</span><br />
    <span class="scope">}</span><br />
<span class="scope">}</span></code></p></blockquote>
<p>Control#setBounds:</p>
<blockquote class="code"><p><code><span class="keyword">void</span> setBounds (<span class="keyword">int </span>x, <span class="keyword">int </span>y, <span class="keyword">int </span>width, <span class="keyword">int </span>height, <span class="keyword">int </span>flags, <span class="keyword">boolean</span> defer) <span class="scope">{</span><br />
    <span class="comment">/**<br />
	 * A patch to send bounds to support mirroring features like what Windows have.<br />
	 */</span><br />
    boundsSet = <span class="keyword">true</span>;<br />
    <span class="keyword">int </span>tempX = x;<br />
    <span class="keyword">if</span>(parent != <span class="keyword">null</span>)<span class="scope">{</span><br />
        <span class="keyword">if</span>((parent.style &amp; SWT.RIGHT_TO_LEFT) != 0)<span class="scope">{</span><br />
            x = Math.max(0, parent.getClientArea().width - x - width);<br />
        <span class="scope">}</span><br />
    <span class="scope">}</span><br />
    Element topHandle = topHandle ();<br />
    <span class="keyword">if</span> (defer &amp;&amp; parent != <span class="keyword">null</span>) <span class="scope">{</span><br />
        <span class="keyword">for</span>ceResize ();<br />
        WINDOWPOS [] lpwp = parent.lpwp;<br />
        <span class="keyword">if</span> (lpwp == <span class="keyword">null</span>) <span class="scope">{</span><br />
            <span class="comment">/*<br />
			* This code is intentionally commented.  All widgets that<br />
			* are created by SWT have WS_CLIPSIBLINGS to ensure that<br />
			* application code does not draw outside of the control.<br />
			*/</span><br />
<span class="comment">//			int count = parent.getChildrenCount ();</span><br />
<span class="comment">//			if (count > 1) {</span><br />
<span class="comment">//				int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);</span><br />
<span class="comment">//				if ((bits &#038; OS.WS_CLIPSIBLINGS) == 0) flags |= OS.SWP_NOCOPYBITS;</span><br />
<span class="comment">//			}</span><br />
            <span class="keyword">if</span> ((width != <span class="keyword">this</span>.width || height != <span class="keyword">this</span>.height)<br />
                    &amp;&amp; <span class="keyword">this</span> instanceof Composite) <span class="scope">{</span><br />
                display.sendMessage(<span class="keyword">new</span> MESSAGE(<span class="keyword">this</span>, MESSAGE.CONTROL_LAYOUT, <span class="keyword">null</span>));<br />
            <span class="scope">}</span><br />
            <span class="keyword">this</span>.left = x;<br />
            <span class="keyword">this</span>.top = y;<br />
            <span class="keyword">this</span>.width = width;<br />
            <span class="keyword">this</span>.height = height;<br />
            SetWindowPos (topHandle, <span class="keyword">null</span>, x, y, width, height, flags);<br />
        <span class="scope">}</span> <span class="keyword">else</span> <span class="scope">{</span><br />
            <span class="keyword">int </span>index = 0;<br />
            <span class="keyword">while</span> (index <span class="tag">&lt;</span> lpwp.length) <span class="scope">{</span><br />
                <span class="keyword">if</span> (lpwp [index] == <span class="keyword">null</span>) break;<br />
                index ++;<br />
            <span class="scope">}</span><br />
            <span class="keyword">if</span> (index == lpwp.length) <span class="scope">{</span><br />
                WINDOWPOS [] <span class="keyword">new</span>Lpwp = <span class="keyword">new</span> WINDOWPOS [lpwp.length + 4];<br />
                System.arraycopy (lpwp, 0, <span class="keyword">new</span>Lpwp, 0, lpwp.length);<br />
                parent.lpwp = lpwp = <span class="keyword">new</span>Lpwp;<br />
            <span class="scope">}</span><br />
            WINDOWPOS wp = <span class="keyword">new</span> WINDOWPOS ();<br />
            wp.hwnd = topHandle;<br />
            wp.x = x;<br />
            wp.y = y;<br />
            wp.cx = width;<br />
            wp.cy = height;<br />
            wp.flags = flags;<br />
            lpwp [index] = wp;<br />
        <span class="scope">}</span><br />
    <span class="scope">}</span> <span class="keyword">else</span> <span class="scope">{</span><br />
        <span class="keyword">if</span> ((width != <span class="keyword">this</span>.width || height != <span class="keyword">this</span>.height)<br />
                &amp;&amp; <span class="keyword">this</span> instanceof Composite) <span class="scope">{</span><br />
            display.sendMessage(<span class="keyword">new</span> MESSAGE(<span class="keyword">this</span>, MESSAGE.CONTROL_LAYOUT, <span class="keyword">null</span>));<br />
        <span class="scope">}</span><br />
        <span class="keyword">this</span>.left = x;<br />
        <span class="keyword">this</span>.top = y;<br />
        <span class="keyword">this</span>.width = width;<br />
        <span class="keyword">this</span>.height = height;<br />
        SetWindowPos (topHandle, <span class="keyword">null</span>, x, y, width, height, flags);<br />
    <span class="scope">}</span><br />
    <span class="comment">/*<br />
	 * The x coordination should be preserved, because the right to left emulation is just<br />
	 * for the view, not the data!<br />
	 */</span><br />
    <span class="keyword">this</span>.left = tempX;<br />
<span class="scope">}</span><br />
</code></p></blockquote>
<p>For more details about Java2Script's SWT Asynchronous Layout implementation, please check the sources history from SVN repository at <a href="http://j2s.svn.sourceforge.net/">http://j2s.svn.sourceforge.net/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://inside.java2script.com/2007/06/29/asynchrony-is-everything.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Browser Statistics Among Web Developers</title>
		<link>http://inside.java2script.com/2007/06/16/browser-statistics-among-web-developers.html</link>
		<comments>http://inside.java2script.com/2007/06/16/browser-statistics-among-web-developers.html#comments</comments>
		<pubDate>Sat, 16 Jun 2007 02:49:03 +0000</pubDate>
		<dc:creator>Zhou Renjian</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Browser]]></category>

		<guid isPermaLink="false">http://inside.java2script.com/2007/06/16/browser-issue.html</guid>
		<description><![CDATA[Here are some numbers about browsers used among web developers: 1. Firefox 54.63% 2. Internet Explorer 38.10% 3. Opera 3.84% 4. Safari 1.56% 5. Mozilla 1.34% Firefox versions: 1. 2.0.0.3 50.74% 2. 2.0.0.4 30.25% 3. 1.5.0.11 6.05% 4. 1.5.0.12 3.65% &#8230; <a href="http://inside.java2script.com/2007/06/16/browser-statistics-among-web-developers.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Here are some numbers about browsers used among <strong>web developers</strong>:</p>
<p>1. <strong>Firefox</strong> 54.63%<br />
2. <strong>Internet Explorer</strong> 38.10%<br />
3. <strong>Opera</strong> 3.84%<br />
4. <strong>Safari</strong> 1.56%<br />
5. <strong>Mozilla</strong> 1.34%</p>
<p>Firefox versions:<br />
1. <strong>2.0.0.3</strong> 50.74%<br />
2. <strong>2.0.0.4</strong> 30.25%<br />
3. <strong>1.5.0.11</strong> 6.05%<br />
4. <strong>1.5.0.12</strong> 3.65%<br />
5. <strong>2.0.0.2</strong> 1.88%<br />
6. <strong>2.0.0.1</strong> 1.26%<br />
7. <strong>2.0</strong> 1.26%<br />
8. <strong>1.0.7</strong> 1.26%</p>
<p>Internet Explorer versions:<br />
1. <strong>6.0</strong> 67.27%<br />
2. <strong>7.0</strong> 32.65%</p>
<p>BTW: From the latest 15 days, more and more people update their Firefox to 2.0.0.4/1.5.0.12:<br />
1. <strong>2.0.0.4</strong> 71.76% (<strong>up</strong>)<br />
2. <strong>2.0.0.3</strong> 11.11%<br />
3. <strong>1.5.0.12</strong> 8.10% (<strong>up</strong>)<br />
4. <strong>2.0.0.2</strong> 1.44%</p>
]]></content:encoded>
			<wfw:commentRss>http://inside.java2script.com/2007/06/16/browser-statistics-among-web-developers.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>QoS of JavaScript</title>
		<link>http://inside.java2script.com/2007/06/12/qos-of-javascript.html</link>
		<comments>http://inside.java2script.com/2007/06/12/qos-of-javascript.html#comments</comments>
		<pubDate>Tue, 12 Jun 2007 05:09:41 +0000</pubDate>
		<dc:creator>Zhou Renjian</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://inside.java2script.com/2007/06/12/qos-of-javascript.html</guid>
		<description><![CDATA[You must be aware of QoS when you are writing Rich Internet Application (RIA), especially when you are using AJAX. Why? And what aspects should be considered in QoS of RIA? Here are some points: 1. Loading JavaScript file *.js &#8230; <a href="http://inside.java2script.com/2007/06/12/qos-of-javascript.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>You must be aware of QoS when you are writing Rich Internet Application (RIA), especially when you are using AJAX. Why? And what aspects should be considered in QoS of RIA?</p>
<p>Here are some points:</p>
<p>1. Loading JavaScript file *.js by &lt;script&gt; tag may fail without acknowledge by the following JavaScript, which may result in a total page error;<br />
2. Loading CSS style file *.css by &lt;link&gt; tag may fail, which results in ugly page layout;<br />
3. Loading images by &lt;img&gt; tag may fail, which may confuse users;<br />
4. ...</p>
<p>The above scenarios do not occurs often in development period. Because you may using local HTTP server to serve resources, or you may have high bandwidth with slow latency. But if you deploy your applications to server, your server may be busy all the time to serve resources, and will fail to serve some resources at some uncertain time. And people may report such bugs if they are in beta tests, but people may lose their deals or money if such failures happen in real online.</p>
<p>So, QoS is required.</p>
<p>How to make sure the RIA's qualities? First, make sure that such HTTP timeouts or failures does not interrupt normal business logics. To do so, try reload resources if such failures are detected. It would be easy to reload *.js file by &lt;script&gt; tag, or other resources by other tags. In order to detect failures, you may have your own loader. This is the reason <a href="http://inside.java2script.com/2007/05/22/classloader-summary.html">why there is ClassLoader in Java2Script</a>. To detect failures is also easy. Just hook the onerror or onreadystatechange event of loading JavaScript. Or you can setup a thread looping to check whether a *.css or an image is loaded or not.</p>
<p>There are other QoS aspects. Stay tuned for more coming discussions.</p>
]]></content:encoded>
			<wfw:commentRss>http://inside.java2script.com/2007/06/12/qos-of-javascript.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Compressing and Deploying JavaScript</title>
		<link>http://inside.java2script.com/2007/06/05/compressing-and-deploying-javascript.html</link>
		<comments>http://inside.java2script.com/2007/06/05/compressing-and-deploying-javascript.html#comments</comments>
		<pubDate>Tue, 05 Jun 2007 15:35:59 +0000</pubDate>
		<dc:creator>Zhou Renjian</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://inside.java2script.com/2007/06/05/compressing-and-deploying-javascript.html</guid>
		<description><![CDATA[For AJAX, deploying JavaScript files may be important for you or not. If you are professional in AJAX, you must know the details of JavaScript deployment. First, you can compress your JavaScript files before deploying them. Common compressors may cut &#8230; <a href="http://inside.java2script.com/2007/06/05/compressing-and-deploying-javascript.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For AJAX, deploying JavaScript files may be important for you or not. If you are professional in AJAX, you must know the details of JavaScript deployment.</p>
<p>First, you can compress your JavaScript files before deploying them. Common compressors may cut 50% off of file size for normal JavaScript. That is to say, if your packed *.js is about 100k, the compressed *.js may be 50k. The compressed *.js may take about 100ms to decompress, but it when comparing to 50k over 1Mb/s bandwidth ( 50k * 8 / 1M = 0.4 s = 400ms). It worths such compressing. Usually bandwidth is not quite good as 1Mb/s, it will much better for compressed JavaScript.</p>
<p>Some well-known JavaScript compressors are <a href="http://dean.edwards.name/packer/">Dean Edwards' Packer</a> and <a href="http://alex.dojotoolkit.org/shrinksafe/">Shrink Safe by Alex at Dojo</a>. You may find some other compressors, like <a href="http://demo.java2script.org/lz77js/">Java2Script's LZ77 JavaScript Compressor</a>.</p>
<p>Second, you can send out your JavaScript files as gzip-encoded by Apache server. For most of modern browsers, gzip-encoding can be accepted. So you should configure your Apache server to do so especially when your JavaScript is over 200k. In common cases, gzip-encoding saves over 75% of JavaScript bandwidth. That is to say, 200k JavaScript only takes up 50k transmission. What a great improvement.</p>
<p>But please pay attention to some defects of JavaScript gzip-encoding for some browsers, like IE. Well, Internet Explorer takes up 80%+ of browser shares. You must not ignore <a href="http://support.microsoft.com/kb/321722/EN-US/">IE's defects on dealing JavaScript gzip-encoding</a>. As IE6.0 SP2 and IE7+ already fixed this bug. You should support these two browsers, as it may get more and more market share.</p>
<p>So when configure .htaccess file for Apache httpd server, you should ignore those buggy IE browser or non-supported browsers. Here is my .htaccess file:</p>
<blockquote class="code"><p><code>&lt;IfModule mod_deflate.c&gt;<br />
    # Netscape 4.x or IE 5.5/6.0<br />
    BrowserMatch ^Mozilla/4 no-gzip<br />
    # IE 5.5 and IE 6.0 have bugs! Ignore them until IE 7.0+<br />
    BrowserMatch \bMSIE\s7 !no-gzip<br />
    # IE 6.0 after SP2 has no gzip bugs!<br />
    BrowserMatch \bMSIE.*SV !no-gzip<br />
    # Sometimes Opera pretends to be IE with "Mozila/4.0"<br />
    BrowserMatch \bOpera !no-gzip<br />
    AddOutputFilterByType DEFLATE text/css text/javascript application/x-javascript<br />
    Header append Vary User-Agent<br />
&lt;/IfModule&gt;</code></p></blockquote>
<p>For more information about this gzip-encoding configuration, please <a href="http://www.google.com/search?q=IE+gzip+javascript+encoding">google "IE gzip javascript encoding"</a> or read <a href="http://blog.joshuaeichorn.com/archives/2007/01/10/compressing-javascript-and-css/">Joshua Eichorn's blog article "Compressing JavaScript and CSS"</a>.</p>
<p>Third, this is still about gzip-encoding. But this method tries to include JavaScript in HTML sources directly. As IE has no bugs on decoding gzip-encoded HTML files, compress JavaScript in this way will suite for most IE6 users. As far as I know, <a href="http://code.google.com/webtoolkit/">GWT</a> uses this way to send out their JavaScript. But loading those HTML files in an embed IFRAME may make the whole architecture a little strange or hard to understand. Few people uses this method.</p>
<p>Maybe there are some other ways to compress and deploy JavaScript. Please let me know or discuss with me if you have a new one.</p>
]]></content:encoded>
			<wfw:commentRss>http://inside.java2script.com/2007/06/05/compressing-and-deploying-javascript.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Packing in Java2Script</title>
		<link>http://inside.java2script.com/2007/06/04/packing-in-java2script.html</link>
		<comments>http://inside.java2script.com/2007/06/04/packing-in-java2script.html#comments</comments>
		<pubDate>Mon, 04 Jun 2007 14:34:59 +0000</pubDate>
		<dc:creator>Zhou Renjian</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Hacks]]></category>

		<guid isPermaLink="false">http://inside.java2script.com/2007/06/04/packing-in-java2script.html</guid>
		<description><![CDATA[Usually, when you develop new features, you split functions into pieces and implement them one by one. And in Java development, there will be implemented by one *.java file and another. If you want to deploy the finished feature, you &#8230; <a href="http://inside.java2script.com/2007/06/04/packing-in-java2script.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Usually, when you develop new features, you split functions into pieces and implement them one by one. And in Java development, there will be implemented by one *.java file and another. If you want to deploy the finished feature, you need to pack them up.</p>
<p>In Java development, deployment means that you need to pack compiled *.class files and other related resource files into a *.jar and place it to correct location. There are lots of tools to do this job. Or if you are using IDE, such as Eclipse, the IDE will provide a whole development life management tools for you.</p>
<p>In JavaScript world, tools are rare. And for the loading speed and performance considerations, packing JavaScript and deploy them need your attentions.</p>
<p>Small *.js file should be packed into some bigger *.js file. But each *.js file should not be too big, or each time you update only one small *.js, you have to update a big *.js file. But *.js files should not be too many. Because *.js files are downloaded from servers in some specific orders, two many *.js files may be queued, which may mean a long latency. Lots of *.js compiled from *.java by Java2Script compiler is very small. In order to get a shorter loading time, most of these *.js files are packed into a big *.z.js file. Please check out the <a href="http://j2s.svn.sourceforge.net/viewvc/j2s/trunk/sources/net.sf.j2s.lib/build/build.xml?view=markup">packing ant script</a>. But packing *.js into a big *.z.js is not a simple job in Java2Script. As there is ClassLoader inside Java2Script system. The packed *.z.js file must be dealt correctly by ClassLoader. This issue is very complicate. And I would like to talk about it in another post.</p>
<p>Small size images can be packed into a bigger size one two. This is especially useful if there are icons for tool-bar. When a small icon needed, just display the big image with given position and size. This trick is a CSS tip. For example, create a DIV block with size 16x16, and set its style with some background image started from given position:</p>
<blockquote class="code"><p><code>&lt;div style="width:16px; height:16px; background-image:url(big.gif); background-position:16px 32px; background-repeat:no-repeat;"&gt;&lt;/div&gt;</code></p></blockquote>
<p>"background-position:16px 32px;" means the icon place at the 2nd row, the 3rd column. That is the image packing trick. Java2Script SWT implementation uses these tricks, you can check the <a href="http://j2s.svn.sourceforge.net/viewvc/j2s/trunk/sources/net.sf.j2s.java.org.eclipse.swt/src/org/eclipse/swt/widgets/Shell.css?view=markup">Shell.css</a>. In there, there are no absolute positions but relative positions, such as "center right". This is because 9 icons are packed as 3x3 squares.</p>
<p>Small *.css can also be packed into a big *.css files too. But in practices of Java2Script packing, *.css files are packed into *.js files. All *.css files are only applied when necessary. For example, when a widget is loaded, the widget related *.css rules are applied to the page so that widget may be in correct style. For this trick, please check <a href="http://j2s.svn.sourceforge.net/viewvc/j2s/trunk/sources/net.sf.j2s.java.org.eclipse.swt/src/org/eclipse/swt/package.js?view=markup">Java2Script CSS hacks</a>.</p>
<p>And there are also some other packing tricks which I may introduce later. As packing is for deployment. And deployed resources are for loading. And loading will affect the whole object oriented inheritance simulator. And things are a whole integrated system.</p>
]]></content:encoded>
			<wfw:commentRss>http://inside.java2script.com/2007/06/04/packing-in-java2script.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Asynchronous Programming</title>
		<link>http://inside.java2script.com/2007/06/03/asynchronous-programming.html</link>
		<comments>http://inside.java2script.com/2007/06/03/asynchronous-programming.html#comments</comments>
		<pubDate>Sun, 03 Jun 2007 14:58:44 +0000</pubDate>
		<dc:creator>Zhou Renjian</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Hacks]]></category>

		<guid isPermaLink="false">http://inside.java2script.com/2007/06/03/asynchronous-programming.html</guid>
		<description><![CDATA[In my early Java2Script development days, I think a lot about asynchronous programming. AJAX was hot and is still hot. What is most important factor in AJAX technologies? I think it is "Asynchronous". Without asynchronous programming, visitors still need to &#8230; <a href="http://inside.java2script.com/2007/06/03/asynchronous-programming.html">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In my early Java2Script development days, I think a lot about <a href="http://j2s.sourceforge.net/blog/2006/02/04/asynchronous-programming/">asynchronous programming</a>. AJAX was hot and is still hot. What is most important factor in AJAX technologies? I think it is "Asynchronous". Without asynchronous programming, visitors still need to waste their time waiting for browser to fetch the next page. What a bad user experience.</p>
<p>In fact, asynchronous programming is not an easy work. Lots of callbacks, lots of threads, lots of locks or semaphores. All these stuffs may be messed up into an unmaintainable geeky thing.</p>
<p>Actually, if there are tools helping to design and maintain such codes, it is not a big job. If you use Java, you won't get stuck at those threads of synchronized locks, as lots of debug tools help you figure out how those things work together at any moment you want to take a look. In fact, there are lots asynchronous programmings in Java design patterns or codes. But in Java world, asynchronous programming is not an outstanding features, and it is seldom discussed as an important issue.</p>
<p>But in JavaScript world, in browser world, asynchronous programming is a huge thing. In JavaScript (also known as EMCAScript)? language specification, there are no threads, no semaphores, no locks. All things are designed in synchronized mode. And before AJAX was hot, there are no robust tools for developers to write and debug JavaScript. If JavaScript sources file size exceeds 100K, it would be a hard-ass job to maintain. And if there are 3 layers of callbacks, it would drive developers crazy to develop new features. From my early experience, I designed a web form with digital signature functions, I used Java Applet in the back-end and used AJAX-style dialogs. And in oder to make a correct call from dialogs to Java Applet, its parameters may be passed through about 4-6 callback layers, because there are security issues over JavaScript calling Java Applet and Java Applet's own sandbox mechanism. At that time, I sometimes found myself at the peak of being crazy or being collapsed.</p>
<p>So as I explain, asynchronous programming is not funny. And we would like to accept synchronous programming. Now let's take a look at those Java synchronous programming which need to be JavaScript asynchronous programming:</p>
<p>Java snippet:</p>
<blockquote class="code"><p><code>Display display = Display.getDefault();<br />
SimpleSWTRPC shell = <span class="keyword">new</span> SimpleSWTRPC(display, SWT.SHELL_TRIM);<br />
shell.open();<br />
shell.layout();<br />
<span class="keyword">while</span> (!shell.isDisposed()) <span class="scope">{</span> <span class="comment">// waiting loop</span><br />
    <span class="keyword">if</span> (!display.readAndDispatch())<br />
        display.sleep();<br />
<span class="scope">}</span><br />
<span class="comment">// continue other codes...</span></code></p></blockquote>
<p>But in JavaScript, the above waiting loop will use up all CPU times and freeze browser. So such waiting loop must be avoided. And callback mechanism is used:</p>
<blockquote class="code"><p><code><span class="keyword">var</span> display = $wt.widgets.Display.getDefault ();<br />
<span class="keyword">var</span> shell = <span class="keyword">new</span> org.java2script.demo.simplerpc.SimpleSWTRPC (display, 1264);<br />
shell.open ();<br />
shell.layout ();<br />
Sync2Async.block (shell, <span class="keyword">this</span>, <span class="keyword">function</span> () <span class="scope">{</span><br />
                <span class="comment">// continue other codes...</span><br />
        <span class="scope">}</span>);</code></p></blockquote>
<p>The above codes use Sync2Async technology. Such technologies have lots of defects. The biggest defect is that it can not stop browser to execute the following codes outside the method closure. For example, if the above codes are in method #openUpDialog, and in another method say #setUp call this method and then call other methods:</p>
<blockquote class="code"><p><code>this.openUpDialog();<br />
this.checkState();<br />
this.sendOutRequest();</code></p></blockquote>
<p>When the above codes are executed in Java mode, #checkState and #sendOutRequest will never be called until user closes the dialog. But in JavaScript Sync2Async mode, the callback technology can not block browser from executing #checkState and #sendOutRequest, which may result in incorrect result. This is the key defect of Sync2Async technology. Even though it has defects, such technology helps developes a lots for some simple tasks.</p>
<p>In order to fulfill some complicate task, designers should design the whole architecture as asynchronous programming patter from the beginning. Even in Java language, all things in asynchronous mode are still difficult.</p>
<p>More should be discussed for this issue.</p>
]]></content:encoded>
			<wfw:commentRss>http://inside.java2script.com/2007/06/03/asynchronous-programming.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

