S2 Tip - Use namespaces to organize your application into logical modules

Many Struts applications contain hundreds of pages. To help organize large applications, the Struts configuration is designed around the notions of “packages” and “namespaces”. Each package can set its own defaults, including a namespace setting.

/example/HelloWorld.jsp

Add actions here

Use the namespace attribute to create logical modules or units of work within an application, each with its own identifying prefix. In an accounting application, the actions relating to “payables” might be in one namespace, and actions relating to “receivables” in another.

Namespaces avoid conflicts between action names. Each namespace can have it’s own “menu” or “help” action, each with its own implementation. While the prefix appears in the browser URI, the tags are “namespace aware”, so the namespace prefix does not need to be embedded in forms and links.

How much is open source worth?

It’s official! WebWork is “worth” more than Struts 2! About 4x more! And they are both written “primarily in JavaScript”!

… at least according to the www.oloh.net “Explore Open Source” website.

It seems that based on metrics like “lines of code”, the WebWork codebase is “worth” a wopping $7,849,557. Meanwhile, Struts 1 weighs in at a paltry $1,761,104. Struts 2 falls in between at $2,305,602.

Obviously, there’s something askew with the WebWork metric. I expect it refers to WebWork 1, which included what is now XWork, and imported JavaScript libraries that the project didn’t code.

The Struts 1 metrics are also weird. Although the project is six years old, and we have the history of every commit from day one, Struts 1 is rated as having a short version control history. Stranger yet, Craig McClanahan is not listed as one of the contributors! That’s just not right. :)

The Struts 2 contributor metrics seem about right, though the language metric doesn’t realize that most JavaScript libraries are imported rather than coded by the host project. But, I have to admit, the ohloh site design is pleasant, and it looks like they are trying to build a community around both contributors and other users. Given a sane set of metrics, ohloh would be interesting indeed. There’s a good number of projects onboard now, though a few are still missing, like SQL on Rails (don’t overlook the screencast!).

Another “fly on the wall of open source” project is SourceKibitzer. Rather than provide digital metrics, the Kibitzer specializes in trend reports. Evidentially, the idea is that we should choose open source projects using the same sort of charts we use to pick stocks (Buy!Buy!Buy!Ching!). Where ohloh offers metrics regarding lines of code, languages, licenses, and contributors, Kibitzer offers charts describing progress, completeness, complexity, and size.

Once upon a time, I tried submitting similar statistics about Struts as part of an ASF board report. The numbers I collected related to the number of mailing list subscriptions, new posts, new issues, newly resolved issues, and total number of issues. At the board level, there was zero interest in this sort of thing. From the ASF perspective, so long as the interpersonal relationship between the PMC members is warm and fuzzy, the rest will take care of itself :)

Of course, I’m not only an ASF engineer, I’m an engineer, and, personally, I do like to see hard numbers. But, sites like ohloh and Kibitzer have to move beyond codebase analyses. To the user-only community, the things that matter are the mailing list and issue tracker. Kibitzer tries to track completeness by looking for semantic clues like “TODO” comments. In practice, we are far more likely to log TODOs in the issue tracker. While it’s interesting that so-and-so contributes a lot of code, to someone casing a project, it’s more interesting the so-and-so will answer my question on the mailing list.

In the same vein, it would also be important to analyze the project documentation. How many lines of text compared to how many lines of code? Is the wording complex? How many contributors? Are related books and articles being published outside of the project?

I suspect that the mailing list and issue tracker statistics might be more reliable than either code or documentation analysis. Compared with reality as we know it, much of the code-based analysis seems dodgy, and a dodgy statistic can worth less than Ted’s best guessimate at a release date :)

13 ASF Practices

People often mention “Apache Rules”. We don’t actually have a rule book, but if we did, here’s what I believe might be the top thirteen practices.

0

Projects must be managed in a collaborative, meritocratic way, so that new volunteers are encouraged to join the project group, and so that the volunteers doing the work are the volunteers who make the decisions.

1

A project’s primary web site and mailing lists must be maintained on ASF hardware. Resources maintained elsewhere are not ASF resources, even if maintained by ASF committers.

2

Code and documentation donated to the ASF must be maintained on ASF hardware.

3

Project source code and documentation must be donated to the ASF under a Contributor’s License Agreement.

4

Donated source code and documentation must carry the ASF copyright and be placed under the Apache License.

5

Other libraries included with a distribution must be redistributable under the Apache license.

6

PMC members can veto a product change with a technical justification.

7

An ASF release must be approved by at least three members of the PMC. A release cannot be vetoed.

8

Releases must be digitally signed by a release manager.

9

The PMC chair/Project VP must submit a status report to the ASF board every three months

A

PMC members are encouraged to nominate qualified contributors as new committers. ASF Members are encouraged to nominate qualified committers as new members.

B

Obtaining a non-exclusive ASF copyright on all material in the ASF repository is encouraged.

C

Author tags in source code are discouraged but permitted.



Of course, there are other customs, but I believe that most other ASF practices would stem from this initial set. And, as with all things ASF, YMMV! :)

Subversion Tips - SVN Redux

When it comes to keeping track of each and every change to content, whether we like it or not, Subversion is a stern gatekeeper. But, when it comes to retagging a version or rewriting a log entry, Subversion is happy to accommodate us.

Retagging a version

Through its global revision number, every Subversion commit creates a working tag. But, instead of tracking that version 2.0.7 of your product maps to Subversion revision r520258, it’s just as easy to create a tag. Later, if we need to make changes to that version without changing the head, we can convert the tag to a branch by checking it out and making a commit.

Some projects like to keep tags as a permanent record, so we often create a repository with three subfolders: trunk, tags, and branches. This particular set of folders is not required, but it’s a convenient convention.

The easiest way to tag a revision is from the command line, using a command like

$ svn copy -r 520258
https://svn.apache.org/repos/asf/struts/struts2/trunk
https://svn.apache.org/repos/asf/struts/struts2/tags/STRUTS_2_0_7
-m "WW-1767 Tag r520258 as Struts 2.0.7"
`</pre>
On occasion, after tagging a version, we might find a minor problem before the bits are actually released, and we might want to tag it again. Not a problem for Subversion. The tags are folders in the repository, and we can rename or recopy tags as needed. But, Subversion can also add to a tag. If you try to recopy a tag by executing the previous example command using a new revision number, it won't overwrite the old tag, but merge the two together, and we end up with a mix of revisions.

That's not exactly what we want. Better to first delete the old tag
<pre>`svn delete https://svn.apache.org/repos/asf/struts/struts2/tags/STRUTS_2_o_7
-m "WW-1767 Removing first try at 2.0.7."
`</pre>
Then, retag the branch as before, specifying the new revision number. If we don't specify a revision number, Subversion will use the latest revision (or "HEAD"). In a multi-developer environment, it's safer to use the revision so there's no doubt as to what is being tagged. Of course, since this is Subversion, we can also go back and create a tag on any revision at any time.

### Rewriting a log entry

Verbose Subversion log entries is an excellent practice. A smart project will have a [developers mailing list](http://www.nabble.com/Struts---Dev-f205.html), and the Subversion alerts set to automatically post to the list. In this way, we can keep everyone in the loop as part of the everyday workflow. If we put any needed explanations in the log, we don't have to send out a special email or have a special conversation later. Very smart projects will also have [ViewVC](http://svn.apache.org/viewvc/struts/) hooked up, making it easy to browse prior revisions, view the DIFFs, and review the logs.

On occasion, we might fire off a commit with an inadequate or incorrect log. No worries, mate. With Subversion, we can update the log so that it reads like a good entry should. Again, the easiest way to amend a log entry is via the command line. Say for example, we left off the issue reference or maybe cited the wrong revision number. To update the log for revision 504523, we can change to the local working directory, and execute
<pre>`$ svn propset --revprop -r 504523
svn:log "WW-1715 Branch for 2.0.x at Struts 2.0.6-SNAPSHOT r504196"
`</pre>
And Subversion will confirm the change
<pre>`$ property 'svn:log' set on repository revision 504523

The change to the log won’t be echoed to the mailing list like a regular commit. If a log entry is changed, the best practice would be to send a message to the developers list to document the change. (“If it didn’t happen on the list, it didn’t happen.”)

While these aren’t everyday tips, on occasion, retagging a version or rewriting a log entry can help Subversion help us.

Ajax: The usual suspects

Blogger Cheng Chun Kit seems to building a survey of Ajax Toolkits, Frameworks, and Libraries. He has a good start, with twenty detailed listings. Though, he still has miles to go, since Douglas Crockford believes that there are at least two hundred Ajax library available today. But, I think Cheng has at least covered the top contenders.

Of the top contenders, the top-top four libraries seem to be Prototype, script.aculo.us, Dojo, and Yahoo! User Interface (YUI) Library. Happily, it’s not an election of remedies. If need be, it’s possible to mix and match libraries on the same page.

For example, during our Ajax spike, we coded the same test application in Dojo and YUI. At one point, we had a mix of Dojo and YUI controls in the same application, and it all worked just fine. We even had the Dojo widgets going through YUI Connection Manager to talk to the server.

You can do the same kind of mash-ups with Java web frameworks too. There’s nothing stopping us from having Tapestry answer some requests and Struts 2 answer some others. In fact, running Struts 1 and Struts 2 side-by-side is one of the recommended migration paths.

But, I digress … Ajax widgets aside, there are a number of Ajax helpers that can work with any library. The DesignCreatology Ajax Tools roundup includes a few Ajax extensions, like Behavior and Event-Selectors. With Behaviour, you can add a JavaScript event to an element using a CSS selectors. Likewise, Event-Selector binds events to elements using CSS style syntax.

Two other nifty Ajax helpers are DWR (for Java) and Jayock for .NET). DWR stands for Direct Web Remoting. DWR allows code in a browser to use Java functions running on a web server just as if it was in the browser. On the .NET side, Jayrock is able to call into server-side methods using JSON as the wire format and JSON-RPC as the procedure invocation protocol.

With DWR or Jayrock, it starts to feel like we are working with a full JavaScript stack. We can call server-side methods as if they were JavaScript functions. Meanwhile, with the scripting support in Java 6, we could actually be calling server-side JavaScript methods!

Can you say convergence? … I knew you could :)