<?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>PawaStation 能猫环岛 &#187; gds</title>
	<atom:link href="http://blog.pawa.ca/tag/gds/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.pawa.ca</link>
	<description>An Apple a Day Keeps the Doctor Away</description>
	<lastBuildDate>Sun, 08 Mar 2009 04:39:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>AMF3 Integer/Number 与 GDS</title>
		<link>http://blog.pawa.ca/2007/11/24/amf3-integernumber-gds/</link>
		<comments>http://blog.pawa.ca/2007/11/24/amf3-integernumber-gds/#comments</comments>
		<pubDate>Sat, 24 Nov 2007 07:42:24 +0000</pubDate>
		<dc:creator>pawaca</dc:creator>
				<category><![CDATA[tips]]></category>
		<category><![CDATA[amf]]></category>
		<category><![CDATA[gds]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.pawa.ca/?p=49</guid>
		<description><![CDATA[AMF3 里面的 integer 类型使用 4 bytes 来传输，但是是以一种诡异的形式，摘 osflash 上的一段描述： Integer-data is probably the single most used item in AMF3. To save space it is an integer that can be 1-4 bytes long. The first bit of the first three bytes determine if the next byte is included (1) in this integer-data or not (0). The [...]]]></description>
			<content:encoded><![CDATA[<p><span class="caps">AMF3 </span>里面的 integer 类型使用 4 bytes 来传输，但是是以一种诡异的形式，摘 <a href="http://osflash.org/documentation/amf3">osflash</a> 上的一段描述：</p>

<blockquote><p>Integer-data is probably the single most used item in <span class="caps">AMF3.</span> To save space it is an integer that can be 1-4 bytes long. The first bit of the first three bytes determine if the next byte is included (1) in this integer-data or not (0). The last byte, if present, is read completely (8 bits). The first bits are then removed from the first three bytes and the remaining bits concatenated to form a big-endian integer. </p></blockquote>

<p>这里的重点是：为了省地方， amf3 的 integer 牺牲了部分范围，只能表示 -268435456(int.MIN_VALUE»3) 到 268435455(int.MAX_VALUE»3) 范围内的数。</p>

<p>这引出了一个问题，如果在 java 中一个 integer 的数值大于 amf3 可允许的范围传输的时候怎么办？ survey 了一些 implement 代码，发现这种时候会用范围更大的 8 bytes number 类型来传输。</p>

<p>[分隔线若干条...]</p>

<p>最近程序 (Flex + <a href="http://www.graniteds.org"><span class="caps">GDS</span></a> + Hibernate + 其他) 被 User 用出一个神秘的 exception： </p>

<blockquote><p>javax.persistence.PersistenceException: org.hibernate.TypeMismatchException: Provided id of the wrong type. Expected: class java.lang.Integer, got class java.lang.Double </p></blockquote>

<p>由于无法 reproduce，我就把他当成了灵异事件，没有理会。没想到这个不着调的 exception 竟然在昨天出现在朕的面前！经过 3.765 秒的分析和 4.132 秒的 survey 终于发现了问题的根源。（深吸一口气）原来是有一个 proxy entity 的 id 超过了 amf integer 可允许的最大范围，这个从 java 传到 flex 还没什么问题，但是回传会来的时候由于 <span class="caps">GDS </span>将 amf number 读成 double 所以造成 id 类型为 double，但实际上这个 id 被声明为 integer，所以在就出现了上面那个 exception （吐气&#8230;）</p>

<p>有趣的是，只有当 entity 是 hibernate proxy 的时候才会出现这个问题。看来是 <span class="caps">GDS </span>某个地方写的有问题，在代码里游啊游，发现了这段：</p>

<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">// /graniteds/hibernate/org/granite/hibernate/HibernateProxyInstanciator.java</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> readId<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobjectinput+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">ObjectInput</span></a> in<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aioexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">IOException</span></a>, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aclassnotfoundexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">ClassNotFoundException</span></a> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">id</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aserializable+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Serializable</span></a><span style="color: #009900;">&#41;</span>in.<span style="color: #006633;">readObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>

<p>上面的这个代码是从 svn 的 trunk 上粘下来的，看来这个问题还没改&#8230;（没被发现？）</p>

<p>总之，如果有谁不幸中招，可以试试 <a href="http://blog.pawa.ca/wp-content/uploads/2007/11/hibernate_patch.txt">apply 这个 patch</a> 到 /graniteds/hibernate/org/granite/hibernate/HibernateProxyInstanciator.java 。</p>

<p>Over</p>]]></content:encoded>
			<wfw:commentRss>http://blog.pawa.ca/2007/11/24/amf3-integernumber-gds/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
