RIAs OR RIEs – CALL THEM WHAT YOU WILL, THEY’RE HERE

No. 1 i-Technology Magazine in the World -Technology

PAGE 3

JUNE 23-24, 2008 NEW YORK CITY

JDJ.SYS-CON.COM

VOL.13 ISSUE:5

Detecting them with FOSS tools

PLUS... Java and the Mac
Interactive Storyboarding with JSP The Rise of Functional Programming Modernizing Axis1 Services Painlessly
T H E W O R L D ’ S L E A D I N G i - T E C H N O L O G Y M A G A Z I N E J D J . S Y S - C O N . C O M

FROM THE PUBLISHER

Editorial Board
Java EE Editor: Desktop Java Editor: Eclipse Editor: Enterprise Editor: Java ME Editor: Back Page Editor: Contributing Editor: Contributing Editor: Contributing Editor: Founding Editor: Yakov Fain Joe Winchester Bill Dudney Ajit Sagar Michael Yuan Jason Bell Calvin Austin Rick Hightower Tilak Mitra Sean Rhody

RIAs or RIEs – Call Them What You Will, They’re Here

Jeremy Geelan

Production
Associate Art Director: Executive Editor: Associate Online Editor: Research Editor: Tami Lima Nancy Valentine Lindsay Hock Bahadir Karuv, PhD

To submit a proposal for an article, go to http://jdj.sys-con.com/main/proposal.htm

Subscriptions
For subscriptions and requests for bulk orders, please send your letters to Subscription Department:

888 303-5282 201 802-3012 subscribe@sys-con.com
One year digital edition subscription: $99.00 (12 issues) Two year digital edition subscription: $129.00 (24 issues)

Editorial Offices
SYS-CON Media, 577 Chestnut Ridge Rd., Woodcliff Lake, NJ 07677 Telephone: 201 802-3000 Fax: 201 782-9638 Java Developer’s Journal Digital Edition (ISSN#1087-6944) is published monthly (12 times a year) for $99.00 by SYS-CON Publications, Inc., 577 Chestnut Ridge Road, Woodcliff Lake, NJ 07677. Periodicals postage rates are paid at Woodcliff Lake, NJ 07677 and additional mailing offices. Postmaster: Send address changes to: Java Developer’s Journal, SYS-CON Publications, Inc., 577 Chestnut Ridge Road, Woodcliff Lake, NJ 07677.

©Copyright
Copyright © 2008 by SYS-CON Publications, Inc. All rights reserved. No part of this publication may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopy or any information storage and retrieval system, without written permission. For promotional reprints, contact reprint coordinator Megan Mussa, megan@sys-con.com. SYS-CON Media and SYS-CON Publications, Inc., reserve the right to revise, republish and authorize its readers to use the articles submitted for publication.

For List Rental Information: Kevin Collopy: 845 731-2684, kevin.collopy@edithroman.com Frank Cipolla: 845 731-3832, frank.cipolla@epostdirect.com

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc., in the United States and other countries. SYS-CON Publications, Inc., is independent of Sun Microsystems, Inc. All brand and product names used on these pages are trade names, service marks or trademarks of their respective companies.

Enough with the new words already.” That was how Sean Voisen recently ended a discussion about the burgeoning technology lexicon, which he thinks can only be explained as “a ploy to keep Merriam-Webster in business.” Voisen, who designs and builds Rich Internet Applications, web applications, data visualizations, and what he calls “other fun pieces of Internet-enabled software” for a living, is not a fan of “RIA” as a term. “Marketing gurus create new terminology like ‘RIA’ and ‘Web 2.0’ in order to force people to engage in new conversations without them dragging along their baggage of ingrained prejudices about what something is or is not,” Voisen contends. “They also do it – I am convinced – to make themselves seem smart,” he adds. Voisen’s view is echoed by Ethan Eismann, the senior experience design lead of Adobe Thermo with Adobe’s XD team. He disagrees with “RIA” as a term for two reasons: “First, because like all things techy, it’s already obsolete and second because it’s limiting.” But Eismann admits that while he hates “RIA,” he also loves it: “I love it because it’s now such a part of the common vernacular of web culture that when it’s used, everyone immediately understands that you are talking about ‘something better than primitive HTML websites.’” Its limiting factor as a term, according to Eismann, has to do with the two words “Internet” and “application.” Personally he prefers to use the acronym “RIE” – for ‘Rich Interactive Experience.’ Front-end engineering experts like Voisen and Eismann remind us that the emergence of Web 2.0 technologies and the iPhone experience have shown that great user interface design makes a big difference, that the era of what Eismann calls primitive HTML websites is truly over, and that on the web the new priority is innovation and optimizing the User eX-

perience (UX), whether that means experimenting with JavaFX or AJAX or whatever. The tools and platforms that encourage and support superior UX are becoming the pre-eminent tools for business survival and success, and their numbers are growing all the time, as reflected by the mushrooming success of the AJAXWord Conference & Expo series – which in spite of its name is now as much about Rich Internet Applications and Web Development Frameworks as about merely AJAX per se. The runaway success of Apple’s iPhone is another clear indicator of the business and market-share power of superior user experience in 2008. Anthony Franco, president of EffectiveUI, who keynoted at AJAXWorld in NYC, summed up the inflexion point very succinctly: “Last year, the overall demand for RIAs outpaced the qualified supply chain. This trend will continue in 2008. While last year brought unprecedented growth in RIA adoption – especially by Fortune 500 companies – RIA adoption in 2008 brings a new onslaught of risks, rewards, challenges, and opportunities for companies of all sizes.” In the end – quite aside from whether you call them RIAs or RIEs – what matters is not words or terminology but business and the realities of enterprise computing. “RIAs are impacting the way that companies like eBay, Ford, Random House, Viacom, GE, Dow Jones, and NBC think about the Internet and desktop software, and are demonstrating how innovative thinking can completely change the way they do business,” according to Franco. As president of EffectiveUI, he enjoys unique opportunities to see close up how Fortune 500 companies are beginning to harness RIAs and leverage them to improve the user experience and boost the bottom line. Is your company doing the same? If not, why not?

Jeremy Geelan is Sr. Vice-President of SYSCON Media & Events. He is Conference Chair of the AJAXWorld Conference & Expo series and founder of Web 2.0 Journal. From 2000-6, as first editorial director and then group publisher of SYS-CON Media, he was responsible for the development of all new titles and iTechnology portals for the firm, and regularly represents SYS-CON at conferences and trade shows, speaking to technology audiences both in North America and overseas. He is executive producer and presenter of “Power Panels with Jeremy Geelan” on SYS-CON.TV.

jeremy@sys-con.com

JDJ.SYS-CON.com

May 2008

3

contents
MAY 2008 VOLUME:13 ISSUE: 5

JDJ Cover Story

Uncommon Java Bugs
by Kris Lachor

24

FROM THE PUBLISHER

RIAs or RIEs – Call Them What You Will, They’re Here
by Jeremy Geelan

...............................3
PRESSROOM

Industry News

Detecting them with FOSS tools

............................6
JDJ News Desk
CASE STUDY

10
GET SMART. GET REAL-TIME.
Next generation Internet applications will provide you with instant news and real-time information without the need for plug-ins or 20th century polling techniques. Imagine using your Web browser to monitor ANY real-time data, from server statistics to your favorite stock portfolio, with NO polling, NO plug-ins, and NO issues with firewalls or proxy servers!

Java and the Mac
It all started with the boss out of Dilbert by Bob Cusick

...........................8
by S.G. Ganesh
JSP

Feature

Feature

Interactive Storyboarding with JSP
Introduction to J-CASE tag library by Masayuki Otoshi

...........................14
JSR WATCH

Java and Free Software in Brazil

GET SMART. GET REAL-TIME. GET POWERED BY KAAZING.
www.kaazing.com 650.943.2436 sales@kaazing.com

18
The Rise of Functional Programming
by Joe Morrison and Kalani Thielen by Michael Galpin
JDJ.SYS-CON.com

28
Modernizing Axis1 Services Painlessly

Bridging the digital divide by Patrick Curran

............................32

Do you want to subscribe, sign up a friend, or possibly have an opportunity to write for us? Visit www.sys-con.com today!
Java Developer’s Journal Digital Edition (ISSN#1087-6944) is published monthly (12 times a year) for $99.00 by SYS-CON Publications, Inc., 577 Chestnut Ridge Road, Woodcliff Lake, NJ 07677. Periodicals postage rates are paid at Woodcliff Lake, NJ 07677 and additional mailing offices. Postmaster: Send address changes to: JDJ, SYS-CON Publications, Inc., 577 Chestnut Ridge Road, Woodcliff Lake, NJ 07677.

May 2008

5

PRESSROOM

Industry News
DigiSoft Announces General Availability of a Java Platform Micro Edition Client Solution for IPTV
(Las Vegas) – DigiSoft.tv has signed a global Binary Value Added Partner agreement with Sun Microsystems for the distribution of a Java Platform Micro Edition (Java ME) based software stack for IPTV Set Top Boxes (STBs). Sun’s Java technology-based media client combined with DigiSoft’s middleware solution for IPTV Set Top Boxes enables service providers to launch high definition (HD) services such as Video and Music on Demand, karaoke, home shopping, network-based recording (NPVR) / time-shifted TV, games and more on a wide range of IPTV STBs with H.264 HD and SD video. Also supported is the latest encryption and watermarking technologies from selected partners. The combined DigiSoft / Sun software stack offers IPTV service providers an open, flexible IPTV middleware solution. The use of Java technology for the software stack enables the creation of multi-platform (converged) Java applications for support on a range of Java-based devices, including Blu-ray Disc players, OCAP and other GEM-based set top boxes, mobile handsets, and personal computers while requiring minimal re-authoring, simplifying application and service deployment. www.digisoft.tv Enterprise T5140 and T5240 servers deliver performance and scalability and help enable customers to consolidate the datacenter into an ultra-dense, energy efficient compute environment, optimized and managed by the Solaris 10 Operating System (OS). The SPARC Enterprise T5140 and T5240 servers deliver up to 16 times higher compute density than competitive twosocket x86 systems and up to 32 times higher compute density than competitive four-socket x86 systems. The Sun and Fujitsu SPARC Enterprise T5140 and T5240 servers provide up to three times more performance than competitive RISC systems in half the space. www.sun.com www.fujitsu.com

President and CEO: Fuat Kircaali fuat@sys-con.com President and COO: Carmen Gonzalez carmen@sys-con.com Senior VP, Editorial and Events: Jeremy Geelan jeremy@sys-con.com

Advertising
Advertising Sales Director: Megan Mussa megan@sys-con.com Associate Sales Manager: Corinna Melcon corinna@sys-con.com Advertising & Events Associate: Alison Fitzgibbons alison@sys-con.com

Events
Events Manager: Sharmonique Shade sharmonique@sys-con.com

Appcelerator Integrates Rich Internet Application Platform with Google App Engine
(Atlanta) – Appcelerator, a provider of open source rich Internet applications (RIA), it has updated its platform to allow applications built using Appcelerator to be deployed to the free new Google App Engine. Used together, the offerings give developers a route to developing, deploying, managing and scaling their applications. Appcelerator is an integrated platform that fuses RIA and service-oriented architecture (SOA). With Appcelerator, developers can assemble interactive web applications without the need for JavaScript or player-based plug-ins. Web applications can be implemented on Java/J2EE, PHP, Ruby, .NET, Python and Perl. Appcelerator for App Engine runs on Python, the scripting language currently supported by App Engine. As Google expands support to other languages, Appcelerator for App Engine will follow suit. www.appcelerator.com

Editorial
Executive Editor: Nancy Valentine nancy@sys-con.com Associate Online Editor: Lindsay Hock lindsay@sys-con.com

Production
Lead Designer: Tami Lima

tami@sys-con.com

Sun and Fujitsu Expand SPARC Enterprise Server Line
(Santa Clara, CA / Tokyo) – Sun Microsystems and Fujitsu Limited have expanded the Sun and Fujitsu SPARC Enterprise server line with the introduction of two new systems based on the UltraSPARC T2 Plus processor. Scaling from the edge of the network to the heart of the enterprise, the third-generation CMT SPARC

Associate Art Directors: Abraham Addo abraham@sys-con.com Louis F. Cuffari louis@sys-con.com

Web Services
Information Systems Consultant: Robert Diamond robert@sys-con.com Web Designers: Stephen Kilmurray stephen@sys-con.com Richard Walter richard@sys-con.com

VoiceObjects Introduces VoiceObjects Desktop for Eclipse
(San Mateo, CA) – VoiceObjects, a personalized phone self-service company, has announced the general availability of its VoiceObjects Desktop for Eclipse and VoiceObjects Developer Edition. Using these new solutions, developers can create over-the-phone, multi-channel applications with personalization features to customize the experience for each user. VoiceObjects 7 suite of products includes VoiceObjects Server for the deployment and management of personalized self-service applications over voice, video, text, and Web self-service channels; VoiceObjects Desktop for creating, testing, deploying and monitoring applications; and VoiceObjects Analyzer, a Web-based service used for caller behavior, system and application analysis. The release of VoiceObjects Desktop delivers solutions that enable organizations to obtain 1:1 personalization. Built from the ground up using open standards, VoiceObjects enhances VoiceXML capabilities in delivering applications that meet consumer demand. Desktop for Eclipse is an Eclipse-based development environment that provides a graphical-use interface for the design, development, deployment, testing and administration of voice, video, text and Web-based applications. The solution supports two operational modes: a network mode that allows for team collaboration, and a standalone mode that allows developers and consultants to perform offline development and testing. www.voiceobjects.com

Accounting
Financial Analyst: Joan LaRose joan@sys-con.com Accounts Payable: Betty White betty@sys-con.com

Customer Relations
Circulation Service Coordinator: Edna Earle Russell edna@sys-con.com

6

May 2008

JDJ.SYS-CON.com

CASE STUDY

Java and the Mac
It all started with the boss out of Dilbert
his is the story of a Mac application developer (okay – it’s about two of them) who set out on a quest to find an application development tool based on Java so his boss would let him develop on the Mac platform, which he loved. There was only one catch – he had to find a tool that was fast. Traditional Java programming was going to take waaaay too long to convert the internal custom programs that had been written in an old 4GL. But the boss still wanted the excellent user interfaces that he was used to – because our hero was good on the Mac and could make the screens look “pretty.” If possible – the boss wanted the impossible – make the application run on a desktop AND over the Web – “just in case.” Here’s the story of our intrepid hero and how he searched, and found, a way to meet all the “Dilbert boss-like” requirements. John Allen, a researcher at Stanford Medical Center, used to use 4GL environments to assist the research divisions at this well-known university. Stanford Medical is one of the most advanced research facilities for oncology (cancer), and with the cutting -edge research it does, there’s no standard software package that can be used. The oncology unit’s only solution was code-ityourself. 4GL worked well for a long time, but a couple of key areas started to become problematic. 4GLs in general don’t scale very well, aren’t very secure due to proprietary security systems, and worst of all don’t run very well over the Internet. Stanford, with over 200 buildings, uses the Internet as its LAN. Essentially this means the applications it uses must run secure, with easy deployment, and have excellent Web capabilities. Another issue is that it needed to access multiple databases, another problem for propriety 4GL tools – which often have their own databases built-in. Because of these challenges, Stanford decided that the 4GL would have to be switched to Java, which would deliver all it needed; however, it turned out that programming in Java was much more complex and much more time-consuming (of course!). After trying some projects in 2003 with the then-promising WebObjects (a Java environment from Apple used among oth-

��� �� ��

��

�� ��� ��� �� ��������� ��� � �� �����

�� �� �� ���� ��������� � �

by Bob Cusick

ISBN 0-9777622-0-3

T

Bob Cusick, managing director of Servoy, USA, has one of the oldest blogs on the Internet (started in 1994). He has been writing business applications for over 15 years, using popular 4GLs, Oracle, HTML, and Servoy. He was the charter technical editor for FileMaker Magazine and speaks at developer conferences all over the world. Visit his blog at bobcusick.blogspot.com.

ers for the iTunes store) it became evident that something else was necessary, and John Allen found it after he came in contact with Servoy. Servoy is a Java-based environment that lets the application developer use prebuilt scripts AND write in Java. Our hero contacted Servoy, Inc. and asked them to have a look at a prototype that was built in WebObjects. The prototype was an application used to manage data around oncology, and it had taken the WebObjects team hired by Stanford two months of coding to come up with a mockup. John was a bit suspicious about Servoy’s response to the prototype: “It’s faster to build this in Servoy than to write you an offer and project document.” A couple of days later, Servoy delivered a working version of the prototype. Going ahead with Servoy was now a no-brainer for Stanford. John is very much a Mac guy: “I just prefer to have a no-hassles OS where everything I need is in the right place, one that’s stable and doesn’t suffer from all types of viruses and malware. With Servoy, I can work on Mac all day, even if the applications I use are deployed to Windows. What’s nice is that I don’t even have to build specifically for Windows – Servoy and Java take care of this for me!” John was able to meet all his boss’s requirements, re-train himself on a Java-based product, and stay on the development platform he loves – the Mac. He deploys to Windows, Linux, and even Solaris across the multiple divisions at Stanford. Many other departments including Child Psychology and the Stanford Law School have also adopted Servoy technology since John first contacted the firm. Our second example is Darren Clarke, principal programmer at The Support Group. The Support Group is a business application consulting firm with offices all over the country. “I love Java, I love my Mac, I love the cross-platform capabilities of Java – I just hate the fact that a lot of simple things are very difficult to achieve with plain Java!” Darren prefers to develop on his Mac, but his customers often use Windows. The beauty of Java and Servoy is that it doesn’t matter. Business customers often have complicated business rules – but a lot of end users need a very easy-to-use interface.

Darren says, “On my Mac, it’s easier to use Java with Servoy for all the aspects involved in delivering business software: writing business rules and workflow rules in a productive way with very user-oriented and friendly user interfaces. With Servoy I solve those problems. Although it’s Java-based, it offers a whole set of functionality that allows me to focus on what I am good at: writing business software that is very user-friendly, stable, and scalable. And I can write it much, much faster in Servoy than in plain Java. With this tool, I can write one code and deploy to a client’s desktop or over the Web. It eliminates the need for rewriting in PHP and HTML – Servoy does most of that for me.” So is Java for Mac all hallelujah? No, unfortunately it isn’t. Apple is sending very mixed messages about Java: on one hand, Steve Jobs mentions that it’s obsolete; on the other hand he runs his Web store and iTunes on it. Also, the Java team at Apple is very responsive and can even be contacted personally with problems. Yet that same team isn’t authorized to send you a patch, and you’ll have to wait before a bug fix makes it into an OS X release – which in some cases can take up to six months. Jan Aleman, CEO of Servoy, says, “Mac is the only platform that we have to write specific ‘if’ statements for. This is because, in particular, the Swing classes aren’t paid enough attention.” According to Aleman, “This is partly a result of Apple not using Swing itself, while at the same time it’s decided to entirely map it on its own set of Aqua GUI components. This is the reason a lot of rather easy-to-fix bugs aren’t solved and actually inspired Servoy to run all our systems on our own technology. In fact, before we release a new version to our public, we run all our internal systems on it. This way, we feel the pain before our customers do.” Funny enough, Servoy’s CEO uses a Mac himself too, not just personally but also for business. “I just got tired of Windows, with the viruses, the instability, the slow boot, the lack of proper command -line tools so I made the jump. I’ve noticed that I’m not the only one. Once a developer gets to choose, he’d rather use the most hassle-free OS out there.”

������������� ������������
������������������������
���������������������������������������

���������������
������������������������
© COPYRIGHT 2007 SYS-CON MEDIA

�� ������������������������������������������������������������������������������������� � ���� ��������������������������������������������� ����������������������������������
���������������������������������������������

���� ���� � ����
�� ���� �� ��� ��������� �� �

�������

����������������� from the Worldʼs Leading i-Technology Publisher

��

� ����
��

� � ��� ����� ��� ����� � � ��� ��� �� �����

���������� ���������������
�������������������������������

ISBN 0-9777622-2-X

�����������������
��������������������������������������

�������������������������������������������������������������������
����������������������������������������������������������������������������������������������������������������� ������������������������������������������������������������������������������������������������������������������ ��������������������������������������������������������������������������������������������������������� �������������������������������������

���� ���� � ����

�������

������������������������
© COPYRIGHT 2007 SYS-CON MEDIA

����������������� from the Worldʼs Leading i-Technology Publisher

8

May 2008

JDJ.SYS-CON.com

FEATURE

Uncommon Java Bugs
Detecting them with FOSS tools
by S.G. Ganesh

ny large Java source base can have insidious and subtle bugs. Every experienced Java programmer knows that finding and fixing these bugs can be difficult and costly. Fortunately, there are a large number of free open source Java tools available that can be used to find and fix defects early in the development lifecycle. In this article, we’ll look at a few examples of specific uncommon1 or unusual defects that can happen in code and see how different Java static analysis tools detect them.

A

In this article we’ll see an uncommon defect and introduce a tool that detects it. We do this for two reasons: to illustrate the kind of unusual problems that can happen in the code and to introduce a FOSS tool that’s suitable for detecting this kind of problem.

Jlint
What does this program print?
class LongVal { public static void main(String[] s) { long l = 0x1l; System.out.format(“%x”, l); } }

Figure 1 FindBugs detects the check-for-equality-to-NaN problem

Testing
As software gets more complex and ubiquitous, it becomes more difficult to ensure high-quality code. One common method of finding bugs is testing. But testing can’t cover all paths and possibilities or enforce good programming practices. Expert knowledge in the form of manual code review by peers is one of the best ways to ensure good code quality. Code review is often used as a mandatory process step for improving the code and for finding the problems early in the software lifecycle. Since testing and manual code review processes are resource-intensive, it would be helpful to use automated tools to review code. Static analysis tools help considerably in detecting the problems early in the software lifecycle and help enhance the quality of the code significantly. There are many high-quality Java tools available in the open source domain. While it’s true that Java programs don’t suffer from traditional C/C++ problems like memory issues and major portability issues, Java software does suffer quality problems like reliability, efficiency, maintainability, and security. A brief discussion on benefits of using FOSS Java tools is given in the sidebar. Before getting into the meat of the matter, let’s discuss why bugs happen. First, it’s important to recognize that everyone makes mistakes, even experts2. Second, compilers only check for syntax and semantic violations. Errors in language or API use, which manifest themselves as bugs, aren’t detected by compilers: This is left to static analysis tools and it’s important to use them to detect coding problems. Third, programmers and engineers are under constant pressure to “get-the-work-done” under tight schedules; working under “almost-impossible-tomeet” work schedules results in code that is often substandard and filled with bugs. So, because of practical problems, most code developed in the real world has bugs and it’s worthwhile using static analysis tools to find them and fix them.

When you run it, it prints 1, not 11 – why? Let’s use a tool to detect the problem. The antic tool (that’s part of JLint) finds it:
$antic –java LongVal.java LongVal.java:3:26: May be ‘l’ is used instead of ‘1’ at the end of integer constant

To avoid this problem, it’s best to use ‘L’ (upper case letter L) as the suffix for long constants instead of ‘l’ (lower case letter l). Antic is part of the Jlint tool that’s meant to find problems related to C syntax. There are quite a few coding problems that are common to languages that use C-like syntax. The problem we saw now is just one such problem. Jlint ferrets out Java inconsistencies and bugs. It’s not a very sophisticated tool and if you don’t have experience using static analysis tools, JLint is a good tool to start with. Antic works on Java source files and Jlint works on Java class file builds. It’s a command line tool and easy-to-use. It’s available at http://jlint.sourceforge.net.

Figure 3 The DeadLock.java program results in Figure 2 Test.java program results in NullPointerException a “deadlock condition”

FindBugs
What does this program print?
class NaNTest {

The FindBugs tool is excellent. It detects correctness problems, multithreading issues, performance problems, and bad practices. It has less false positives and warns of only critical or important problems that are likely to be actual defects in code. So, if you’re pressed for time and want to look at only important problems, this tool will suit you. It runs on Java class/jar files, so no Java source files are needed to use it. And it runs in a nice standalone GUI. You can download it at http://findbugs.sourceforge.net/.

The programmer, possibly by mistake, typed ‘l’ (English letter l) instead of ‘1’ (number one)!
long l = 0x1l;

public static void main(String[] s) { double d = getVal(); if(d == Double.NaN) System.out.println(“d is NaN”); } private static double getVal() { return Double.NaN; } }

PMD
What’s wrong with the program in Listing 1? If you try to run it (as shown in Figure 2) you’ll get a NullPointerException! What could have gone wrong? PMD detects it and warns of the problem:
$ pmd Test.java text design Test.java:3 Overridable method ‘foo’ called during object construction

Benefits of Using FOSS Java Static Analysis Tools
Using Java static analysis tools can significantly improve the quality of code. Although static analysis tools can’t cover all the paths or possibilities, it provides significant help in providing coverage in detecting problems early in code; such tools can also point out programming problems and warn of violations of important and well-accepted programming rules and recommendations. Using static analysis tools has many attractive benefits. A few of the salient benefits of most of these tools are listed here. Most of the Java FOSS tools: • Can cover code that’s not covered by testing or dynamic analysis • Find many unusual or uncommon bugs that are usually missed during testing or manual code review • Work even on partial code – fully compilable source isn’t always needed • Easily integrate with popular IDEs, so it’s comfortable to use them in your favorite environment • Are usually easy-to-run –with just a button click from your IDE • Are absolutely free and high-quality

S. G. Ganesh is a research engineer at Siemens (Corporate Technology), Bangalore. Prior to Siemens, he worked at Hewlett-Packard for around five years. His areas of interest are programming languages and compilers. His latest book is 60 Tips on Object Oriented Programming (ISBN-13 978-0-07-065670-3) published by Tata McGrawHill, New Delhi.

sgganesh@gmail.com

You might be surprised to find that it doesn’t print anything! What went wrong? The FindBugs tool detects the problem and warns us about it (see Figure 1). The bug is that the condition (NaN == NaN) evaluates to false! In the condition (d == Double.NaN), this code checks to see if a floating-point value is equal to the special “Not A Number” value. The IEEE 754 floating-point standard provides the special semantics of NaN: no value is equal to NaN, including NaN itself. So, the check (d == Double.NaN) always evaluates to false. The correct check to use is the condition check Double.isNaN(x). The FindBugs tool detects this problem and aptly names it “Doomed test for equality to NaN”.

The bug in this program is that the constructor of the Base class calls an overridden method. Constructors don’t support runtime polymorphism since derived objects aren’t constructed when the base class constructor executes, the virtual method foo is called from the base class constructor. Since foo is overridden, the overridden foo calls the toString method from i, which isn’t initialized yet (note that i gets initialized only after the Derived constructor has completed executing). Because of this, the program terminates with a NullPointerException. For this reason, it’s not a recommended programming practice to call overridable methods from constructors.

10

May 2008

JDJ.SYS-CON.com

JDJ.SYS-CON.com

May 2008

11

FEATURE
The PMD tool checks for problems like possible bugs, design rule violations, duplicates, sub-optimal or dead code, suggestions for migration to newer JDK versions, J2EE, JavaBeans, JSP and JUnit rules. It , works on Java source files and can be used from the command line. Plug-ins for popular IDEs like Eclipse, JBuilder, and JCreator are also available. You can download it from http://pmd.sourceforge.net/. Acquiring multiple locks is prone to deadlock, particularly if not done in the same order or if the sleep()/wait() in the Thread is called after acquiring locks. In this program, foo and bar acquire locks in opposite order and call sleep(). Hence deadlock occurs. Acquiring multiple locks is not a recommended programming practice. However, it’s often required in practice, so when we need to acquire multiple locks, we should ensure that we acquire them in the same order in the code. Alternatively, we can consider using non-blocking locks when we attempt to acquire multiple locks. The tryLock method in the java.util.concurrent.locks.Lock interface provides this ability. It’s also recommended to release locks quickly and not hold the locks for a long time; so, it’s not recommended to use sleep/wait methods after acquiring a lock; consider using the wait/notify mechanism instead to avoid deadlocks because of holding a lock for a long time waiting for a condition to occur. The QJ-Pro tool checks for problems like conformance to coding standards, coding best practices, misuse of features, and APIs. It gives lots of violations by default, so you’d have to spend some time selecting the list of rules you want to run for your project. It works on Java source files and is easy-to-use in its standalone GUI version (shown in Figure 5). You can use its plug-ins with popular IDEs like Eclipse, JBuilder, JDeveloper or use it as an Ant job. You can get QJPro from http://qjpro.sourceforge.net/.
Listing 1
class Base { public Base() { foo(); } public void foo() { System.out.println(“In Base’s foo “); } } class Derived extends Base { public Derived() { i = new Integer(10); } public void foo() { System.out.println(“In Derived’s foo “ + i.toString()); } private Integer i; } class Test { public static void main(String [] s) { new Derived().foo(); } }

DoctorJ, and JarAnalyzer. More information and links on Java tools is provided in the Resource section.

Conclusion
We saw four specific static analysis tools that can be used to detect not-so-common defects in code. They are free, easy-to-integrate with IDEs, and easy-to-use. It’s highly recommended to use such tools to improve the quality of the software by detecting and fixing bugs early in the software lifecycle.

QJ-Pro
What’s wrong with the program in Listing 2? It’s likely that the program will hang after running successfully for few times as shown in Figure 3; in other words, this program can lead to a “deadlocked condition” (the program actually hint at this: the name of the class is Deadlock!). The QJ-Pro tool detects it as shown in Figure 4. The bug in this code is that the code acquires two locks in opposite order; and after that a sleep/wait method is called – this condition will usually result in a deadlock. Locks are the basic Java synchronization mechanism. Using locks ensures exclusive ownership for a thread while executing a critical section. Incorrect use of synchronization can lead to deadlocks. A big problem with deadlocks (as with most multithreading problems) is that deadlocks are “non-deterministic” – they need not reproduce consistently, and so it’s difficult to detect, reproduce, and fix problems related to deadlocks.

Resources
• If you’re interested in a list of the Java FOSS static analysis tools available, check http://java-source.net/open-source/code-analyzers. • “A Comparison of Bug Finding Tools for Java” by Nick Rutar, Christian B. Almazan, and Jeffrey S. Foster from the University of Maryland provides a detailed technical comparison of Bandera, ESC/Java, FindBugs, JLint and PMD tools. See http:// www.cs.umd.edu/~jfoster/papers/issre04.pdf. • If you’re using Eclipse, it’s very convenient to use Java tools as plug-ins. The list of available plug-ins for Java is at http://www.eclipseplugincentral.com/Web_Linksindex-req-viewcatlink-cid-14-orderby-rating.html. • The book Java Puzzlers: Traps, Pitfalls, and Corner Cases by Joshua Bloch and Neal Gafter covers many interesting bugs that can happen in code. Check the link http://www.javapuzzlers.com/.
1

Here the word “uncommon” means the kind of defects we talk about are not defects due to usual pro-

Other Tools
Other than the four tools covered here – Jlint, FindBugs, PMD, and QJ-Pro – there are many other FOSS tools available. For example, CheckStyle checks for adherence to coding standards such as Sun’s. You can get it from http://checkstyle.sourceforge.net/. JCSC (Java Coding Style Checker) checks for coding style adherence and for common bugs. You can get it at http://jcsc.sourceforge. net/. There are many more useful tools like Classycle, Condenser,

gramming problems like null-pointer access or incorrect casts. The defects we are going to cover are little

Listing 2
class This {} class That {} class DoSynchronize implements Runnable { public static void foo() throws InterruptedException { synchronized(This.class) { synchronized(That.class) { Thread.currentThread().sleep(10); } } } public static void bar() throws InterruptedException { synchronized(That.class) { synchronized(This.class) { Thread.currentThread().sleep(10); } } } public void run() { try { foo(); bar(); } catch (InterruptedException e) { System.out.println(“Caught interrupted exception”); } } } class DeadLock { public static void main(String []s) { DoSynchronize pc = new DoSynchronize(); Thread t1 = new Thread(pc); Thread t2 = new Thread(pc); t1.start(); t2.start(); } }

unusual that they don’t generally occur in programs; at least, they don’t occur everyday when we program.
2

To err is human: It is only that novices make more mistakes, but experts know common pitfalls, so they

write code with lesser number of defects.

Figure 4 QJ-Pro detects deadlock because of acquiring multiple locks

Figure 5 QJ-Pro detects deadlock because of acquiring multiple locks

12

May 2008

JDJ.SYS-CON.com

JDJ.SYS-CON.com

May 2008

13

JSP

Interactive Storyboarding with JSP
Introduction to J-CASE tag library
lot of rework still happens in projects applying UML techniques because of conflicts and omissions in requirements. To reduce rework, interactive storyboarding is effective, but it seems that projects using the technique are limited because of the few tools available. To improve this situation, this article introduces the J-CASE open source Tag Library that lets us describe storyboards on JSPs based on use cases, and explains how to generate document and UML diagrams from the JSPs. To reduce the rework and improve quality of the requirements, we should carefully realize the use cases in design stage. There are two approaches to realize (and see Figure 1): • Class definitions – Find classes and define object interactions. They are represented in class and sequence diagrams, etc. • Storyboarding – Describe detail scenarios based on use case descriptions, and add user interface information and system processes to be executed. Ideally both activities are necessary. However, we tend to neglect the storyboarding in software analysis and design. Use cases only capture core functional requirements; they’re not enough for stakeholders to fully understand how the system will work. They don’t know what they really want to do with the system until they see the actual system we develop. Storyboarding visualizes the use cases and shows stakeholders what the screens look like and what happens on each screen. It helps them get a better understanding and we could get more feedback before moving to implementation. Although storyboarding has lots of benefits, why isn’t it more popular?

by Masayuki Otoshi

A

One of the reasons is that there are few storyboard tools available. In storyboards, the scenarios defined in use cases are detailed, and abstract screens and process logic are also added. So the flows typically become complex, and we can’t easily maintain them without tools. The following features are required in storyboard tools: • Interactive Storyboarding – The storyboards described should be able to execute on a simulator or Web site so that stakeholders can experience the story on screens. • Easy Maintenance – The requirements represented on the storyboards are often changed. The data we need to modify has to be minimized. So tools should auto-

matically generate supplemental documents and diagrams. • Use Case Description Style – Since we’ve already captured requirements in use case descriptions, it’s better to describe storyboards using the same format so we can describe them by extending existing descriptions. The tools available today fall into two groups. One is “storyboard tools” (tools for writing storyboards), and the other is “tools for drawing diagrams” like Visio, the UML tool, and PowerPoint. Some storyboard tools are available to generate HTMLs for interactive storyboarding from screen and flow definitions. But these are commercial products and not cheap. In the case of tools for drawing diagrams, say, the UML tool, storyboards can be expressed using class diagrams and activity diagrams. However, the UML diagrams created aren’t intuitively understood. It’s not easy to imagine screens and flows from the diagrams, especially for stakeholders who aren’t familiar with UML. It also doesn’t satisfy the requirements of interactive

storyboarding and easy maintenance. A tool that supports all the features needed is J-CASE Tag Library. J-CASE takes a different approach than the other tools. First we create JSP files describing use cases and screens. It generates documents with use case style and UML diagrams for use cases and navigation maps. Compared to other GUI tools, we can call J-CASE a tool for developers. If you have expertise in JSP you’ll understand how to use , the tags, and realize it can extend custom codes using other tag libraries. In general, you may think we shouldn’t code for writing storyboards. However, I need to emphasize that there’s an advantage in writing them with JSP in the analysis and design phase. My experience is that developers typically find conflicts and missing requirements, even though we’ve spent time reviewing the requirement and specification documents. That’s because programming languages are limited in expressions and requires more precision than natural language. So, when developers can’t translate the requirements written in natural language into code, they recognize that’s something wrong or missing. Since J-CASE requires us to write some codes, we can also get similar recognitions when writing JSPs for storyboards.

Figure 3 Use Case JSP and Action JSPs

Figure 4 Use Case Frame generated by the useCase tag

Figure 5 Actions Frame generated by the actions tag

Figure 6 The login screen generated by the screen tag

Figure 7 The confirmation dialog generated by the dialog tag. Figure 9 Storyboard document with screens and process results

Create Use Case and Action JSPs
Let’s start to create a use case and storyboard using J-CASE tags. As a sample use case, I’ll use a “Log In” use case available for download on the J-CASE Web site. Before starting to create the storyboards, core scenarios have to be captured in use cases. Figure 2 shows the use case description of the “Log In” use case. J-CASE expresses the use case using two kinds of JSP Use Case JSP and Action JSP Main , . and alternative flows (flows of events) are described in Action JSPs, and the rest of information, such as use case ID, name, Brief Description, and Actor, is described in Use Case JSP . In the Use Case JSP use case information , except flows of events is described using a <jc: useCase> tag. Use Case ID, name, actor, and the link to the first Action JSP are specified in the attributes of the tag. Other additional information (Brief Description and Actor) is added using a <jc:desc> tag in the body of the <jc:useCase>. Listing 1 represents use case information of the “Log In” use case. The Use Case JSP is converted into a Use Case Frame as shown in Figure 4. By clicking the link labeled “[UC01] Log in” you can start experiencing the use case. In the Action JSP actions performed by ac, tors are described using <jc:actions> and <jc: action> tags. Each <jc:action> represents an event that the actor (end user or system) can take on the page, and the flow of the events is represented by making links between Action

Figure 8 Process results generated by the processResults tag

JSPs. Listing 2 shows two actions that the user may take on the login page. The first action represents the event of Main Flow Step 2 in Figure 2, and the second one is Alternative Flow 1 Step 1. The Action JSP is converted as in Figure 5.

Figure 10 Use case diagram generated by the generateUseCase tag

Generate Use Case Document
Once you create all Use Case and Action JSPs, you can execute a <jc:generateUseCase> tag to generate a use case document from the JSPs. The tag requires input and output attributes. The path of the Use Case JSP is specified in the input, and the HTML path of the use case document to be generated is specified in the output (see Listing 3). Refer to Figure 2 again. It’s the use case HTML generated by the <jc:generateUseCase> tag.

Figure 1 Two ways to use case realization

Visualize the Use Case
Screens, system processes, and so on aren’t typically mentioned in use cases to focus on capturing core requirements. Now that the “Log In” use case is created, it’s time to describe the screens and processes. To visualize the pages, J-CASE provides <jc: screen>, <jc:dialog>, etc. For example, the login form can be specified using HTML code in the <jc:screen> tag as shown in Listing 4. The <jc:screen> tag is displayed as shown in Figure 6.

A dialog to ask the user for a “Yes” or “No” can be represented using the <jc:dialog> tag shown in Listing 5. The code generates the dialog frame shown in Figure 7 when accessing the JSP . The logic of the system process can be defined as a Java method in a JSP declaration tag (<%! %>). In a JSP that represents a login process, you can define, for example, the authenticate method shown in Listing 6 that authenticates the user by checking the credential parameter. The method annotated with @JCaseProcess is automatically executed when the page is loaded, and you can see the execution results using the <jc:processResults> tag. In case authentication fails, you’ll see the process results as shown in Figure 8.

Generate Storyboard Document
After adding screens and processes on the JSPs, you can execute the <jc:generateUseCase> tag again to generate the storyboard document. When you access the JSP including the <jc: , generateUseCase>, the storyboard.html shown in Figure 9 is generated. You’ll also see the screens and process results you added on it this time.

Masayuki Otoshi develops Web applications for a manufacturing company as a senior developer.

otoshi@mxd.mesh.ne.jp

Figure 2 “Log In” use case description

14

May 2008

JDJ.SYS-CON.com

JDJ.SYS-CON.com

May 2008

15

JSP
Generate UML Diagrams
The <jc:generateUseCase> tag also accepts useCaseDiagram and navigationMap attributes, which generate XML files of the UML diagrams. If you execute <jc: generateUseCase> with those attributes as shown Listing 8, XML files that can be edited with EclipseUML are also generated. Figure 10 shows the use case diagram of the “Log In” use case. Figure 11 shows the navigation map that represents navigations among pages (JSPs). With these diagrams, we can verify if there are any conflicts or redundancies in defined use cases and flows. cases and the specifications required for actual implementation. While writing storyboards, you’ll find conflicts, redundancy, and omissions in the use cases. Visualized screens and flows also give us a better understanding. To get the benefits, it’s important to choose the right storyboard tool according to the requirements of your project. This article recommends using a tool that supports creating interactive storyboarding, and introduced J-CASE Tag Library. It helps you refine use cases and define better specifications.

The World’s Leading Java Resource Is Just a >Click< Away!
JDJ is the world’s premier independent, vendor-neutral print resource for the ever-expanding international community of Internet technology professionals who use Java.

Conclusion
Figure 11 Navigation map of “Log In” use case

Resources
J-CASE homepage: http://www5f.biglobe. ne.jp/~webtest/jcase/

Storyboarding is a technique to bridge a considerable gap between use

Listing 1: useCase tag
<jc:useCase id=”UC01” name=”Log in” link=”protected.jsp” actor=”Consumer User”> <jc:desc name=”Brief Description”> The user logs in the system. </jc:desc> <jc:desc name=”Actor”> Consumer user </jc:desc> </jc:useCase>

Listing 5: Dialog tag
<jc:dialog name=”Confirmation” button=”Yes,No”> Are you sure to remove the file? </jc:dialog>

Listing 6: Process definition
<%! @JCaseProcess(“The system authenticates the user.”) public String authenticate(PageContext pageContext) throws Exception { String credencial = JCaseUtils.getParameter(pageContext, “credencial”); if (!”valid”.equals(credencial)) { throw new Exception(“Invalid ID or password.”); } JCaseUtils.setAttribute(pageContext, “auth_result”, “valid”); return “Valid session has been created.”; } %>

Listing 2: Actions and action tags
<jc:actions> <jc:action name=”Correct Credencial” link=”loginProcess.jsp?credencial=valid”> The user enters correct ID and password. </jc:action> <jc:action name=”Invalid Credencial” link=”loginProcess.jsp?credencial=invalid”> The user enters invalid ID or password. </jc:action> </jc:actions>

Listing 7: Generate the storyboard document Listing 3: Generate use case document
<jc:generateUseCase input=”useCase.jsp” output=”useCase.html” /> /> <jc:generateUseCase input=”useCase.jsp” output=”storyboard.html”

! e v l y n s s: l e t h i o ition er w n i t Ed emb T o d int ec E Pr er, D M l ow mb ta al ShSepte i i , ig pecJune D u r Sc h ,
o ar F
M
www.JDJ.SYS-CON.com
or 1-888-303-5282

Listing 4: Screen tag
<jc:screen name=”Login Form” align=”center”> <table> <tr><td>User ID </td><td><input type=”text”></td></tr> <tr><td>Password</td><td><input type=”text”></td></tr> </table> <input type=”button” value=”Submit”> </jc:screen>

Listing 8: Generate UML diagrams
<jc:generateUseCase input=”useCase.jsp” output=”storyboard.html” useCaseDiagram=”useCase.uud” navigationMap=”navMap.uad” />

16

May 2008

JDJ.SYS-CON.com

OFFER SUBJECT TO CHANGE WITHOUT NOTICE

FEATURE

Functional Programming
Better living without side effects
by Joe Morrison and Kalani Thielen
ava applications have become steadily harder to understand and maintain in recent years. Object-oriented programming has proven an effective way to develop enterprise applications, but several recent trends are causing a sharp increase in code complexity. One is the increasingly common use of the Factory design pattern, abstracting away the object creation process (e.g., the creation of servlet objects by application servers, the use of Spring as a general-purpose object factory, the use of JNDI, etc.) Another is the increased use of the JavaBean pattern with reflection and annotations (e.g., for object serialization and persistence). The result is that objects have more mutable state than ever, and the code causing changes to that state is increasingly decentralized. Programs are becoming easier to write, but harder to debug as complexity spirals out of control. Functional programming is a model of computation that avoids making repeated changes to objects, and computes outputs from inputs in a stateless way. The implications are far-reaching; functional programs are more concise, easier to understand and debug, and can be executed more efficiently on modern computer hardware. Although functional programming has been around for a long time there has been a recent resurgence in interest with the advent of languages like Scala, which support functional programming and can be executed in a standard JVM. But even if you’re writing code in Java, you can use functional programming patterns and achieve many of the benefits. In this article we explain the basic principles of functional programming, and show some functional patterns that you can start using in your Java programs immediately.

The Rise of

J

oriented paradigm (or any paradigm) stops people from violating unwritten rules. As a result, you have to understand exactly how the ArrayReader and CharReader objects interact to predict what will happen. The problem is magnified if your program is multithreaded. The fundamental problem is that each object behaves differently depending on its current state. (Obviously the second time you call read() on an ArrayReader you get a different result from the first time you call it.) That means that in general, if you want to understand what any particular operation is doing to an object, you have to know exactly what state the object was in before you invoked the operation. But to know that you have to know at what point the object was created, and the exact sequence of subsequent operations that might have changed the object’s internal state. That’s easy if the object reference is assigned to only a local variable and never shared, but if the object reference can be obtained from anywhere in your application via reflection or a directory service, then all bets are off.

</list> </constructor-arg> </bean> <bean id=”charReader” class=”CharReader”> <constructor-arg ref=”arrayReader” /> </bean> </beans>

Note that we used constructor-based dependency injection, but it’s common to use setter-based injection in which case we would have added setters to each class for the String array and Reader dependencies, thus creating even more mutable state. By changing this XML file we can cause our program to behave completely differently. Here is a version, for example, that provides the CharReader object with its own private ArrayReader and eliminates the confusing sharing of the mutable state:
<beans> <bean id=”arrayReader” class=”ArrayReader”> <constructor-arg> <list> <value>Foo</value> <value>Bar</value> <value>Baz</value> </list> </constructor-arg> </bean> <bean id=”charReader” class=”CharReader”>

starting from any type of Reader and returning its output one character at a time. See Listing 1. Notice that both ArrayReader and CharReader have private, internal state. It’s part of the benefit of object-oriented programming that these implementations could be changed without affecting any other code as long as the public interfaces are preserved. But in real life object-oriented programming, subtle problems begin to emerge due to the too frequent use of mutable (i.e., changeable) state. Even this simple Reader example can be hard to understand if readers are shared or accessed concurrently from multiple threads. For example, what does the following code example do?
public static void main(String[] args) { Reader arrayReader = new ArrayReader (new String[] { “Foo”, “Bar”, “Baz” }); Reader charReader = new CharReader (arrayReader); String s = arrayReader.read(); while (s != null) { System.out.println (s); System.out.println (charReader.read()); s = arrayReader.read(); } } // uh oh

Adding Fuel to the Fire by Abstracting Away Object Creation
Design patterns that abstract away the process of object creation bring a huge amount of benefit in terms of software configuration management and testability. Such design patterns have become enormously popular in recent years, but they are problematic when combined with the use of mutable state. A programmer cannot determine which classes a particular code sequence will instantiate just by looking at the code, and therefore cannot reason about the code until the runtime behavior of the object factory is fully understood. For example, let’s say we decide to rewrite our example based on Spring retaining the exact same behavior as before:
public static void main(String[] args) { BeanFactory factory = new XmlBeanFactory(new FileSystemResource(“ applicationContext.xml”)); Reader arrayReader = (Reader) factory.getBean (“arrayReader”); Reader charReader = (Reader) factory.getBean (“charReader”); String s = arrayReader.read(); while (s != null) { System.out.println (s); System.out.println (charReader.read()); s = arrayReader.read(); } }

<constructor-arg> <bean class=”ArrayReader”> <constructor-arg> <list> <value>Hello</value> </list> </constructor-arg> </bean> </constructor-arg> </bean> </beans>

Joe Morrison is a managing consultant at Lab49, and has over 20 years of experience leading engineering teams in designing and building complex networkbased applications. His projects have ranged from distributed object research at Verizon Laboratories, to value chain management software at Benchmarking Partners in Boston, to in-the-trenches SOA projects for financial services firms in New York. Joe has a BMath degree in computer science from University of Waterloo, and a MS in computer science from MIT. He is a regular blogger on http://blog.lab49.com/.

This version produces the output:
Foo H Bar e Baz l

As it turns out, the result is:
Foo B Baz a

The Problem
Object-oriented programming is about being able to define packages of state, together with operations on that state. Typical object-oriented languages support encapsulation, i.e., the notion that the state can only be accessed via the defined operations, and polymorphism, i.e., the notion that objects of different types can be treated uniformly. Here is an example that shows these concepts. The Reader interface defines an operation for retrieving information one String at a time. The ArrayReader class implements this interface, starting from an array of Strings and returning them one at a time. The CharReader class also implements the same interface,

The underlying classes have not been changed at all, nor has the main logic, but we have left the instantiation of the classes to the Spring framework. Would you be able to understand the code sequence above if you hadn’t read the introduction to this article? For completeness, here is the applicationContext.xml file:
<beans> <bean id=”arrayReader” class=”ArrayReader”> <constructor-arg> <list> <value>Foo</value> <value>Bar</value> <value>Baz</value>

joe.morrison@lab49.com

The B and the a on the second and fourth line of the output come from the word “Bar.” It’s confusing because the loop alternates each call to arrayReader.read() that pops a word from the ArrayReader, with a call to charReader.read() that pops a word from the same ArrayReader every time it runs out of characters. The spirit of these classes was to call either the ArrayReader or the CharReader in a loop, but not to make calls to the same ArrayReader both directly and indirectly via the CharReader class. But nothing in the object-

With this change to the configuration file, the main loop prints Foo, Bar, and Baz as expected, and the CharReader prints out individual characters from the word Hello. They no longer interfere with each other. The question of whether or not the main ArrayReader’s state is shared (creating the undesired interaction between the classes) depends on the application configuration file, which illustrates why the configuration file must be read and understood to predict the

Kalani Thielen is a Lab49 technology consultant, working in the financial services industry. Prior to joining Lab49 in 2006, he worked for six years developing products for the publishing, advertising, and communications industries. As a specialist in programming language theory, his present work focuses on the development and certification of compilers for bond pricing and trading languages.

kthielen@lab49.com

18

May 2008

JDJ.SYS-CON.com

JDJ.SYS-CON.com

May 2008

19

FEATURE
behavior of the actual program. When we are talking about configuration files running to hundreds and thousands of lines of XML, this can be daunting. This is not a straw man argument. Code like this is getting written and deployed every day in mission-critical enterprise applications. We’ve had to debug some of it. We are not saying that object-oriented programming is bad, or that it’s wrong to abstract away the process of object creation. On the contrary, our point is that mutable state makes programs hard to understand, and modern programming practices magnify the problem. Complexity in software is inescapable, but unnecessary complexity is, well, unnecessary. By attacking the problem at its root (mutable state), we hope to have our cake and eat it too.
1 + 2 + sum [3, 4, 5] 1 + 2 + sum 3:[4, 5] 1 + 2 + 3 + sum [4, 5] 1 + 2 + 3 + sum 4:[5] 1 + 2 + 3 + 4 + sum [5] 1 + 2 + 3 + 4 + sum 5:[] 1 + 2 + 3 + 4 + 5 + sum [] 1 + 2 + 3 + 4 + 5 + 0

Swiss Federal Institute of Technology, and one of the designers of Java generics. Scala is a multi-paradigm language, smoothly integrating features of both object-oriented and functional languages. Most importantly it is fully interoperable with Java. It compiles to JVM bytecodes (i.e., standard .class files), Java libraries can be used freely in Scala programs, and it is possible to inherit from Java classes and implement Java interfaces directly in Scala. An Eclipse plug-in is even available.

def sum (l: List[Int]): Int = { l match { case Nil => 0 case ::(x,xs) => x + sum(xs) } } def main(args: Array[String]) { println (sum(List(1, 2, 3, 4, 5))); } }

Functional Programming: An Alternative Approach
To understand better how functional programming can simplify this problem, we’ll first look at an even simpler problem in Haskell (one of the most mature modern functional programming languages). If you only remember one thing about functional programming, it should be this central idea: that it should be possible to substitute a function call with its result, without changing the meaning of a program. This simple principle (generally referred to as referential transparency) has radical implications. At its best, this idea strengthens the intuition we’ve developed from high school algebra that, difficult as a problem may be, we can write it out in its entirety and solve it by progressively simplifying it. Rather than taking on the full-grown horror of a decades-old legacy system, let’s consider a very simple functional program and analyze it in ways representative of real-life concerns.
sum [] = 0 sum x:xs = x + sum xs

Having made each step of the computation explicit, the derivation of the final result is clear. What’s more, we can be certain that each step in the above derivation completely describes the computation, as we’ve given up the possibility of implicit “side effects” happening between steps. You can imagine that if the “sum” function had a side-effect (like updating the input list) this simple two-line example would become much more difficult to understand. Because a functional program implies that you can always substitute a function call with its result, there are two very important things that our compiler can do to help us without any effort on our part. The first is that, according to the principle of referential transparency, the compiler can substitute the final result for the call to “sum” at compile-time, without changing the behavior of the program. This has the effect, in our example, of doing no runtime computation at all! In more realistic cases, the compiler may not be able to compute the entire function ahead of time, but with this principle as a guide it can still simplify the inevitable runtime computation by partially evaluating as much of it as possible at compile-time. The second thing the compiler can do is to perform the final computation in parallel where possible. Given some simple properties of the functions involved (in this case, the fact that a + b + c = a + (b + c) = (a + b) + c), the compiler could easily generate code to compute the final sum as (with concurrent evaluation denoted by parentheses):
1 + 2 + 3 + 4 + 5 + 0 (1 + 2) + (3 + 4) + (5 + 0) 3 + 7 + 5 (3 + 7) + (5) 10 + 5 (10 + 5) 15

Installation Instructions via the Eclipse Plug-in
If you’re an Eclipse user, it’s easy to get started with Scala by installing the Scala Eclipse Plug-in. You don’t even have to install Scala first. Just select:
Help -> Software Updates -> Find and Install -> Search for new features to install

and create a new remote site called “Scala Plugin Update Site” with this URL: http://scala-lang.org/downloads/scala-plugin Install the feature Scala Plugin UpdateSite. If you get an error that package org.eclipse.pde.runtime is missing, then go back to:
Help -> Software Updates -> Find and Install -> Search for new features to install

This is slightly more verbose, but similar in spirit to the twoline Haskell example we started with. The Haskell version didn’t declare a package, enclosing class, or Main function, so a fair comparison is to look at only the sum function that is six lines long in Scala and includes type declarations. Note the patternmatching syntax, for example, the use of :: to match a list and split the head node from the remaining nodes. This is an example of a nice Scala feature called case classes that lets you write pattern-matching case statements for your own classes as well as built-in ones. Note that it’s not the objective of this paper to be a Scala tutorial. There are already many of those on the Web. But we want to introduce Scala because it provides excellent support for functional programming, fits well with the Java technology stack, and is gaining momentum in the Java community.
This sum example we started with may be simple, but it already illustrates how functional programming is different. The obvious way to code this in Java would have been to initialize a counter to zero, iterate through the list, and keep modifying the counter by adding the next value. If you’ve been writing Java code for a long time, you may not realize how deeply ingrained it is for us to solve problems by constantly modifying variables, calling methods that modify objects, and so on. But in functional programming, your first instinct should be to think of every problem in terms of computing an output directly from an input, breaking it into smaller problems that you solve recursively if necessary.

and select The Eclipse Project Updates, expand the category corresponding to your version of Eclipse, and select the Eclipse Plugin Development Environment. Install it and restart Eclipse. That plug-in includes the required org.eclipse.pde.runtime package, so once it’s installed you should be able to install the Scala plug-in. If you are not an Eclipse user, you can install Scala the traditional way, starting from this URL: http://www.scala-lang.org/downloads/index.html Once you’ve installed Scala, create a new Scala Project. Create a package called com.lab49.example and within it create a Scala Object called Main with the following contents:
package com.lab49.example;

This definition is intended to describe a function, “sum,” that adds up all of the numbers in a list. If the input list is empty (denoted by empty square brackets) the sum is 0. Otherwise we can break the list into its head (“x”) and its tail (“xs” – read as the plural of “x”), in which case the sum is just the head plus the sum of the tail. It might help clarify this to read the function out loud in English: “The sum of an empty list is zero. Otherwise, the list has an initial value x followed by the remaining values xs, and the sum is x plus the sum of the xs.” This is a recursive definition, and although it may at first glance seem like an endless loop, the sum will always decrease the length of the input list by one until the simplest case (the empty list) is reached. Let’s try it out on an example:
sum [1, 2, 3, 4, 5]

Let’s come back to our original problem now and try to apply these concepts.

Rewriting Our Original Example
First let’s consider the Reader interface we started with:
public interface Reader {

Using the principle of referential transparency, and substituting the appropriate body of the “sum” function at each step, we can proceed to rewrite this as follows:
sum 1:[2, 3, 4, 5] 1 + sum [2, 3, 4, 5] 1 + sum 2:[3, 4, 5]

Remarkably, the compiler can (given just these few reasonable assumptions) produce a very specialized, efficient executable from our compact functional program. The key to passing all of this complexity off to the compiler is that we go out of our way to leave the compiler as many implementation options as possible. To summarize this viewpoint: functional programs describe what is to be computed, allowing functional compilers to decide how to compute it. Unnecessary complexity creeps into software projects where these problems of what and how are intermixed.

object Main { def main(args: Array[String]) { println(“Hello, world!”) } } }

String read();

Select Run as Scala Application. If it displays Hello, world then congratulations! You have just written your first Scala application. Now let’s try rewriting the sum function in Scala:
package com.lab49.example; object Main {

Introduction to Scala
A good way for Java programmers to experiment with functional programming concepts is to give Scala a try. Scala is an interesting programming language first released in 2003 by Martin Odersky, a computer science professor at the

The idea of this interface is to provide access to a list of strings one at a time, presumably so we can do something to those strings. But the fundamental idea of this interface is not in keeping with functional programming, since every time you call read you change the state of the object. Can we come up with a more functional way of doing the same thing? Indeed we can, by changing the responsibilities slightly. Instead of feeding strings to a consumer one at a time, we will instead ask the consumer to tell us what work they want done on each string (using a callback) then we will do it to all of the strings. In Scala the equivalent to a Java interface is a trait, so our revised example will look like this:

20

May 2008

JDJ.SYS-CON.com

JDJ.SYS-CON.com

May 2008

21

FEATURE
trait Reader { def repeatForEach (f: String => Unit) = () }

Now let’s write the CharReader class. It requires a Reader upon construction, and provides character-by-character access to all of the items in that reader:
class CharReader (r: Reader) extends Reader { override def repeatForEach (f: String => Unit) = { r.repeatForEach ((s: String) => s.toList.foreach ((c: Char) => f (c.toString))); } }

���������������������������
���������������������������������

We are replacing the read method with one called repeatForEach, which takes a callback as an argument. The callback must take a string as input and return nothing as output (that’s what the Unit type means in Scala), the idea being that repeatForEach will invoke the callback for each individual string. We say = () to declare that by default, this method does nothing. Now we need an equivalent to the ArrayReader that takes a list of strings at construction time, and can be used later to provide one-at-a-time access to those strings. In Scala you don’t implement an interface, you extend a trait. Furthermore, although Scala supports an Array type, we want to use the List type, which is immutable and emphasizes our functional style. So we end up with this:
class ArrayReader (strings : List[String]) extends Reader { override def repeatForEach (f: String => Unit) = { strings.foreach (f); } }

This defines a class ArrayReader that extends the Reader trait and that requires a list of Strings upon construction. Note that in Scala you can specify arguments in a class definition (almost like a function definition). This means that the arguments must be provided in every use of the constructor and they automatically become available as immutable class members. Thus the following code in Scala:
class ArrayReader (strings : List[String]) { }

This is more difficult to understand, so let’s work through it step-by-step. The CharReader takes any kind of Reader as an argument upon construction, and is also a Reader itself – just like in our original example. Like the ArrayReader it provides a repeatForEach method that takes a callback argument. Whenever this method is called with a callback argument f, the CharReader calls repeatForEach on its underlying reader, providing its own callback, which calls toList.foreach on each String, allowing each character to be processed individually. The callback f is invoked on each character after converting it to a one-character string. Scala supports type inference, meaning that you can omit many of the type declarations without sacrificing any type safety at all. Thus you can write this more compactly this way:
class CharReader (r: Reader) extends Reader { override def repeatForEach (f: String => Unit) = { r.repeatForEach (s => s.toList.foreach (c => f (c.toString))); } }

�������������������������
������������������������������������� ��������������������������������
���������������������������������������
�������������������������������������������������������� ��������������������������������������������������������� ������������������������������������������������������� ������������������������������������������������������ ������������������������������������������������������� ������������������������������������������������������ ���������������������������������� ������������������������� ��������������������������������������������������������� ��������������������������������������������������������� ���������������������������������������������������������� ������������������������� ������������������������������������������������������ ��������������������������������������������������������� ����������������������������������������������������� ���������������������������������������������������������� ������������������������������������������������������ ������������������������������������������������������� � � ������������������������������������������������������� ������������������������������������������������������� ��������������������������������������������������������� �������������������������������������������������� �������������������������������������������������������� ������������������������������������������������������� ���������������������������������������������������������� ������������������������������������������������������������� ����������������������������������������������������������� ����������������������������������������������� ��� ��������������������� ��� ������������������������������ ��� �������������� ��� �������������� ��� �������������� ��� �����������������������������

Now let’s try using our new classes:
object Main {

is analogous to the following Java code:
public class ArrayReader { private final List<String> strings; public ArrayReader (List<String> strings) { this.strings = strings; } } }

def main(args: Array[String]) { val arrayReader: Reader = new ArrayReader(List(“Foo”, “Bar”, “Baz”)); val charReader: Reader = new CharReader (arrayReader); arrayReader.repeatForEach (println); charReader.repeatForEach (println); }

Once you have an instance of the Scala ArrayReader class, at any point in the future you can call repeatForEach and pass it a callback, and it will perform the callback on each of the strings in the original list, in sequence. This is equivalent in usefulness to our original ArrayReader class. For example, here is how you would print out all of the strings:
object Main { def main(args: Array[String]) { val arrayReader: Reader = new ArrayReader(List(“Foo”, “Bar”, “Baz”)); arrayReader.repeatForEach (println); } }

Here’s the output:
Foo Bar Baz F o o B a r B a z

������������������

�������������������������������������������������������� ��������������������������������������������������������� ����������������������������������������������������������������� �����������������������������������

22

May 2008

JDJ.SYS-CON.com

��������������������

������������������������

FEATURE
This looks surprisingly like our original example, doesn’t it? We have a Reader interface with ArrayReader and CharReader implementations with roughly the same meanings as in the corresponding Java versions. The only difference is that this example has no mutable state whatsoever. There is no point at which any variable is modified from an old value to a new value. Although state is still shared between the arrayReader and charReader objects (the charReader contains a reference to the arrayReader), it’s simply not possible for them to interact inappropriately. Whenever you call:
arrayReader.repeatForEach (...)

Not all functional programming idioms can be translated into Java, but some of the simpler ones can, and although they may seem unnatural at first, they do bring benefits. It’s always worth asking the question: Can I solve this problem without the use of mutable state?

tion of the aggregate function, but it’s on a locally created unshared object, so it’s acceptable. Programming languages like Scala that are designed for functional programming would not even require that, since they support immutable collections.

A Reconciliation Example
Say you have two lists of information that have to be reconciled. You want to know which items are in one list and not in the other, and vice versa. This kind of problem sometimes crops up in financial applications, and is often solved by traversing both lists and building a data structure to store the differences (e.g., a hash table). A more functional solution to the problem is to write code that can subtract the contents of one list from another as shown in Listing 3. This example shows a functional approach to reconciling lists of information, but also shows the kind of compromise that has to be made when doing this style of programming in Java. Unfortunately the built-in Java Collection classes do not efficiently support immutable lists, so there is no way in the diff function to build up the result without either using mutation or creating our own immutable collection classes. We chose a practical approach: Create a fresh LinkedList object when the recursion bottoms out then mutate it repeatedly by calling addFirst to build up the result. Although this is not functional, we are doing it in only one place, and we are changing an object that was created within the diff method, is never shared, and has no permanent state after the initial call returns. So the implementation of diff is “mostly functional,” and the rest of the example is completely functional. This solution has most of the virtues of functional programming in terms of avoiding the problems of shared mutable state, and doesn’t destroy its input lists the way the removeAll method would (as defined in the Java Collection classes).

Summary
The use of mutable state makes programs hard to understand, especially in conjunction with currently popular programming practices in which objects are created indirectly and state sharing is not obvious from reading the code. Furthermore in multithreaded environments, programs relying on mutable state are prone to race conditions, requiring the use of locking that can impact performance and make programs even harder to understand and debug. Functional programming offers an alternative approach to solving computing problems based on transforming inputs into outputs in a stateless way. Functional programs are referentially transparent, meaning function calls can always be substituted with their results without changing

the meaning of the program. The loss of expressive power from having to avoid the use of mutable state is compensated for by providing better support for manipulating function objects and combining them in useful ways. You can start using rudimentary functional programming techniques in Java immediately, but advanced techniques require better programming language support than Java offers. Scala is a useful language for Java programmers to explore, as it provides excellent support for functional programming while fitting smoothly into the Java developer’s world.

Additional Reading
• Wikipedia: http://en.wikipedia.org/wiki/Functional_ programming. • Can Your Programming Language Do This?: http://www. joelonsoftware.com/items/2006/08/01.html. • Bill Venners, Martin Odersky, and Lex Spoon. First Steps to Scala. May 9, 2007: http://www.artima.com/scalazine/ articles/steps.html.

a given input of ... will always produce exactly the same result. There isn’t any method for resetting the iterator either, because there’s no such concept in this design. You can call arrayReader.repeatForEach as many times as you like, and each time it will iterate through the entire list with no possibility of problems occurring. It can be used in a multithreaded environment and race conditions won’t even be possible. Race conditions can only occur when you have mutable state. It may seem like cheating to convert the program to a functional one by changing the design to use callbacks, but we argue that it’s fair game. Functional programming is all about programming without side effects (i.e., mutating state), and that means coming up with new idioms for solving familiar problems. In this case, the original iterator-based solution was very typical Java code. To achieve the same thing without side effects we had to pass callbacks around (also known as closures, function objects, or anonymous functions) but this is very typical in functional languages, which typically provide a clean, elegant syntax to support that style of programming.

Listing 1
public interface Reader { String read(); } public class ArrayReader implements Reader { private String[] sourceArray; private int currentIndex; public ArrayReader(String[] s) { sourceArray = s; currentIndex = 0; } public String read() { if (sourceArray != null && currentIndex < sourceArray.length) { return sourceArray[currentIndex++]; } return null; }

Listing 2
public interface StringCallback { public void doString (final String s); } public interface Reader { public void repeatForEach (final StringCallback f); } public class ArrayReader implements Reader { private final String[] strings; public ArrayReader (final String[] strings) { this.strings = strings; } public void repeatForEach(final StringCallback f) { for (String s : strings) { f.doString(s); } }

Functional Programming in Java
Let’s explore how we can introduce functional programming concepts into our Java code, in case our managers are not yet ready to allow the use of Scala for commercial software development. Unfortunately Java lacks many advanced functional programming features and its syntax is not ideal for this. Higher order functions (i.e., functions that operate on other functions) are almost impossible to express, especially if you want to make them strongly typed. (Defining strongly typed higher order functions requires the use of generics and Java’s “type erasure” implementation of generics throws away a significant amount of type information at runtime in the interest of efficiency. Martin Odersky giveth and Martin Odersky taketh away.) That being said, the recent support in Java for anonymous classes still allows us to represent our Scala Reader example reasonably faithfully in Java. The reader example is revisited on Listing 2. This Java solution is written in a functional style, although it may look awkward to most Java programmers. We had to introduce a StringCallback interface to represent the callback, and used the new anonymous class capability in several places. However this solution has all the virtues of the Scala solution. It is immune to the problems associated with shared mutable state, and can be used safely in a multithreaded environment without any need for locking or any risk of race conditions.

A Tree Aggregation Example
Say you have a tree of any type of object. Let’s keep it simple and represent the tree as an array of Java objects, each element of which could be a leaf node or another array. You might want to calculate a value based on all elements of the tree. A functional approach to this problem is to define a TreeWalker that can traverse any tree and accept a user-provided aggregation function. See Listing 4. Once again we rely on Java’s new anonymous class capability, but we avoid the use of generics because Java’s “type erasure” implementation of generics would not allow us to use instanceof. In this example we created a tree of numbers called myTree with eight nodes. Then we used the TreeWalker twice, each time passing it a different aggregation rule; one that knows how to aggregate a tree by adding, and another that knows how to aggregate a tree by multiplying. The point is that tree traversal and aggregation have been factored into a general-purpose capability, and complex operations can be performed on the tree without any need for mutable state. As in the previous example, there is brief use of mutable state in the implementa}

public class CharReader implements Reader { private Reader reader; private String currentString; public CharReader (Reader r) { reader = r; currentString = null; } public String read () { while (currentString == null || currentString.length() == 0) { currentString = reader.read(); if (currentString == null) return null; } String s = currentString.substring(0, 1); currentString = currentString.substring(1); return s;

}

public class CharReader implements Reader { private final Reader r; public CharReader (final Reader r) { this.r = r; } public void repeatForEach(final StringCallback f) { r.repeatForEach(new StringCallback() { public void doString(String s) { for (char c : s.toCharArray()) { f.doString(Character.toString(c)); } } });

}

}

}

}

24

May 2008

JDJ.SYS-CON.com

JDJ.SYS-CON.com

May 2008

25

FEATURE

public class Main { public static void main(String[] args) { final Reader arrayReader = new ArrayReader(new String[] { “Foo”, “Bar”, “Baz” }); final Reader charReader = new CharReader (arrayReader); arrayReader.repeatForEach(new StringCallback() { public void doString(String s) { System.out.println (s); } }); charReader.repeatForEach(new StringCallback() { public void doString(String s) { System.out.println (s); } }); } } Output: Foo Bar Baz F o o B a r B a z } } } } }

System.out.println (“In first list but not second:”); for (String s : reconciler.diff(firstList, secondList)) { System.out.println (“ “ + s); } System.out.println (“In second list but not first:”); for (String s : reconciler.diff(secondList, firstList)) { System.out.println (“ “ + s); }

Listing 4
public interface Aggregator { public Object initialValue (); public Object combine (Object x, Object y);

public class TreeWalker { public Object aggregate (Object[] tree, Aggregator a) { Object o = a.initialValue(); for (Object item : tree) { if (item instanceof Object[]) { o = a.combine(o, aggregate((Object[])item, a)); } else { o = a.combine(o, item); } } return o;

�����������������������������������������������
���������������������������
������������������������������������ � ����������������������������������� ��������������������������������������� �������������������������������������� ���������������������������������������� ������������������������������������� ���������������������������������������� ��������������������������������������� ����������������� ������������������������������������������������������������� ����������������������������������������� ������������� ������������������������������������������������������ ��������������������������������������������������������� �������������������������������������������������������������� ��������������������������������������������������������������� ���������������������������������������������������������� ������������������������������������������� �������������������������������������������������������������� ������������������������������������������������������������� ������������������������������������������������������� ������ ������������ ������������������������������������������ �������������������������������������������������� ����������������������������������������������������������� ����������������������������������������������������������� ����������������������������������������������������������� �������������������������������������������������������������� ������������������������������������������������ ������� ����������������������������������������������������������� �������������������������������������������������������������� ������������������������������������������������������������ ������������������������������������������������������������

public class Main {

Listing 3
public class Reconciler<T> { public LinkedList<T> diff (final List<T> l1, final List<T> l2) { if (l1 == null) return null; if (l1.size() == 0) return new LinkedList<T>(); final T head = l1.get(0); final List<T> tail = l1.subList(1, l1.size()); if (l2.contains(head)) return diff (tail, l2); LinkedList<T> result = diff (tail, l2); result.addFirst(head); return result; } public static void main(String[] args) { final List<String> firstList = Arrays.asList(new String[] {“Adam”, “Bob”, “Charlie”}); final List<String> secondList = Arrays.asList(new String[] {“Bob”, “David”}); final Reconciler<String> reconciler = new Reconciler<String>(); } public static void main(String[] args) { Object[] myTree = new Object [] { 4, 7, new Object[] {3, 8}, new Object[] {2, new Object[] { 5, 9 }}, 6 }; TreeWalker treeWalker = new TreeWalker(); Object sum = treeWalker.aggregate(myTree, new Aggregator() { public Object initialValue() { return 0; } public Object combine(Object x, Object y) { return ((Integer)x).intValue() + ((Integer)y).intValue(); } }); System.out.println (“Sum is “ + sum); Object product = treeWalker.aggregate(myTree, new Aggregator() { public Object initialValue() { return 1; } public Object combine(Object x, Object y) { return ((Integer)x).intValue() * ((Integer)y).intValue(); } }); System.out.println (“Product is “ + product); }

����������
�������������������� ����������������������

��������������������������������������������������� ��������������������������������������������� �������� ������������������������������������������������������ ����������������������������������������������������� �������������������������������������������������������� ��������������������������������������������������� ������������������������������������������������������ ������������������������������������������������������� ����������������������������������������������������������� ������������������������������������������������ �������� ������������������������������������������������������� ����������������������������������������������������������� ����������������������������������������������������� ����������������������������������������������������������� ����������������������������������������������������������� ������������������������������������������������������������ �����������������������������������������

��������������������

26

May 2008

JDJ.SYS-CON.com

���������������������������������
������������������������������������������� �����������������������������

�����������������������

��

FEATURE

the AdminClient on a regular basis. It works great and is reliable – that’s a big part of why Axis has been such a huge success. Still, Web Services have evolved and you need more than Axis to take advantage of these advances. For a simple service like the one in Listing 1, it might not be too hard to change the code to get it to work on a newer Web Service stack. It would still take some work. That work only goes up for more complicated services. This is where WSAS comes in. Let’s take a look at just how easy the upgrade is with WSAS.

Figure 4 Axis service deployed

Redeploying to WSAS: Using WSDD

by Michael Galpin

Migrating with WSAS

f you’ve been working with Web Services for a long time, chances are you’ve worked with Apache Axis and that you have an Axis Web Service somewhere in your code base. You probably also know about the many improvements in Axis2, especially around support for the more modern WS-* standards. So maybe you’ve been planning on migrating these old Axis services, but it can be hard to justify spending a lot of time on something that’s working just fine. However, there’s a great new migration path available to you: WSO2’s Web Services Application Server (WSAS.) With WSAS, you can take your existing Axis Web Service, redeploy it to WSAS, and then with just a few clicks enable things like WS-Security and WS-Reliable Messaging. There’s no need to rewrite or regenerate any code. Does this sound too good to be true? It’s not, just read on.

I

submitting purchase orders. Let’s take a look at its WSDD file shown in Listing 1. This is a fairly typical WSDD. It describes two services. Each service has several operations that can be called. It also describes mappings between the parameter types of the service to Java classes. To deploy this you’d use Axis’s deployment tool, the AdminClient. If you’ve been using Axis over the years, all of this is old news. You’ve probably seen dozens of WSDDs and used

Prerequisites
In this article, you’ll work with WSO2 WSAS. You’ll definitely want to download the latest version of WSAS. You can run it with any Java Web container, such as Tomcat. Or you can run it in standalone mode. This article assumes experience with Axis, and in particular with deploying an Axis Web Service. It references a sample from Axis 1.4. Obviously a familiarity with Web Services in general, and with some of the modern WS-* standards is very useful.

Figure 1 WSAS Management Console: Services Tab

Example of an Existing Axis Web Service
Let’s take a typical starting point for a lot of people. You have a service you developed and used Axis to expose as a Web Service. There’s a good chance that the service might not have been originally intended to be a Web Service. Maybe it was just an internal service used by one application. You then realized it would be valuable to other applications you were developing and used Axis to do this. There are a couple of different ways to do this with Axis, but the most powerful and flexible is to use Axis’s Web Service Deployment Descriptor (WSDD.) Let’s take a look at a sample WSDD. Axis ships several great samples. We’ll use the bid-buy sample. It mimics an e-commerce system. It exposes a Web Service for doing typical e-commerce tasks like requesting a price quote and

Figure 2 WSAS Management Console: Services Tab

Michael Galpin is an architect at eBay in San Jose, CA. He’s been developing software since 1998, and holds a degree in mathematics from the California Institute of Technology.

You can upgrade your Axis service with WSAS very easily. There’s no code to change. There’s no code to generate or regenerate. There’s no configuration file to alter or add. All you need is a WSDD and JAR file with the classes for the service. That’s it. If you’ve been using Axis, there’s a good chance you already have both of these laying around already. For the Axis bid-buy sample we’re using, all we have to do is put the class files in a JAR. To do this we move them into a directory structure reflecting the package structure (samples.bidbuy) and then run Java’s jar command as shown in Listing 2 (Listings 2 and 3 can be downloaded from the online version of this article at http://jdj.sys-con. com). Now we’re ready to get started with WSAS. Load up the Management Console. Go to the Services tab and you should see something similar to Figure 1. Notice the Upload Axis1 Service (.wsdd) Option. That’s exactly what we want to do. Go ahead and choose that and you’ll see a screen similar to Figure 2. This is a straightforward interface. Simply use the Browse buttons to locate the deployment descriptor for your Web Service and the jar file you created for your service. Then click upload. You should get a confirmation screen similar to Figure 3. The upload is asynchronous, but shortly afterwards your list of Service Groups should show a “deploy.wsdd” (that was the name of the deployment descriptor from the bidbuy sample) similar to Figure 4. That’s all you have to do! Your crusty old Axis Web Service is now running on the super-modern WSAS Web Service stack. Your Web Service is going to benefit greatly even if this is where you stop. Since it’s running on WSAS (and thus Axis2) you’ll get great performance benefits. WSAS uses a powerful combination of a StAX parser and the Axis Object Model (AXIOM) for parsing SOAP. This is much more efficient in terms of both speed and memory usage than Axis1. The Axis2 architecture also lets you plug in whatever data binding you want, such as JAXB. It also enables Message Transmission Optimization (MTOM) for your service, by default. This allows for much more efficient transport of binary data if your service accepts or receives binary data. Of course you probably don’t want to stop here, as now there’s a whole new world of options that you’ve just enabled by migrating to WSAS. Let’s take a look at those now.

Figure 5 Link to Bid WSDL

Figure 6 Bid WSDL

Figure 7 Manage the bid service

Examining the Service on WSAS
Figure 3 Upload of WSDD confirmed

mike.sr@gmail.com

In our list of services, click on the WSDL 2.0 link for the Bid Service, as shown in Figure 5. This should bring a graphical representation of the WSDL

file that WSAS has created to describe your service. It should look similar to Figure 6. One thing to notice here is the “invokeAxis1Service” section. The bid-buy sample we picked was an RPC-encoded service, a style of SOAP that’s been deprecated because of its brittleness. So what has WSAS done here? First, just because RPC-encoding is far from a best practice doesn’t mean that your service isn’t using it. You could

28

May 2008

JDJ.SYS-CON.com

JDJ.SYS-CON.com

May 2008

29

FEATURE
Second, WSAS has created more modern bindings for your service. This is for either existing clients that can be re-coded or new clients who want to take advantage of new Web Service standards. Again, you didn’t have to write any code, yet now there’s a SOAP 1.2 binding to your service. This is important, because now we can start enabling other SOAP-based technologies, i.e., various WS-* technologies. how WSAS made sure to maintain backwards compatibility with the original service, even though the original service used the deprecated RPC-encoding format. Once we brought our service into WSAS, we could easily enable WS-Security and WS-Reliable Messaging. Finally, WSAS made it especially easy to pick a powerful Security Configuration, automatically managing the Policy for us.

Managing the Service on WSAS
Go back to your list of service, but this time click on the bid link under services. This should bring up the interface shown in Figure 7. There’s a lot you can do here, but for now let’s click on the Manage Module Engagements link. That should bring up the interface shown in Figure 8. The various modules in the Module combo box represent Axis2 modules that implement various WS-*. Let’s say we’re interested in WS-Security. To enable this, we simply pick rampart from the list, as shown in Figure 9. Click the Engage button, and just like that WSAS will activate its WS-Security module for your service, as shown in Figure 10. Similarly, you can pick sandesha from the Module list and WSAS will enable WS-Reliable Messaging for your service. Let’s take a look at some of the security options we have available to us.

Resources
• Take a look at the WS-RM specification from the developerWorks library (http://www.ibm.com/developerworks/ library/specification/ws-rm/). • Learn about the benefits of WS-Security in the developerWorks article Implementing WS-Security (http://www.ibm. com/developerworks/webservices/library/ws-security. html). • WSAS enables WS-Addressing automatically. Learn how important this is in the developerWorks article The hidden impact of WS-Addressing on SOAP (http://www.ibm.com/ developerworks/webservices/library/ws-address.html). • Read about the Axis2 module system in the developerWorks article Web Services and Axis2 architecture (http:// www.ibm.com/developerworks/webservices/library/wsapacheaxis2/). • Explore the benefits of using a StAX processor in the developerWorks article StAX’ing up XML, Part 1: An introduction to Streaming API for XML (http://www.ibm.com/developerworks/opensource/library/x-stax1.html). • Keystores are integral part to your security. Learn all about them in the developerWorks article Unshackling key management in Java security (http://www.ibm.com/developerworks/ibm/library/it-keyjava.html). • You’re going to want to download WSO2 WSAS (http:// wso2.com/products/wsas/). • Read about the latest features in WSO2 WSAS 2.0 (http:// blog.ruchith.org/2007/07/wso2-wsas-20-released.html). • Learn from and interact with the WSO2 community on the WSAS Wiki (http://wso2.org/wiki/display/wsasjava/ Home). • Learn about exposing your services as Web Services easily with Axis2 (http://ws.apache.org/axis2/). • Learn how Axis2 can enable your SOA designs in the develListing 1: WSDD for Axis bid-buy sample
<deployment xmlns=”http://xml.apache.org/axis/wsdd/” xmlns: java=”http://xml.apache.org/axis/wsdd/providers/java” xmlns: bid=”http://www.soapinterop.org/Bid” xmlns:reg=”http://www.soapinterop.org/Registry”> <service name=”Bid” provider=”java:RPC”> <namespace>http://www.soapinterop.org/Bid</namespace> <parameter name=”className” value=”samples.bidbuy. BidService”/> <parameter name=”allowedMethods” value=”RequestForQuote SimpleBuy Buy Ping”/> </service> <beanMapping qname=”bid:PurchaseOrder” languageSpecificType=”j ava:samples.bidbuy.PurchaseOrder”/> <beanMapping qname=”bid:Address” languageSpecificType=”java:

Figure 11 Security configuration of bid service

Figure 8 Manage modules for bid service

Security Configuration
Let’s go back to our Service listing (Figure 7) and this time click the Security Configuration link. This will bring up the interface shown in Figure 11. What is this list you see here? This list represents 11 different pre-set security configurations included with WSAS. These 11 configurations represent the most common scenarios for securing a Web Service. Whatever your security requirements are, it’s probably covered by one of them. Enabling any of them is trivial, just pick its radio button and continue. For example, let’s say we pick the “Sign and encrypt - TripleDES/RSA15 – DK” option then we’ll bring up the interface shown in Figure 12. Notice that WSAS already has both a trusted certificate store and a keystore location provided to support encryption. The Management Console has a Keystore tab (on the left) that you can use to manage certificates and providers. Once you apply the security configuration, you can go back to the list of services and click on the Policy, as shown in Figure 13. This will bring up the Policy, shown in Listing 3. The Policy is an extensible way to configure any/all of the WS-* technologies you have enabled for your service. Where did this Policy come from? It was generated by WSAS for you when you selected the Security Configuration. You can still manually edit this file either to tweak security or to configure your WS-Reliable Messaging policy.

Figure 12 Enabling Triple DES/RSA15 - DK

Figure 9 Enabling WS-Security

Figure 13 Accessing the policy for the bid service

samples.bidbuy.Address”/> <beanMapping qname=”bid:LineItem” languageSpecificType=”java: samples.bidbuy.LineItem”/> <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * --> <service name=”BidRegistry” provider=”java:RPC”> <parameter name=”className” value=”samples.bidbuy. RegistryService”/> <parameter name=”allowedMethods” value=”Register Unregister Lookup LookupAsString”/> </service> <beanMapping qname=”reg:Service” languageSpecificType=”java: samples.bidbuy.Service”/> </deployment>

Figure 10 WS-Security enabled

very well have partners, both internal and external, that are using this format when invoking your service. No migration path can simply leave those partners high and dry by telling them to re-code their client code. So WSAS has deployed a fully backwards-compatible version of your service. Anybody using RPC-encoding to invoke your Web Service can continue to do so. Not only do you not have to change any code to upgrade to WSAS, your clients don’t either.

Summary
In this article we’ve started with an Axis service, and very easily redeployed it to WSAS. All we needed was its WSDD deployment descriptor and a JAR of all its classes. We saw

30

May 2008

JDJ.SYS-CON.com

JDJ.SYS-CON.com

May 2008

31

JSR WATCH

Java and Free Software in Brazil
Bridging the digital divide
Patrick Curran

Advertiser Index
Advertiser
DataServices World at SOA World

URL
dataservicesworld.sys-con.com

Phone
888-303-5282

Page
27

Fiorano

www.fiorano.com/downloads

7

A

couple of recent Brazil-related news events suggested the theme for this column: Java in Brazil. First, the annual International Free Software Forum (FISL) (http://fisl.softwarelivre. org/9.0/www/) was recently held in Porto Alegre, Brazil. FISL is one of the world’s most important free software conferences, and more than 7,400 people attended this year, including many from Sun’s Java organization. Second, Sun Microsystems and the Brazilian organization responsible for digital television (DTV) conversion announced (http://java.sys-con.com/ read/514870.htm) that they would join forces to develop an open source content platform based on Java technology for use in the country-wide conversion of television applications and services.

Software Livre
FISL is a major event in the free software world, not only because Brazil is a significant emerging economy but also because the Brazilian government, under the presidency of Luiz Inácio Lula da Silva (Lula), has championed the cause of free software. (SouJava (http://www. soujava.org.br/display/v/Inicial), the largest Java Users Group in Brazil and possibly in the world – they have more than 18,000 members – is a major participant in FISL. SouJava was the first Java User’s Group to join the JCP back in 2005, and its president, Bruno Souza – now a Sun employee – is a tireless champion of Java and open source.) The Brazilians believe that “software livre” can help to bridge the “digital divide,” (http://en.wikipedia. org/wiki/Digital_divide) to ensure that all citizens have free access to public services, to preserve and

defend national sovereignty (avoiding domination by non-Brazilian corporations), and to conserve national resources by eliminating software licensing fees. Because Java is based on open standards and is freely available, it has been – and is increasingly – adopted by Brazilian government agencies for the development of software that delivers services to its citizens, from taxation to health care. For example, in Brazil, health care is free to all citizens. This posed a variety of organizational and management problems, from tracking patients’ records to scheduling appointments. To solve these problems, a comprehensive health-care automation system (http://www.infoq. com/articles/Brasilian-HealthcareSystem) was developed entirely in Java. The system is designed to handle all the requirements of a public health care information system including scheduling, inventory management, billing, disease tracking, reporting and auditing, regulatory compliance, and security access control. The system, claimed to be the largest Java Enterprise application ever built, was first deployed to automate all health

care services in Sao Paulo – the largest city in Brazil, and the fourth largest in the world with over 20 million people. Today the application is in production in Sao Paulo and 20 other cities and is being implemented nationally. The system has been open sourced by the Brazilian government for use by any public health organization, and its implementation is being considered in other Portuguese-speaking countries, such as Angola and Mozambique. A couple of other recent announcements illustrate the strength of the free software movement in Brazil. At this year’s FISL, the Brazilian Ministry of Education announced plans (http://news.northxsouth. com/2008/04/24/brazilian-government-to-deploy-53k-open-sourcelabs-serving-52-million-students/) to deploy 53,000 computer labs throughout the country, giving 52 million students access to computer resources. The computers in the labs will be run as a Linux distribution called Linux Educacional, which is based on Debian and the KDE desktop. Also this month, the Brazilian Election Supreme Court announced

InterSystems

www.intersystems.com/cache27p

617-621-0600 Cover IV

Java Developer’s Journal

www.jdj.sys-con.com

888-303-5282

17

Kaazing

www.kaazing.com

650-943-2436

4

NetBeans/Sun Microsystems

www.netbeans.org

Cover II

Northwoods Software Corp.

www.nwoods.com

800-434-9820

13

SOA World Conference & Expo 2008

www.soaworld2008.com

888-303-5282

23

Software FX

www.softwarefx.com

561-999-8888 Cover III

SYS-CON e-Newsletters

www.sys-con.com

888-303-5282

33

SYS-CON Media

books.sys-con.com

888-303-5282

9

Patrick Curran is Chair of the JCP and Director of the JCP Program at Sun Microsystems, Inc.

General Conditions: The Publisher reserves the right to refuse any advertising not meeting the standards that are set to protect the high editorial quality of Java Developer’s Journal. All advertising is subject to approval by the Publisher. The Publisher assumes no liability for any costs or damages incurred if for any reason the Publisher fails to publish an advertisement. In no event shall the Publisher be liable for any costs or damages in excess of the cost of the advertisement as a result of a mistake in the advertisement or for any other reason. The Advertiser is fully responsible for all financial liability and terms of the contract executed by the agents or agencies who are acting on behalf of the Advertiser. Conditions set in this document (except the rates) are subject to change by the Publisher without notice. No conditions other than those set forth in this “General Conditions Document” shall be binding upon the Publisher. Advertisers (and their agencies) are fully responsible for the content of their advertisements printed in Java Developer’s Journal. Advertisements are to be printed at the discretion of the Publisher. This discretion includes the positioning of the advertisement, except for “preferred positions” described in the rate table. Cancellations and changes to advertisements must be made in writing before the closing date. “Publisher” in this “General Conditions Document” refers to SYS-CON Publications, Inc. This index is provided as an additional service to our readers. The publisher does not assume any liability for errors or omissions.

patrick@jcp.org

32

May 2008

JDJ.SYS-CON.com

JDJ.SYS-CON.com

May 2008

33

JSR WATCH

It’s fitting that Java is now the platform of choice for implementing interactive TV infrastructure and applications, since the language – back when it was called Oak – was originally designed for just this purpose”
no ballot at this stage – the draft is simply intended to provide the JCP membership and the public with something that is detailed enough to generate useful feedback. I encourage you to download the drafts from the JCP website (follow the links below) and to send your feedback to the Spec Leads. JSR 303: Bean Validation (http:// jcp.org/en/jsr/detail?id=303), led by RedHat, defines a metadata model (based on annotations and XML descriptors) and API for JavaBean validation, enabling simple and reusable validation mechanisms at each tier of the application. JSR 235: Service Data Objects (http://jcp.org/en/jsr/ detail?id=235), led by IBM and BEA, standardizes Data Objects in terms of change history, compound data objects, dynamic and generated API, metadata, support for XML and Web services, neutral representation of business data, import/export from common formats, validation and constraints, relationship integrity, and navigation. JSR 249: Mobile Service Architecture 2 (http://jcp.org/en/jsr/ detail?id=249), led by Vodafone and Nokia, updates the Mobile Service Architecture (MSA) specification ( JSR 248) to incorporate new component JSRs and to define additional clarifications and requirements for implementing the JSRs in mobile devices. SK Telecom) demonstrates that it’s not always so simple. This JSR proposed to define APIs to enable MIDlets to be displayed and activated on the idle screen of embedded devices. The JSR failed its approval ballot in April 2008. Those voting “no” argued that idle screen integration should be handled by JSR 271 MIDP 3, and that a separate JSR defining additional APIs is unnecessary. The ballot for JSR 325: IMS Communication Enablers (ICE) (http:// jcp.org/en/jsr/detail?id=325) has not yet closed (as I write this), but since this JSR extends rather than overlaps with another it’s more likely to be approved. The JSR builds on JSR 281, defining a highlevel framework and API that will provide Java ME-based devices with a simple way to access IP Multimedia Subsystem (IMS) Communication Enablers for services such as Presence, Instant Messaging, Multimedia Telephony, and Push to talk Over Cellular (PoC). Finally this month, JSR 113: Java Speech API 2.0 (http://jcp. org/en/jsr/detail?id=113), led by Conversational Computing Corporation, is up for its Final Approval Ballot. Version 1 of the Java Speech API, which was developed by Sun before the JCP was created, defines APIs that allow developers to incorporate speech technology into user interfaces for their Java programming language applets and applications. Version 2.0 extends and builds on version 1, and tracks the emerging W3C Speech Interface Framework (http://www.w3.org/TR/voiceintro/) whenever possible. That’s all for now. On to JavaOne…

that the 2008 elections in Brazil will switch from proprietary OSbased electronic voting machines to systems based on GNU/Linux (http://www.techforce.com.br/ index.php/news/linux_blog/tse_ migrates_to_linux).

Digital TV in Brazil
Brazil, like the United States, is facing a transition to digital TV transmission in the near future. By the year 2016, analog transmissions will cease, and all TV broadcasting will be digital. Brazil intends to tackle this transition in a more ambitious manner than the US – defining a digital TV standard that will not only serve TVs but also mobile devices. In line with its policy of providing equal access to all citizens, they have chosen an open source and royalty-free approach (http://biz.yahoo.com/ bw/080304/20080304005617.html?. v=1) that defines a Java-based platform for the delivery of interactive services for digital TV devices. The specification builds on the same Java platform that currently serves as the basis for other widely deployed digital television standards, including OpenCable/tru2way, Multimedia Home Platform, GEMIPTV, and Blu-ray Disc/BDJ. It’s fitting that Java is now the platform of choice for implementing interactive TV infrastructure and applications, since the language – back when it was called Oak – was originally designed for just this purpose.

Two JSRs Submitted for Initial Approval Ballot
It may seem as if JSR approval ballots are a foregone conclusion and that rejection is unlikely, but the example of JSR 324: On Screen MIDlet API for Java ME (http://jcp. org/en/jsr/detail?id=324) (led by

This Month’s Active JSRs
This month three JSRs reached the Early Draft Review (EDR) stage. The Early Draft is the Expert Group’s first deliverable. There’s

34

May 2008

JDJ.SYS-CON.com

Embed the fastest engine.

For software developers seeking competitive advantages, InterSystems Caché® makes applications more valuable by increasing their speed and scalability, while decreasing hardware and administration requirements. This is the fastest database engine you can put in your applications, and it's the only database that gives you the combined benefits of object and relational technologies. Thanks to its innovative architecture, Caché spares Java and .NET programmers a lot of tedious work by eliminating the need for objectrelational mapping. Caché is available for Unix, Linux, Windows, Mac OS X, and OpenVMS – and it supports MultiValue development. Caché is deployed on more than 100,000 systems worldwide, ranging from two to over 50,000 users. Embed our innovations, enrich your applications.

Make Applications More Valuable
Come see product demonstrations at booth #410 at JavaOne, May 6th-9th, San Francisco
© 2008 InterSystems Corporation. All rights reserved. InterSystems Caché is a registered trademark of InterSystems Corporation.3-8 EmbedCache27JDJ

Download a free, fully functional, no-time-limit copy of Caché, or request it on CD, at InterSystems.com/Cache27P

Sign up to vote on this title
UsefulNot useful