tag:blogger.com,1999:blog-363102072024-02-28T01:11:05.707-05:00A Developer's NotesUnknownnoreply@blogger.comBlogger35125tag:blogger.com,1999:blog-36310207.post-11496924681702188582012-03-16T22:30:00.003-04:002012-03-17T00:13:05.821-04:00What is AtomicReference for really?we had a discussion about AtomicReference at work the other day, it appears that none of us really understand why we should use AtomicReference based on a quick glimpse at the java doc provided.<br /><br />The confusion comes from that we all firmly believe reference assignment is atomic in java, so why both with AtomicReference.<br /><br />I decided to do some research on it and found this great post: <a href="http://stackoverflow.com/questions/3964317/memory-barriers-and-coding-style-over-a-java-vm/3964347#3964347">Memory Barriers</a>. It looks like there are several benefits of using AtomicReference.<br /><br />Internally AtomicReference marks the value <span style="font-weight: bold;">volatile</span>, which creates a memory barrier that a, makes sure no thread is reading out dated data, b, provides happens-before guarantee because your code won't be reordered by compiler. If you only use the get/set method of AtomicReference, you are essentially marking your variable volatile in a fancy way.<br /><br />The other interesting method is compareAndSet(expected, newVal). With care, AtomicReference can be used as an efficient way to do synchronization, especially when concurrent change happens rarely. to do this, the thread calls compareAndSet instead of set. If it fails, then it means that the value had been updated, so this thread has to deal with the conflict, such as abandon its change, overwrite, or merge.<br /><br />In summary, AtomicReference differs from other atomic types in the concurrency package that it doesn't offer the typically desired atomic action like getAndIncrement, but they are similar that they all provide compareAndSet methods.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-4739652591265546282011-04-26T22:33:00.006-04:002011-05-04T20:56:15.403-04:00content assist issue in Flash Builder eclipse pluginI had some rough time trying to get standalone flash builder version 4 to work with Java code and Tomcat. After hours of scratching my head, I gave up. It just shouldn't be this hard. But if you are adventurous enough to give it a try, here is a great tutorial you may want to read first: <a href="http://flashworks.wordpress.com/2011/03/25/java-flex-blazeds-project-solving-issues-with-flash-builder-4-stand-alone/">http://flashworks.wordpress.com/2011/03/25/java-flex-blazeds-project-solving-issues-with-flash-builder-4-stand-alone/<br /></a><br />So my next logical step is to install flash builder plugin to an eclipse installation. I know eclipse pretty well so the java/maven/wtp/tomcat parts went smooth without any drama. Flash builder plugin installed fine. And I was able to import flex projects and tweak the class path to make it build. The only thing missing in this setup is content assist, where I don't get code complete, API suggestions, or open declaration (F3) etc.<br /><br />After two days of suffering without content assist and numerous googling, I finally found this great discussion which gave me a pointer to get it fixed. :)<br /><a href="http://forums.adobe.com/thread/694803">http://forums.adobe.com/thread/694803</a><br /><br />The culprit: <span style="font-weight: bold; font-style: italic;">Flash Builder doesn't work well with m2eclipse. Importing flex project as maven project confused the crap out of flash builder.</span><br />So what I end up doing is to start with clean project checkout, then in eclipse, create a new flex project with the same name as the checked out project, uncheck the "default project location" and point it to where the project is checked out. then tweak the src folder and build path to make the new project look just like "we imported it from the SCM checkout". After that content assist works like a charm.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-36617754767164363792011-03-14T22:58:00.002-04:002011-03-14T23:03:39.978-04:00NavigableMap in JDK6JDK6 introduced <i>NavigableMap</i> and retro-fitted TreeMap to implement this interface. I was a bit confused at first about <i><b>ceilingKey</b></i> vs <i><b>higherKey</b></i> and <i><b>floorKey</b></i> vs <i><b>lowerKey</b></i>. It turns out that floor and ceiling operations can return <b>equal</b> entries, while higher and lower operations must be <b>strictly</b> less than or greater than. <div><br /></div><div>Nice features. I can definitely find some uses for them. :)</div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-56504505266008697042010-11-23T09:20:00.006-05:002010-11-27T21:42:42.454-05:00Use compiler to catch new enum value not covered in "switch"This old trick shines more and more when our project's code base grew over million+ lines. I have to put it on the web one more time just in case there is a developer out there haven't seen this.<br /><br />Basically you can set the compiler to generate compilation errors when there are enum values not covered in switch block. So that when a new value is added to an enum class, every switch statement on this enum class will get a compilation error. This way it is easier to find and add corresponding cases, and it is impossible to ignore them. :)<br /><br />To make this work, you have to do (or not do) two things:<br /><ol><li>DO NOT use "default" case when you do switch on enum values.</li><li>Set your compiler to generate ERROR instead of ignore enum values not covered in switch. In eclipse (the greatest IDE), it is here:<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3TL4ylpBqPCT748YETCqoudHDKJeGuzwr5oOoNZ546fGd6eYxRcDty0qWTG1-N1d5qgJDWkbrMIGVQG4teSGszQE9J8pyncE-o8UGYgErpp1nOw0QaWBoU4Bh52uiu9H8-y1W/s1600/enum-switch.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 244px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3TL4ylpBqPCT748YETCqoudHDKJeGuzwr5oOoNZ546fGd6eYxRcDty0qWTG1-N1d5qgJDWkbrMIGVQG4teSGszQE9J8pyncE-o8UGYgErpp1nOw0QaWBoU4Bh52uiu9H8-y1W/s320/enum-switch.png" alt="" id="BLOGGER_PHOTO_ID_5544425445216913394" border="0" /></a></li></ol>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-57621282192626404612010-02-25T18:36:00.003-05:002010-02-25T20:57:43.724-05:00hey gmail, what is up? I am a little worried about you.I am a loyal fan of gmail ever since its first beta version. I jumped all over the web to get an invitation back in 2004. A couple years ago when my geeky friends switched their companies' email system to gmail, I was a supporter too.<br /><br />But a couple things happened recently, which made me not so sure no more. Starting later last year I began to receive emails sent to another address that I had no relation with. Apparently gmail is forwarding others email into my inbox, all junk though. But if it is doing this, how do I know it is not forwarding my email to others?<br /><br />Another hiccup happened this week. I pop emails from several alias accounts. And mails start showing up late, 2 or 3 days late, as a consequence I wasn't able to get back to people in time.<br /><br />Google pretty much runs my life. I wish the best for them. But with the buzz burns still all over the web, this kind of misbehaviours on email application is worrisome. Even the giant can bite more than it can chew, sometimes. So this is a shout out to the gmail team, check it out.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-36310207.post-46001827870816944042010-02-16T21:18:00.003-05:002010-02-16T21:30:08.704-05:00JBoss Tools Eclipse plugin content assist lessonsI learned a couple lessons in the process of making JBoss Tools Eclipse plug-in to do content assist (where you type ctrl-space to get code suggestions). This is mostly about JSF component libraries.<br /><br />First of all, in order to get content assist for JSF components, you must have the TLD file in your class path. We are using Richfaces libraries, and all its components get content assist. The ones I had trouble with are jsf-core and jsf-html, the f: and h: tags by default. Oddly enough though, with all the JSF libraries I have on my class path, none of them had packaged the TLDs for these two. I made a jar file and put jsf-core.tld and jsf-html.tld in the META-INF folder to get this working.<br /><br />Another lesson learned is that the name space URI has to match exactly with the TLD's. I mean exactly. Kind of obvious, but easy to miss when trouble shooting. I added Openfaces like this <span style="font-weight: bold; font-style: italic;">xmlns:o="http://openfaces.org"</span> in the first place and it didn't work, because it is expecting a "/" at the end. So the correct syntax is <span style="font-style: italic; font-weight: bold;">xmlns:o="http://openfaces.org/"</span>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-36310207.post-33019064523757019662010-02-14T23:12:00.003-05:002010-02-14T23:45:48.383-05:00Build Synergy in a new ubuntu systemHad to jump through quite a few hoops to get synergy to compile on a fresh ubuntu 9.10 box, including gcc-cpp and libxtst stuff. The most annoying error message is the 'You must have the XTest library to build synergy' one, it just won't go away after I got all the xtest, libxtst, libxest, libxcb-xtest crap installed.<br /><br />Well, here is all it takes: (copied from synergy-plus)<br /><textarea name="code" class="xml">sudo apt-get install cmake python g++ make xorg-dev</textarea><br />By the time I figured this out, I already moved on to synergy-plus, which is much easier.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-6036399249021709642010-01-28T15:51:00.003-05:002010-01-28T16:06:10.709-05:00jQuery goodies that I will try in next projectjqGrid, the data grid plugin with editing, searching, paging, and a lot more features<br />http://www.trirand.com/blog/?page_id=5<br /><br />iconDock, good idea to put a bunch of icon/buttons on the page<br />http://icon.cat/software/iconDock/0.8b/dock.html<br /><br />Horizontal Accordion, just cool<br />http://www.portalzine.de/index?/Horizontal_AccordionUnknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-16483936310329038892009-12-15T22:12:00.002-05:002009-12-15T22:42:33.980-05:00jboss tools 3.1M4 code assist/content assist not working with JSF core and html?I was playing with jboss tools 3.1M4 and only found out that I am not getting content assist (CA) for the JSF core and html tags. All other namespaces work fine, like richfaces, seam, ajax4jsf etc. How could that be?<br /><br />My first thought was that the TLDs for core and html are missing. So I manually added the core and html XSD into the XML catalog, restarted eclipse, didn't do it.<br /><br />Next I found a couple wiki pages (<a href="http://community.jboss.org/wiki/NewKBplug-inandCodeAssistinJBossTools310M3">here</a> and <a href="http://community.jboss.org/wiki/CodeAssistinJBossToolsXMLandJSPXHTMLEditors">here</a>) talking about how content assist works in jboss tools 3.1. They are good how-to but not helping me out. I was ready to dive into the source code and examine the Knowledge Base CA processors.<br /><br />Then something stroked my mind: is it because my project is not considered JSF projects? I right clicked my project and in the Jboss Tools menu selected "Add JSF Capabilities...", and voila, that made all the difference.<br /><br />I spent about 3 hours trying to figure this out. This reminds me again: more often than not the solution is much simpler than one imagined.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-43933399277290129712009-09-24T11:03:00.003-04:002009-09-24T11:11:00.115-04:00keep aventail vpn working after kernal upgradeI made aventail vpn client working a while back, here is the note I made.<a href="http://a-developers-notes.blogspot.com/2009/05/aventail-vpn-under-kubuntu-904-fixed.html"><br />http://a-developers-notes.blogspot.com/2009/05/aventail-vpn-under-kubuntu-904-fixed.html</a><br /><br />But after each kernel update, the client will break due to the new kernel comes with a newer version of the openssl library.<br /><br />Luckily the aventail client is looking for a specific version of ssl library, 0.9.7 being specific. so it is easy to make it work again. Here are the scripts:<br /><textarea name="code" class="java"><br />cd /usr/lib<br />sudo rm ./libcrypto.so.0.9.7<br />sudo ln -s /usr/local/ssl/lib/libcrypto.so.0.9.8 ./libcrypto.so.0.9.7<br />sudo rm ./libssl.so.0.9.7<br />sudo ln -s /usr/local/ssl/lib/libssl.so.0.9.8 ./libssl.so.0.9.7<br /></textarea><br />Voila, got vpn client again!Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-77402154228804502842009-05-19T23:23:00.002-04:002009-05-20T00:32:13.410-04:00aventail vpn under k/ubuntu 9.04 fixedJust fixed my vpn issue with kubuntu 9.04. Actually the solution is not limited to k/ubuntu, google results showed that several other distros have the same issue too.<br /><br />The symptom: through the web client, I am able to login, get web access, then get web and client/server access, but the Aventail OnDemand Tunnel shows status error, without any details. Or in the binary console client, you got DoHandShake Failed message<span style="font-family: monospace;"></span>.<a href="http://just-another.net/2008/11/20/ubuntu-intrepid-and-aventail-ssl-client/"><br /><br />Ben Smith got a great post</a> which eventually helped me solve my issue. Several points to watch out:<br /><ol><li>Most importantly, try to compile different versions of openssl if one version didn't work, not necessarily a newer version. I started with 0.9.8g, then tried 0.9.8k without luck, then tried 0.9.8i and it worked. Dont ask why becuase it's way over my head.<br /></li><li>Make sure your aventail binary client's version matches your vpn server's version<br /></li></ol>Hat off to Ben, :)Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-36310207.post-6766597300917629152009-01-29T09:59:00.002-05:002009-01-29T10:03:41.662-05:00JSF converter implementation notesSEAM's built-in converters are big time-savers, especially the s:convertEntity and s:convertEnum. Now the needs of rolling out customized JSF converters are few and far between, I just want to jot down the patterns I had used in case I forget.<br /><ol><br /><li>take the entity's primary ID as string, and load it from persistence media by ID to convert back to object</li><br /><li>implement an algorithm that can encode the object into a unique string, and reconstruct the object by parsing the string</li><br /><li>Construct a map of strings and objects. Because converters are instantiated on demand, you have to save the map in a backing bean whose life-cycle spans over requests. The map is nested in the h:selectOneMenu component using f:attribute tag, so that the converter can get a handle of it.<br /><textarea name="code" class="xhtml"><br /><h:selectOneMenu id="dropDown" value="#{bean.selectedOption}"><br /> <s:selectItems value="#{beanManager.options}" var="o" label="#{o.label}"/><br /> <f:attribute name="options" value="#{beanManager.options}"/><br /> </h:selectOneMenu><br /></textarea><br /></li><br /></ol>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-45361673766905581952009-01-29T00:25:00.005-05:002009-04-07T17:25:44.253-04:00SEAM Howto - end conversation and go back to the previous pageIn web application it is often desirable to provide a "Cancel" button in a function area which will redirect the user back to the page they come from.<br /><br />In SEAM if the function area is wrapped by a conversation, then there are two ways to archive this navigation effect, depending on whether or not you need to do clean up when ending the conversion.<br /><br />If there is no clean up to be done, you can use s:link or s:button as shown in the example below. The action is invoked first. The view attribute is rendered if redirect did not happen after the action invocation.<br /><textarea name="code" class="xml"><br /><s:button value="Cancel" action="#{conversation.endAndRedirect}" view="/defaultPage.xhtml"></s:button><br /></textarea><br />If there is clean up to be done, you can archive this in pages.xml file with a navigation hack.<br /><pre name="code" class="xml"><br /><h:commandbutton value="Cancel" action="#{backingBean.cleanup}"></h:commandbutton><br /></pre><br />In your pages.xml:<br /><textarea name="code" class="xhtml"><br /><navigation from-action="#{backingBean.cleanup}" evaluate="#{conversation.endAndRedirect}"><br /> <rule outcome="false"><br /> <redirect id="/defaultPage.xhtml"></redirect><br /> </rule><br /></navigation><br /></textarea>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-48798163515932525292008-06-03T12:21:00.003-04:002008-06-03T13:24:33.330-04:00upgrade JBoss Tools from 2.0.1 to 2.1.0Since JBoss Tools is a drop in plugin, you just copy the files into eclipse/plugin folder to install, I wasn't able to figure out how to remove the old version. It may not matter to eclipse but it just doesn't feel right to have multiple versions hang around. I know you can switch back and forth among different versions. But how often do you switch back? Plus eclipse is not able to recognize 2.1.0 of JBoss Tools anyways.<br /><br />After fiddling with eclipse plugin management UI for a bit, I lost my patient and went with the brutal force:<br /><blockquote><br />cd eclipse/plugin<br />ls -d org.jboss.tools.* | grep 2.0.1.GA | xargs rm -rf<br /></blockquote>So far so good. Everything is still working.<br /><br />Please comment if you have a better way to upgrade JBoss Tools.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-42163871311867714842008-05-29T23:41:00.005-04:002008-05-29T23:58:01.934-04:00screen resolution for k/ubuntu 8.0.4 hardy heron running on virtualboxJust fixed a resolution issue for my ubuntu hardy heron guest system running in virtual box (host is kubuntu 8.0.4). The solution is based on this thread.<br /><br />There are two things I changed in xorg.conf to make it work:<br /><ol><li>find the video driver device second and add <span style="font-style: italic;">Driver "vboxvideo". see following:<br /></span><pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 2px; padding: 6px; overflow: auto; text-align: left;">Section "Device"<br /> Identifier "Configured Video Device"<br /> Driver "vboxvideo"<br />EndSection</pre><br /></li><li>find the screen section and add a display subsection including the modes.<br /><pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 2px; padding: 6px; overflow: auto; text-align: left;">Section "Screen"<br /> Identifier "Default Screen"<br /> Monitor "Configured Monitor"<br /> Device "Configured Video Device"<br /> SubSection "Display"<br /> Modes "1280x800" "1024x768" "800x600"<br /> EndSubSection<br />EndSection</pre></li></ol>Voila! it works. The only drawback is that the auto-resize guest display function of virtual box doesn't work.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-41385767777595294802008-05-29T17:54:00.003-04:002008-05-29T18:02:16.293-04:00starting vmware server on ubuntu 8.0.4 hardy heronIt wasn't an easy task to get vmware server installed on my kubuntu 8.0.4 box with kernel 2.6.24-17. And after jumping through all those hoops and firing up vmware, I cannot start any virtual machined created. The message I am getting is: Unable to change virtual machine power state: The process exited with an error: End of error message.<br /><br />After a couple fruitless google searches, I saw a post mentioning about the debug information. Then I went to "edit virtual machine settings" -> "options" -> "advanced" and enabled the "run with debug infor" option. Hah, I got the actual error right away.<br /><br />It turned out to be that I installed the vmware server with "sudo" and it created a ".vmware" folder in my home folder with root:root permission. Changing the permission fixed my issue.<br /><br />Ehh.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-9955395680991455952008-03-31T09:55:00.001-04:002008-03-31T09:57:56.764-04:00join lines in Eclipse 3.3Many times a day when formatting/re-factoring code I join the next line of code to the end of current line. If it is java code, you can do ctrl-delete twice then insert a white space in between two lines. If it is xhtml file, two ctrl-delete will remove the opening tag of next line (at least in JBoss Tools editor), so a lot of times I just type delete key as fast as I can, Yuk. I cannot tell how much I miss 'J' in vi to join lines.<br /><br />NOW in Eclipse 3.3, a new (new to me) shortcut ctrl-alt-j will do exactly what 'J' does in vi, joining two lines and put a white space in between. Command-alt-j on mac.<br /><br />Try it and you will like it.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-90122025547986941282008-03-20T15:31:00.006-04:002008-03-20T15:48:32.462-04:00Using SEAM i18n support to externalize stringsSEAM brings support of i18n in JSF applications to a whole new level. It is another show case of "convention over configuration" design philosophy. But its documentation misled me a little bit.<br /><blockquote></blockquote><blockquote>By default, the resource bundle used by Seam is named <tt class="literal">messages</tt> and so you'll need to define your labels in files named <tt class="literal">messages.properties</tt>, <tt class="literal">messages_en.properties</tt>, <tt class="literal">messages_en_AU.properties</tt>, etc. These files usually belong in the <tt class="literal">WEB-INF/classes</tt> directory.</blockquote>By reading this paragraph, I thought that when all you want is to externalize some labels/strings in your application, you can just throw a file named <span style="font-size:85%;"><span style="font-style: italic;">messages.properties</span></span> then start referencing resources using <span style="font-size:85%;">messages</span> built-in component. It didn't work like that.<br />I also tried to force loading the resource bundle using tag <span style="font-size:85%;"><span style="font-style: italic;">core:resource-loader</span><span style="font-style: italic;"><core:resource-loader></core:resource-loader></span><span style="font-style: italic;"><core:resource-loader></core:resource-loader></span></span> in <span style="font-size:85%;"><span style="font-style: italic;">components.xml</span></span> file. It didn't work either.<br />Finally it turned out that you got to put the locale string in your file name although you don't care about locale at all. In my case I just renamed my file as <span style="font-size:85%;"><span style="font-style: italic;">messages_en.properties</span></span> and everything worked.<br />I guess it makes sense in a way that a resource bundle got be associated with a locale. But won't it be nice to dump everything without an explicit locale into the default?Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-76264295589491913002007-10-08T00:50:00.001-04:002008-03-17T15:34:40.396-04:00Kubuntu/ubuntu run command dialog doesn't run script.I put together a Eclipse launch script to start eclipse with JDK 1.6 while my system's default JDK is 1.5. Some extra VM parameters are also used to make eclipse run a little bit faster because I live in it all day long.<br /><br />The script loads Eclipse fine in bash console. But when I try to launch it from run command dialog by pressing Alt-F2, nothing happens. Eventually I figured out that the problem is in my launch script: I forgot to push "#!/bin/sh" at the beginning of the file.<br /><br />I am not sure why nothing happens when the sha-bang '#!' is left out, but if you encounter something similar, it might be cause.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-32231678718394865102007-09-19T23:26:00.000-04:002007-09-19T23:54:58.719-04:00Saving datetime into database, what timezone is it in?Moments ago I posted a review on Amazon.com and returned to the product's page, it shows the review was posted 7 hours ago. It seems like Amazon is having a timezone <span class="blsp-spelling-corrected" id="SPELLING_ERROR_0">conversion</span> issue.<br /><br />I am not trying to pick on Amazon. The funny part is that right this afternoon I was asked by a coworker about what timezone a <span class="blsp-spelling-error" id="SPELLING_ERROR_1">datetime</span> column of our database table is in. Then we had a discussion about how to handle timezones.<br /><br />Timezone in databases is a delicate issue, and a tricky one to fully understand. Conversion is one issue. Others issues include moving data between database servers running in different timezones, moving data between different database dialects, interpret archived data, etc.<br /><br />In the past I tried a couple approaches besides blindly saving the Date object through <span class="blsp-spelling-error" id="SPELLING_ERROR_3">JDBC</span> regardless of the timezone information. In one application I converted the <span class="blsp-spelling-error" id="SPELLING_ERROR_4">datetime</span> property into <span class="blsp-spelling-error" id="SPELLING_ERROR_5">UTC</span> time before saving it. In another application I converted time into milliseconds and saved it into database as long number.<br /><br />I don't have a clear understanding of the relationship among the JVM's timezone, the Date object's timezone, the database server's timezone, the Timestamp's timezone in JDBC result set, and the Datetime column's timezone is MS SQL Studio's result set.<br /><br />I have the full intension to study this topic in depth and report back.<br /><br />Stay tuned.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-41735938756815343982007-09-18T16:52:00.000-04:002007-09-18T17:09:24.920-04:00the sneaky OutOfMemoryError: PermGen space errorToday I ran into several VERY nice posts which talk about the PermGen errors.<br /><br />Here are Frank Kieviet's two blogs: <a href="http://blogs.sun.com/fkieviet/entry/classloader_leaks_the_dreaded_java">classloader leakers</a> and <a href="http://blogs.sun.com/fkieviet/entry/how_to_fix_the_dreaded">how to fix it (more like how to find it, fixing is likely to be the easy part)</a>.<br /><br />Here is an excellent list of known offenders and links from Spring forum. <a href="http://opensource.atlassian.com/confluence/spring/display/DISC/Memory+leak+-+classloader+won%27t+let+go">link</a>.<br /><br />I cannot wait to modify jhat to map out the heap of my applications. We actually have two applications that are suffering from PermGen errors. One interesting point is that both applications suffer this error when they are hot deployed (unload then load while the application server is running) and when they run for a prolonged period of time. It seems like the first scenario is well examined. It will be very interesting to see what I can find out on the second scenario.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-39021601906158054072007-07-31T09:05:00.000-04:002007-07-31T18:00:06.197-04:00Custom sort of rows and columns without writing comparatorWhen doing <span class="blsp-spelling-error" id="SPELLING_ERROR_0">JasperReports</span>, I am often asked to sort the rows and columns in a particular ways other than alphabetical. <span class="blsp-spelling-error" id="SPELLING_ERROR_1">JasperReports</span> does support customized comparators for sorting. But I found it quite complicated to implement and not very easy to update in the future. Today I figured out a trick that can do arbitrary sorting easily.<br /><br />In my sql statement, I concatenate the sequence number and the actually value together, for example, '01Banana', '02Orange', '03Apple'. Then in my report, I chop off the sequence number before displaying it, such as $F{field}.subString(2).<br /><br />This trick works fine for small number of values.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-36310207.post-6558122966223117752007-05-24T18:34:00.000-04:002007-05-25T09:43:16.116-04:00Responsive UI: do the heavy lifting in backgroup threadSlow wireless connection, less processing power, less memory, all these factors make JavaME applications tend to feel sluggish. One trick we developers can play is to use background thread to do the heavy lifting parts.<br /><br />The sample code below shows how one can use a separate thread to perform the time consuming task, while the UI still interacts with user, and update the UI when the task is completed.<br /><br />Please note that the Runnable object passed to UiApplication.invokeLater() should return quickly. The Runnable object is put into the event queue to be executed by the event dispatcher thread. During the time this runnable is executing, all new UI events are queued so the UI will not respond to any input.<br /><blockquote><br />package com.mycompany.sample;<br /><br />import net.rim.device.api.ui.UiApplication;<br />import net.rim.device.api.ui.component.AutoTextEditField;<br />import net.rim.device.api.ui.component.ObjectChoiceField;<br />import net.rim.device.api.ui.container.MainScreen;<br /><br />public final class DemoBackgroundThread extends UiApplication {<br />public DemoBackgroundThread(){<br />super();<br />pushScreen(new EditorScreen());<br />}<br /><br />public static void main(String[] args) {<br />new DemoBackgroundThread().enterEventDispatcher();<br />}<br /><br />private static class EditorScreen extends MainScreen {<br />private AutoTextEditField _firstNameField;<br />private AutoTextEditField _lastNameField;<br />private ObjectChoiceField _timezoneField;<br />public EditorScreen()<br />{<br /> super();<br /> _firstNameField = new AutoTextEditField("First Name: ", "");<br /> _lastNameField = new AutoTextEditField("Last Name: ", "");<br /> _timezoneField = new ObjectChoiceField("Timezone: ", new String[]{"Loading Timezones"});<br /> add(_firstNameField);<br /> add(_lastNameField);<br /> add(_timezoneField); <br /> new Thread(new Runnable() {<br /> public void run() {<br /> final String[] zones = new String[6];<br /> zones[0] = "-Select Timezone-";<br /> for(int i = 1; i < zones.length; i++) {<br /> try {<br /> //<span style="font-weight: bold;">do the heavy lifting here, like fetching data from remote server or heavy calculations.</span><br /> Thread.sleep(1000); <br /> } catch (InterruptedException e) {<br /> //who cares<br /> }<br /> zones[i] = "GMT-"+i;<br /> }<br /> UiApplication.getUiApplication().invokeLater(new Runnable(){<br /> public void run() {<br /> _timezoneField.setChoices(zones);<br /> }<br /> });<br /> }<br /> }).start();<br />}<br />}<br />}<br /><br /></blockquote>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-3382419566117587192007-05-22T15:05:00.000-04:002007-05-22T16:12:21.440-04:00Debug Blackberry app inside EclipseOnce you <a href="http://a-developers-notes.blogspot.com/2007/04/eclipse-environment-setup-for.html">get your eclipse environment setup</a>, it is pretty straight forward to debug your app, thanks to Blackberry JDE, 4.1 and higher comes with <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jpda/jdwp-spec.html">JDWP</a> implementation.<br /><br />Let's first start JDWP, from Start --> All Programs --> Research In Motion --> Blackberry JDE 4.?.? --> JDWP. In this interface, the first main tab "Simulator" configures the simulator to lanch when debugger connects and the other behaviors. Please make sure that in the "General" tab "Launch simulator when debugger connects" is checked. In the second main tab "Communications", you can change the port JDWP listens to. This is the port we will connect to from our eclipse debugger.<br /><br />With JDWP running, we can go back eclipse. Before we get started, we should increase the debugger's timeout threshold. Start elcipse, go to Window --> Preferences --> Java --> Debug, at the bottom of the dialog, increase the "Debugger timeout" and "Launch timeout" to 10 times longer. :) It is much needed unless you have a monster computer with multiple cores and multiple gigs of memory.<br /><br />To config the debugger, go to Run --> Debug... In the dialog, select "Remote Java Application" from left hand list, then click on the "New" button; now at the right hand pane, give it a meaningful name, check the remote host and port matches <span class="blsp-spelling-error" id="SPELLING_ERROR_0">JDWP's</span>, then go to the third tab "Common", check "Debug" option in "Display in Favorites menu" so you don't have to open this dialog next time. Click "Debug" button if you are ready, otherwise click "Close" button to save the configuration.<br /><br />Now the fun part begins. Edit code, run the ant task to deploy, set break point, click on the debug icon, and repeat this cycle.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-36310207.post-81713958563038586892007-05-21T23:24:00.000-04:002007-05-22T15:19:14.938-04:00Eclipse setup for blackberry developmentThese are proven-to-work steps to setup your eclipse environment for developing Blackberry applications. I hope this post will make somebody's entry into the RIM development easier.<br /><br />To get started, do the following if you haven't done so:<br /><ol><li><a href="http://www.eclipse.org/downloads/">Download </a>and install Eclipse</li><li><a href="http://na.blackberry.com/eng/developers/downloads/jde.jsp">Download </a>and install <span class="blsp-spelling-error" id="SPELLING_ERROR_0">BlackBerry</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_1">JDE</span></li><li><span class="blsp-spelling-error" id="SPELLING_ERROR_1"><a href="http://ant.apache.org/bindownload.cgi">Download </a>and install Apache ant<br /></span></li><li><a href="http://www.etaras.com/blackberry/rapc/">Download </a><span class="blsp-spelling-error" id="SPELLING_ERROR_2">RAPC</span> ant task jar file<br /></li></ol>Now let's setup our eclipse environment.<br /><ol><li>Start your eclipse, switch to a brand-new workspace, for example: <span style="font-style: italic;">c:\RIM\workspace</span></li><li>go to Window --> Preferences --> Java --> Installed JREs, click on "<span style="font-style: italic;">Add</span>" button.</li><li>In the dialog, leave the default "<span style="font-style: italic;">Standard VM</span>" option for JRE type;<br /></li><li>Type in a "<span style="font-style: italic;">JRE name</span>" as you like, such as 'RIM JRE';<br /></li><li>In "<span style="font-style: italic;">JRE Home Directory</span>", navigate to your installed JDK home, such as 'C:\Program Files\Java\jdk1.6.0';<br /></li><li>Leave "<span style="font-style: italic;">Default VM Arguments</span>" blank;<br /></li><li>Now select all the jar files in "<span style="font-style: italic;">JRE System Libraries</span>", then click "<span style="font-style: italic;">Remove</span>" button to remove all of them; Click "<span style="font-style: italic;">Add External JARs</span>", navigate to you Blackberry JDE installation folder, select lib/net_rim_api.jar, such as 'C:\Program Files\Research In Motion\BlackBerry JDE 4.2.1\lib\net_rim_api.jar'.</li><li>Click "<span style="font-style: italic;">OK</span>" button to add the new JRE.</li><li>Check the checkbox of your newly added JRE to make it the default (Optional: select this JRE, click on "Edit" button to see if the system libraries are still like you set. It happened to me a couple times that eclipse added the jars in JRE home back into the list.)</li></ol>With the eclipse setup, we are ready to create our first project:<br /><ol><li>Goto File --> New --> Project, select "Java Project", enter Project Name "HelloWorld", Make sure in the JRE group the "RIM JRE" is selected. In the "Project Layout" group, I prefer to have src and class output into separate folders. Click "Finish" button.<br /></li><li>Right click the project, select New --> Folder, create a folder named "lib"</li><li>Right click the project, select New --> Folder, create a folder named "resources"</li><li>Right click "lib" folder, select "import"; in the dialog, select "general" --> "file system", import the anttask-rapc-1.?.jar you downloaded. Right click the jar file and select "Build Path" --> "Add to Build Path".</li><li>Follow the same step to import an icon file in GIF format into "resources" folder. (other image formats work too, we use GIF for demo).</li><li>Create a package named "com.mycompany.sample"</li><li>Create a class named "HelloWorld.java" in this package and paste these code:<br /><pre>package com.mycompany.sample;<br /><br />import net.rim.device.api.ui.UiApplication;<br />import net.rim.device.api.ui.component.LabelField;<br />import net.rim.device.api.ui.container.MainScreen;<br /><br />public final class HelloWorld extends UiApplication {<br /><br />public HelloWorld(){<br />super();<br />MainScreen screen = new MainScreen();<br />screen.add(new LabelField("Hello world!"));<br />pushScreen(screen);<br />}<br />public static void main(String[] args) {<br />new HelloWorld().enterEventDispatcher();<br />}<br />}</pre></li><li>Now right click on the project name and create a new file named "build.xml", copy and paste the following code and edit the JRE and RIM JDK pathes accordingly, also search and replace the simulator batch file "8800.bat" to one that exists in your JDE (this ant build script is modified based on a post in <a href="http://www.blackberry.com/developers/forum/forum.jsp?forum=1">Blackberry Java Forum</a>.)<pre><br /><?xml version="1.0" encoding="UTF-8"?><br /><br /><project name="HelloWorld" default="buildRIM" basedir="."><br /><br /><taskdef name="rim" classname="com.etaras.anttask.rapc.RAPC" classpath="lib/anttask-rapc-1.8.jar" /><br /><br /><property name="jdehome" value="C:\Program Files\Research In Motion\BlackBerry JDE 4.2.1" /><br /><property name="javahome" value="C:\Program Files\Java\jdk1.5.0_11"></property><br /><property name="simulator" value="${jdehome}\simulator" /><br /><property name="bin" value="${jdehome}\bin" /><br /><br /><target name="debug" depends="buildRIM"><br /><copy todir="${simulator}" overwrite="true"><br /><fileset dir="."><br /><include name="*.cod" /><br /><include name="*.debug" /><br /><include name="*.csl" /><br /><include name="*.cso" /><br /></fileset><br /></copy><br /><exec executable="cmd.exe" dir="${bin}" spawn="true"><br /><arg value="/c" /><br /><arg value="jdwp.bat" /><br /></exec><br /></target><br /><br /><target name="simulate" depends="deploy"><br /><exec executable="cmd.exe" dir="${simulator}" spawn="true"><br /><arg value="/c" /><br /><arg value="8800.bat" /><br /></exec><br /></target><br /><br /><target name="deploy" depends="buildRIM"><br /><copy todir="${simulator}" overwrite="true"><br /><fileset dir="."><br /><include name="*.cod" /><br /><include name="*.debug" /><br /><include name="*.csl" /><br /><include name="*.cso" /><br /></fileset><br /></copy><br /></target><br /><br /><target name="buildRIM" description="Composes RIM"><br /><rim jdehome="${jdehome}" javahome="${javahome}"><br /><workspace src="helloworld.jdw" build="true" update="true"><br /><cldc src="helloworld.jdp"<br />title="HelloWorld"<br />vendor="my company"<br />version="0.1"<br />description="HelloWorld"<br />arguments=""<br />systemmodule="false"<br />runonstartup="false"<br />startuptier="7"<br />ribbonposition="0"<br />output="helloworld"<br />options="-quiet"<br />update="true"><br /><files dir="."><br /><include name="**/*.java" /><br /><include name="resources/**/*.*" /><br /></files><br /><icons dir="."><br /><include name="resources/**/*.png" /><br /><include name="resources/**/*.gif" /><br /></icons><br /></cldc><br /></workspace><br /></rim><br /></target><br /><br /></project><br /></pre><br /></li><li>Open a DOS window, change to the directory where you have your build.xml file, type "ant simulate", this task will build the project, deploy it and start the simulator.</li><li>Look for the logo you picked for your HelloWorld app and open it, you should see a blank screen displaying "Hello World!". How exciting!</li></ol>I will write down my experience of debugging applications inside eclipse in the next couple of days.Unknownnoreply@blogger.com2