DevX has a porting articled titled Struts to Stripes—A Road Worth Traveling. It sort of made me think, looks like Stripes was pretty much made to address certain flaws in Struts - namely, the XML bloat and the need to write FormBeans (why can’t these be generated from the XML? Hmmm…). It does look pretty straightforward.
Archive for November, 2006
How I wished this was around when I was back in programming school. My class had to resort to avoiding input altogether because I suspect the lecturer didn’t actually know how to provide input to console applications (which was all we did for Java classes). Sure, accepting String args[] would suffice, but I didn’t know that back then (I’m sure some all of us wondered “What is that argument doing there?” at some point :)). A few other lecturers resorted to non-standard input classes, some wrote their own. With a standard input API for consoles, all that nonsense should fade away soon.
Talking about the API itself, it does look rather polished and should cover 90% of a programmers needs (don’t ask what the 10% that it might not cover, I’ve not come up with any yet). And sometimes, programming in consoles might be useful - especially when coupled with the fact that Java has just been open-sourced and a JRE is going to be bundled with just about every Linux distro (Linux geeks tend to love console apps, remember?). Maybe we’ll see a plethora of console applications written in Java soon?
Sidenote: Still, sometimes it’s better to use a properties file for input, especially when there are too many arguments to type or when there’s a large risk of user entering wrong input (e.g. a super-duper complex input)
Hmmm.., I just realized I don’t talk much about work here. Well, this post is about as good as any to start :). I’ve just finished co-developing a very fun project. Fun in the sense that it’s a critical system (financially) and it’s a high-transaction one. I’ve never really gotten involved in heavy duty projects before and this experience was refreshing. It was a re-write of an existing application, one that was starting to break at its seams after load has increased. The project is for DiGi, Malaysia’s No. 1 prepaid telco provider. It shouldn’t be a surprise then that the project has to do with its prepaid business. It doesn’t have an internal code name, but its commercial name should be Flexi e-load (I could be mistaken, so correct me if you know better :)). About 30% of DiGi’s reloads are done using this system, a maximum of 20 transactions per second (with rumors that this load might increase much). Through internal testing, it was determined that the upgraded system can take about 130 transaction per second (up from a paltry 7), so I believe we have head room here

OK, now let’s talk about Flexi e-load’s guts. It runs on 4 Sun Sparc servers; 3 application servers, 1 database server. The application servers are hardware load balanced and clustered to provide high-availability. The J2EE application server used is BEA Weblogic 8. Parts of the J2EE stack used - JDBC connection pooling and JMS. Both exposed via JNDI. JMS is great for fast asynchronous transactions (which suites the business requirement of Flexi e-load). Believe it or not, the previous the application wasn’t even threaded (this is partly why it crumbled when load increased). Earlier upgrades included some threading but it too was bug riddled. Switching to JMS provided a clean and easy way for multi-threading the application. Another problem was that data was being transfered among classes via XML, yes, XML. It was slow and memory consuming (to put it lightly). I have no idea why this was used - every single class that communicated with another had a bunch of XML parsing and XML building code resulting in a huge bloat, none of which was easily debug-able. So another part of the optimization performed was the removal of most of the XML junk and relied on POJOs and MDBs instead. Maybe XML was used to facilitate integration with external systems? I guess we’ll never know at this point, everything’s been removed :). Yet another problem was the persistence layer used - iBATIS. I want to like the framework (really), but coding in SQL is soooo yesterday. I don’t mind hand-tuning certain SQL for performance, but iBATIS forces the developer to write every single SQL statement required. Dang, that hurt. It also didn’t help that some SQL were so badly written (performance wise) that when it came to tweaking it, this part was just such a pain (in the midst of the pain, I wished Hibernate was used instead). Because SQL was handwritten this resulted in a problem - a lot of bad performing ones were written (see below) and they were very hard to fix since rewriting is risky (we’re talking about business rules here). Database access was also way too frequent. A single business transaction sometimes result in 5 - 10 database hit. I’m not joking. Lookup tables weren’t cached and object already in memory was re-queried without good reason nor need (feels like developers that worked on different modules weren’t communicating properly, yes?). If I were asked to summarize the optimizations performed, it would be: removal of all the XML junk, use JMS for async, multi-threaded processing and reduction of database hits (on average, an access to a small lookup table incurs a 600ms wait, assuming no locks, while a HashMap cached version read takes 2ms). Not to say those are the only tweaks though. I know that the rewrite for multi-threaded socket connectors to SMSC servers also improved reliability and performance.
Speaking about database hits, part of the performance bottleneck was (still is?) the database - Oracle. Ok, granted that application developers doesn’t know a lot about databases, but I question whether any thought at all was put into optimizing the database before this. I think that a little bit of database knowledge is essential for every programmer, more so after this project. Indexing was totally absent from most of the tables (I’m not talking about PK indexes, those were there). Because of this, Oracle’s explain plan showed most of the SQL queries were resulting in full table scans. There are also too many dynamic SQL (see, I told you developers write bad SQL), resulting in very little SQL re-use (a high parse-execute ratio). Then there’s the problem of partitioning, no tweaking of block size (some of these should really have been considered). Let’s not go into other known tweaks - pinning lookup tables in the db cache (some of these was cached at the application level eventually), optimizing the cache-hit ratio in SGA, locking SGA in memory (we have 4GB of RAM…). Furthermore, some odd options such as db tracing and logging was enabled, gasp! In fact, it’s still enabled. I’m gonna try to have that disabled unless there’s a good reason why tracing and logging was enabled on a fully-functional OLTP database.
So that’s what I’ve been up to for the past 3 months. Now I’m working on some parts of Flexi e-loads reports (accessible via the Web) and general performance. The tech-lead for the project has resigned recently resulting in a great loss for the team (he was responsible for maybe 70%-80% of the re-write).
Looking forward, hopefully, there’ll be a new web project for me to work on. I wanna use AppFuse
Thanks to a colleague that mentioned AppFuse, I Googled, ended here and then found this article - Seven simple reasons to use AppFuse in developerWorks (at this point, you know it’s good, since developerWorks articles are usually deserve thumbs up). Going through it, I have no idea how AppFuse slipped under my radar for so long. This framework (or super-framework), if does all it claims to do, is the perfect tool to use to kick-start any Java web project. It’s that good. Integrated testing (DBUnit, jMock, bla bla), ease of deployment (Maven 2, Ant), support for persistence layers (Hibernate, iBATIS), able to use the popular web frameworks (Struts 1, WebWorks, Spring MVC), and much more (I’m still reading here). We’ve got a couple of projects coming in, and you can bet I’ll use AppFuse
Ever wanted to contribute to something great? How does helping a group of scientist solve genetic diseases sound? All you need to do is visit this site - Folding@Home; download its client software and run it. After assigning yourself a unique ID (to track your contribution), and an optional team ID (teams compete for ranking), the client software will start to download work packets to process. Its essentially a low-priority program which runs only when your CPU is idle.

Think about it - most of the time your CPU is idle - web surfing, file downloading, writing a document, reading emails, etc. - are all very common activities yet they use little CPU processing time (especially with fast processors). Why not donate those idle time then? If and when you need 100% CPU time to be free (say, gaming :)), the client is easy to shutdown. Just remember to restart it again.
Michael Yuan’s article on Scaling Enterprise Java on 64-bit Multi-Core X86-Based Servers is quite a good read. A few potentially drop-in tips to enhance performance:
- use the
-Xms<size>(minimum memory) and-Xmx<size>(maximum memory) flags. For instance, the-Xms1g -Xmx1gto force the JVM to use a fixed amount of memory (1 GB). Apparently, resizing of heap @ runtime can cause instability - by default, garbage collection is single threaded. Use certain flags to let it run in multiple threads, in either background or foreground threads
further tune Java’s garbage collection- Monitor the GC and JVM. Use
-verbose:gcfor GC printing to console. If using JDK 5, start the JVM with the-Dcom.sun.management.jmxremoteflag and run theconsolecommand to view JVM performance in a GUI - startup the JVM with the
-serverflag. Starts up slower but better runtime performance
A few other tips involves programming (using NIO, Concurrency in JDK 5, etc.) and JBoss so they’re not fast fixes. Still, go read the original article for more info. A few other gems in the article - a Java load / performance tool called Grinder and a list of JVM flags.