FrSIRT Alert does NOT apply to Struts 1.x !!!

In July, the Apache Struts group issued a security fix to Struts 2 to eliminate a remote code exploit. The exploit was based on a problem with a Struts 2 dependency (XWork). Since Struts 1 does not use XWork, Struts 1 is not vulnerable to the exploit.

Unfortunately, a recent security alert mis-described the problem as affecting all versions of Apache Struts prior to 2.0.9. This is NOT accurate. No version of Struts 1 is affected by this security issue. The only affected versions of Apache Struts are 2.0.0 through 2.0.8. Period.

We’ve updated the Apache Struts website to clarify the scope of the exploit and asked FrSIRT to correct their alert to exclude Struts 1.x.

There are many reasons why someone might want to migrate from Struts 1 to Struts 2, but this security alert is not one of them!

Three new Struts 2 books available for pre-order

Ian Roughley’s mini-book, “Starting with Struts 2”, available in print and as a free PDF since May, is about to be joined by three new books about Struts 2.

Coming in October is “Struts 2 Design and Programming: A Tutorial” by Budi Kurniawan. Budi’s Struts 1 book is rated “four stars” based on reader reviews at Amazon.

Coming in November is “Practical Apache Struts 2 Web 2.0 Projects” by Ian Roughley, an Apress book. As mentioned, Ian is also the author of “Starting with Struts 2” (available now!).

Looking down the road a bit, “Struts 2: The Complete Reference” by James Holmes is scheduled for release in June 2008. James is also the author of “Struts 1: The Complete Refererence”, which may be the most up to date Struts 1 book.

To order any of these books, please visit the Apache Bookstore site. All commissions for books ordered through the Apache Bookstore site are donated back to the Apache Software Foundation.

If you do plan on ordering any of these books, please consider pre-ordering today. Pre-orders do affect a book’s ranking, which will help us get the Struts 2 word out!

Eight Habits of Highly Effective Programmers (5-8)

Last time, we covered habits 1-4: Estimate (Be Proactive), Test-First (Begin with the End in Mind), Iterate (Put First Things First), and Narrate (Seek first to understand, and then to be understood).

  • Refine (Think Win/Win)
    Stable requirements are the holy grail of software development. If we do pursue the myth of stable requirements, clients and developers both lose. We may ship what the requirements describe, but we probably won’t ship what the client really wants and needs.

When building business applications, a better approach is successive refinement. Rather than try to define in detail the application all at once, we first define and implement a key workflow. Through a series of iterations, we continue to extend and refine the workflows that comprise the application. The goal of each iteration is to provide client with functioning application that does useful work.

Successive refinement encourages clients and developers to act as collaborators, rather than adversaries, wrangling over requirements.

  • Reuse (Synergize)
    A worker is only as good as his or her tools. As we create software that works, we look for ways to reuse that code in other projects. Few applications have totally unique requirements. Every application overlaps with the next. If arrange a codebase so that reusable components are separated from unique components, we usually increase cohesion and decrease coupling, creating software that is easier to change, extend, and reuse. By writing software so that it is easy to use more than once, we often create software that is easier to use even once.

  • Refactor (Sharpen the Saw)
    Techniques like Test-First and Iterate help us write good code quickly, but great code still takes time and effort. As we verify that code is effective and relative, we can use our tests to help us refactor, or improve the design of existing code.

Well-designed code is easy to test and easy to change. Because we know new features will be easy to add, well-designed code doesn’t need “hooks” for future development. Code becomes an asset that pays dividends today and tomorrow. Refactoring is another win/win, since it helps us create better code today and happier clients tomorrow.

  • Mentor
    It’s said that we never truly understand a task until we teach it to someone else. Teaching creates a dialog between instructor and student. When the dialog is healthy, both student and instructor benefit. Teaching forces us to organize and prioritize our own knowledge, clarifying the task in our own minds. Clever students often ask questions we never thought to ask, and in finding the answers, we ourselves come to learn more. For me, writing this article is a case in point!

To learn more about programming best practices, see The Pragmatic Programmer and Software Craftsmanship. Be guided by the humble observation of an extreme programmer: “I’m not a great programmer. I’m a good programmer with great habits.”

For a similar treatment of the “12 Steps”, see “12 steps to stellar software (usability) design“.

Eight Habits of Highly Effective Programmers

Next to the gospel, my favorite self-help book is the Seven Habits of Highly Effective People. The Habits apply to any endeavor, and I like to say that the Seven Habits is the first book any novice programmer should read. To help underscore why, here’s my humble homage to brother Steven Covey: The Eight Habits of Highly Effective Programmers.

  • Estimate (or Be Proactive)
    Programmers invent the future. It’s often hard for us to know how long something will take, because, often, we’ve never done this exact thing before. In the fictional series Star Trek, engineer Montgomery Scott would triple his estimates, so as to seem like a miracle worker. Software engineers often have to triple estimates just to be in the right ballpark!

Educators tell us that feedback is essential for learning. Before starting any programming task, write down an estimate first. After the task is done, compare your estimate with the actual result. Of course, all engineers are optimists, otherwise we couldn’t be engineers. But, with practice, we can learn what factor to apply to our internal estimates to match external events. (As implied, my factor is three!)

An easy way to get started with estimates is to keep a standup journal. Every day before starting work, jot down the most important task you did the last working day and the most important thing you hope to do today. Over time, you will develop a basis for comparing estimates with outcomes.

  • Test First (or Begin with the End in Mind)
    Most projects budget at least some time for testing. Many projects schedule this time at the end, after the rest of the work is done. Tests serve two purposes. Run today, tests prove that our code works. Run tomorrow, tests prove that our code still works. Test-last development dilutes the value of tests. The earlier tests are written, the sooner they can tell us that the our code still works. Tests are most valuable when written before we write the implementation. By writing the test first, we define what our code needs to do to succeed. As a result, we write only the code we need to write, no more, no less.

  • Iterate (or Put First Things First)
    Creating effective software is a learning process. Each release addresses old needs and exposes new needs. Many software products are written for small workgroups, or focus groups of representative users. The sooner we deliver a product that the group can review, the sooner we can verify that established needs are being met, and the sooner we can identify new needs. Early verification is important, since programmers often misinterpret needs and write great code that solves the wrong problem. Writing code is easy. Identifying what code to write is hard. Early iterations help us create a positive feedback loop, so we can deliver better applications.

  • Narrate (Seek first to understand, then to be understood)
    Many teams define an application through a series of use cases, or plain-language workflows. To “set the stage”, a use case might begin with a narrative that describes one common instance of the workflow. The narrative often refers to a prototypical user and includes details of how that user would use the system under specific circumstances. By describing the workflow in plain language, from the user’s perspective, we can establish a dialog. Use cases help developers understand what clients want, and also help clients better understand what developers need to know to implement the workflow.

Next time: Habits 5 thru 8 …

JSF Redux

The Expert Group for JSF 2.x is now forming, and people continue to consider whether JSF is the right choice.

To recap my own comments …

Here’s the thing: The vast majority of web applications are intranet application that we build in six to twelve weeks to serve a handful of users.

In a small-group intranet environment, server/bandwidth efficiency is not the limiting factor. The overriding concern is whether the application helps the people using it become more efficient. Do our people get more work done by using the application? Since we may be talking about five or twenty-five people connecting to a server on the next floor in the same building, scalability, in an environment like this, literally doesn’t matter. We still need a reasonable response time, but, often, people will forgive a slightly-longer response time for a more helpful user interface.

Of course, not all of us are building small-group intranet applications. If we have thousands of users who hit the application occasionally, from all over the world, our non-functional requirements can be quite different. Or, if we have a small group of users, but those users are working on the space shuttle, again, our requirements are going to be different. Different requirements imply different solutions.

There’s an old saw: Do you want it Fast, do you want it Right, or do you want it Soon? Pick any two.

For an intranet application, we might choose Right and Soon. (If it’s not right, no one will use it.) For an Internet application, we might pick Fast and Soon. (If it’s not fast, no one will use it.) For a space shuttle application, Fast and Right would more important than time to market (and we wouldn’t even use web technology!).

For an intranet application, JSF can be an excellent choice – if you have a group of developers that like working with Swing/VB type technology. For an Internet application, Struts can be an excellent choice – if you have a group of developers that like working with standard web technology.

But, make no mistake, in final analysis, it’s the developers that will make the difference. So, either use the technology that your team likes, or hire developers that like to use your technology. :)
In the realm of physics, in order to get any work done, we’ve had to resort to two separate, and seemingly contradictory, theories. Quantum theory is useful for calculations at an atomic scale, and general relativity is useful for calculations on a planetary scale. Either works fine on their own, and we don’t hesitate to put each to good use, but we’ve yet to find a way to reconcile the two.

In my experience, the same principle applies to web development. Techniques that work well for small intranet applications may not work as well for busy Internet applications, and vice versa. When it comes to the craft of web development, one size does not fit all.

Vive la difference!