While the practical problems of test-friendliness seem to be addressed by IoC, it sounds to me like some of the morass-of-deployment-descriptors problem are inescapable. Mapping services into POJOs declaratively (as Spring, Hibernate and Struts all require) isn't a walk in the park; until there's a linter and/or metadata/xdoclet support for easing how services can be mapped in given a specific runtime context, the pain of diddling XML config files and finding errors at runtime are going to be part of the landscape. Nonetheless, automated unit testing without cactus is a huge win in my book -- leaving CruiseControl to run unit tests and having Cactus runs reserved for manually-invoked integration tests sounds like the way to go.( Oct 16 2004, 09:33:02 AM PDT ) Permalink
I've been looking for a way to enable internationalization and localization ("i18n" and "l10n" as they say) uniformly for both Java and Perl code bases. I really like the simplicity of Java's ResourceBundles but it looks like a build tool will be necessary in order to maintain one master lexicon for it and for the Locale::MakeText Perl counterpart.
Currently reviewing Locale::Maketext::TPJ13 and java.util.ResourceBundle for some insight into how to keep it all together. Maybe there is a wheel that's been invented already here, if I have to invent it, it will be an ant task!( Sep 13 2004, 01:36:37 PM PDT ) Permalink
Let's say you have a page called "query_results.html" that internally calls a table widget "query_results_table.html". And let's say the table widget takes a parameter for which column to sort the rendered table on and a title for the table caption. So the calling component might invoke the widget like this (assuming .html are handled as JSP):
<!-- could also spec a symbolic name in the tiles definition xml --> <tiles:insert page="query_results_table.html"> <tiles:put name="title" value="Widget Query Results"/> <!-- some literal text --> <tiles:put name="sort_order" beanName="sortOrder" /> <!-- a java.lang.String --> </tiles:insert>
The called component (query_results_table.html) then has this
<tiles:importAttribute name="title" ignore="true"/> <!-- an optional parameter --> <tiles:importAttribute name="sort_order" /> <!-- a mandatory parameter -->
HTML::Mason provides a similar facility.
<& query_results_table.html, title=>'Widget QueryResults',sort_order=>$so &>
or equivalently, call out to Perl-land
% $m->comp('query_results_table.html',title=>'Widget QueryResults',sort_order=>$so);
The called component would have something like this
<%args> $title => 'Default Title' $sort_order # mandatory parameter </%args>
So what does it look like without parameterizable components? Well, for instance every PHP project I've seen is rife with stuffing things into globals and then using an include like
$title = 'fubar'; $sort_order = 'cereal'; include('query_results_table.html');
The component has magical variables in scope and it hopes that the caller set them (yech).
<? echo "$title"; ?>
This is unacceptably lame speghetti-bait. There very well may be some better ways to do it in PHP, too bad they're not prevalent. All of the PHP code I've seen has semi-random groupings of functions stuffed into include files like that. If you're lucky, there might actually be class definitions in there. But the UI components can't take a distinct set of parameters; you're either hoping that the caller stuffed the right variables into the current scope or you're going to write a lot validation code.
I didn't want to get into naming conventions for components or any of the other real life deltas you'd want to see in production code; I just to want keep it illustrative. Hopefully this example isn't too simple and contrived that it fails to illuminate the importance. OK, maybe not... so why is this important? Relying on the presence (or absence) of variables set externally is a problem plagued, buggy development practice. A component's instrumentation should be unambiguous. The Java and Perl examples illustrate clear, explicit parameterization. Which params are mandatory and which are optional is obvious from the the way they are declared in the component. Using named parameters leads to cleaner, less buggy code that's easy to reuse and change. Rapid development and agility, that's what I want.
Now I know there are perfectly reasonable people who are happy with PHP in every respect and will take umbrage at my dis. Well, it's nothing personal folks. Rapid prototyping is cool but structuring a language so it's easier to make a mess than to keep it clean is not.( Aug 03 2004, 12:53:29 AM PDT ) Permalink
In his post, Rafe even mentions hosting it as a project on Sourceforge. Consider this a tap on the shoulder: if you want to give MT the heave-ho and aren't on a Wordpress trajectory, Roller's architecture ain't bad.
( Jul 08 2004, 06:27:52 PM PDT )
I might be concerned with how easy a particular scaling solution is to integrate with the application language and framework, but they all can be made to scale. I prefer to look at how much the prevailing practices with the technology make change easy. Just 'cause you can prototype it quickly doesn't necessarily mean you can collaborate well with it and evolve it easily. And I've certainly seen my share of funky reinventions of the materialized view, half baked cache management systems and database pounders wind their ways into prototypes that become hacked architecture. So all of the hubbub about troutgirl's Friendster goes PHP post (and Rasmus' feeble attempt to indict J2EE) strikes me as trite (and perhaps I'm not the only one puzzled by it). troutgirl's remark that, "We had not one but TWO guys here who had written bestselling JSP books. Not that this necessarily means they're great Java devs, but I actually think our guys were as good as any team." Begs the question: what does that have to do with it? Were the performance problems really in the presentation tier? Or was the presentation so closely coupled to the backend that they couldn't be distinguished? And I need to know what reading not to recommend, what were the names of those books? Gimme a break.
Poor web application performance is often simply attributable to at least one of a handful of Common Stupid Mistakes:
You can make those mistakes in any programming language and framework. The key for me is how easy is to avoid these traps given the practices that are widely used by adherents to a given application environment. How good are the tools? The test frameworks? Is clean object design and architectural layering widely appreciated by the development community around that technology?
There are lots of ways to make mod_perl and PHP or MySQL scale (Slashdot and Wikipedia will be happy to testify), there are lots of huge J2EE applications that have enjoyed terrific scaling, you might employ caching that is native to your technology (i.e. in Java, PHP or Perl) or agnostic caching. But regardless, if the architecture suffers from too many crappy hacks, gratuitous dynamicism, gratuitous caching, excessive round-tripping and tight coupling -- it's gonna suck. Period.
So concern yourself with how easy will it be to employ best practices, to evolve and extend the functionality over time and integrate with other applications. The scalability concerns can be handled with various means.
( Jul 07 2004, 11:04:57 PM PDT )
The signal to noise ratio on TheServerSide's Forum have never kept me glued to the conversations but they recently outed users who share locations, which hopefully, by reducing anonymity, will raise the signal level a bit. Though recently enriched with a $10M investment from Intel, the JBoss group may have to spend some of the funds earmarked for engineering on PR instead. There's certainly no shortage of bile being offered for one of the most ambitious open source J2EE code bases, is there? "Anonymous Fakers!" declares Mike Spille. Lots of downloads evidently doesn't translate into lots of love.
Is this a redux of the fraudulent reviews on Amazon thing?
I'm wondering now if the comment-throughput on all of these blogs hosted on jroller.com have crashed their server; those blogs were inaccessible for a while today. Ya know, JBoss can run embed Tomcat as its web container (the server identifier says "Apache-Coyote/1.1" which in all likelihood is Tomcat). Hah, maybe they're running on JBoss!
I've always enjoyed the expressiveness and rapid development qualities of Perl, Python and Ruby. However, the proliferation of Perl's obscure idioms and linear of scripting tendencies of many of its users is enough to make you shudder. The absence of semi-colon statement delimiters is enough to always make me feel like I've forgotten something with the latter two. Then there's function-crazed languages like PHP and Tcl. Maybe the world does need a clean break from it all? Well, Groovy is definitely a departure of sorts. It looks a little like Ruby and a little Java with a dash of JSTL but not entirely like any one of them. And it compiles down to ye olde JVM's bytecode.
The Groovy website is loaded with examples for using SQL and writing servlets (um, make that "Groovelets") using the Groovy syntax. Support for regexp and xpath matching is in there. Reading through it, I'm impressed with the familiarity and yet the newness of the syntax. But I can't help wondering if I'd really use it to build any substantial software. In many respects, it took Java so long to mature as far as lots of those little things that matter to me like regexp support, cached prepared statements in the JDBC API and the various jax-foo API's -- all good stuff but a long time coming. So why start using Groovy?
Well, I thought of one place where I'd imagine using Groovy. When collaborating with GUI implementers on the web tier of an application, I have in the past found myself working hard to keep the communications loop tight between those dealing with the markup and the tags and on the other end those dealing with Action classes, servlets and filters. "The MonkeyBean has a Collection of Bananas... you can iterate over each of them to access their Peels..." Wouldn't it be nice if the folks working with the markup and tags could write their own beans and actions without having to know all of that Hard Java Stuff? Well, maybe. I mean if they're implementing a lot of the display logic with JSTL, why not give them an easy entry into the data-centric modules that the JSTL accesses?
Well, I don't know but I'm willing to be open minded about it and I guess the powers that be in JCPville are as well; Groovy has it's own JSR. There are a lot of important check-off items already in place:
I can see the why Groovy might be more attractive that Jython or something like that that uses the JVM but isn't native to it. On the other hand, if I didn't know better were I hiring an engineer (and I'm not, please, no phone calls) and a candidate had "Groovy" listed on their resume, I might pass them by as a goofball. Although, knowing what I do now about what Groovy may potentially be good for, I might put that resume on top of the file.
I think I feel a song coming on:
Slow down, you move too fast
You got to make the morning last
Just kicking down the cobblestones
Looking for fun and feeling groovy
Ba da da da da da da, feeling groovy
Hello lamppost, what'cha knowing
I've come to watch your flowers growin'
Ain't cha got no rhymes for me?
Doo-it in doo doo, feeling groovy
Ba da da da da da da, feeling groovy
I got no deeds to do
No promises to keep
I'm dappled and drowsy and ready to sleep
Let the morning time drop all its petals on me
Life I love you, all is groovy
59th Street Bridge Song
Sorry, I got carried away there. I couldn't help myself. ( Apr 26 2004, 09:25:52 PM PDT ) Permalink
The bottom line for me is: I want to be able to easily test stuff outside of the containers and the mandatory interface implementations. Traditional J2EE, the practices promoted around it and the tools provided haven't accounted for that requirement. So the grassroots have.
Sun, consider yourself put on notice!
Due to space constraints, I couldn't get into it in my article about AOP (Aspect Oriented Programming: An Introduction) earlier this month but as I was looking around the landscape of AOP implementations and the related technologies (i.e. Inversion of Control) it's become increasingly apparent that Hibernate, Spring and an array of other projects that've gained momentum from the grassroots level are really the important story this year in J2EE, not Java Server Faces or EJB 2.1 or EJB 3.0 -- the J2EE developers in the trenches are tired of Sun groping around trying to get it right and they're pressing ahead with real-world solutions without Sun's official blessing. If useful standards can arise out of the open source ecosystem, then Sun's JCP, the insular and opaque JSR working groups and the Decisions From On High about what's important at JavaOne are likely to see their relevance ebb.
Hasta La Vista, Baby
TheServerSide apparently has had this little gem published for a while, their
Application Server Matrix provides links to downloads, data sheets and product reviews. Great resource!
( Apr 17 2004, 10:28:29 AM PDT )
I first ran across the ToStringBuilder class looking for a tool to standardise the formatting of toString() -- it's annoying to trace a set of objects' contents to a log file and find that they all implement toString() with different levels of completeness or with different formatting conventions. Well, this class has another little gem in one of it's static methods. Check this out:
System.out.println("An object: " + ToStringBuilder.reflectionToString(anObject));
<Emeril Lagasse>BAM!</Emeril Lagasse>
By providing a higher-level wrapper API, ToStringBuilder makes using reflection to dump a Java object contents a little bit easier. Of course, seeing as how I started off talking about Perl, it's worth a mention that TMTOWDI'ness presents itself in this case. The Java bean API's XMLEncoder can be used to serialize a Java object to XML.
( Apr 16 2004, 10:59:39 PM PDT )
I first used PHP in 1996 (it was called PHP/FI at the time) -- it offered a very innovative alternative to Perl and CGI generated content by making the execution flow out UI embedded logic. I liked it. The language was easy; very Perl-ish. But over the years, other frameworks have emerged that, despite the many improvements PHP has enjoyed, easily eclipse PHP.
PHP's primary strength is its enablement of rapid development of database backended web applications. For prototyping and providing "functional mockups", that's all well and good. But what I'm seeing is that as soon as you want to scale the application along some axis (runtime traffic, i18l, collaborative development, multiple presentation formats), it's difficult to justify sticking with PHP. From what I reckon, a J2EE web tier (servlet container, JSP w/jstl taglibs, MVC i.e. struts, etc) offers a lot of high level infrastructure and, when contrasted with PHP, is a clear winner:
|Content format scaling||If you want to co-brand a PHP site, plan on having conditional logic scattered and tangled all over the UI code. This quickly degrades down into a maintenance nightmare.||A J2EE MVC framework such as Jakarta Struts (with tiles) provides a centralized mechanism to declaritively and programmatically control how content is assembled for presentation.|
|Locale scaling||PHP allow you to extend the runtime with the GNU gettext framework. IMO, this is a difficult to use system; you have to manage PO files that have a peculiar file format.||The standard Java library has ResourceBundle support built-in with a simple file format (properties files) and, again, web tier infrastructure such as the servlet container, JSTL and Struts provides easy-to-use tools to access ResourceBundles.|
|Collaborative scaling||The distinction between UI code and business logic is fuzzy and requires lots of developer discipline to keep it cleanly separated; there's little support in the framework itself. This pretty guarantees closely mingling formatting and display code with lots of logic. Yuck.||While it's certainly possible to write horrible applications with J2EE web infrastructure (i.e. the the fact that you can embed Java code, er, scriptlets, directly into a JSP is a terrible fact of life), the wealth of framework support (JSTL, Struts, etc) makes it easy to follow practices that keep the separation of concerns clean.|
There are other little things in the pro's and con's. PHP can support URL rewriting session tracking without doing anything special in the markup code -- nice that it can do that unintrusively but icky on other counts
All of these points of contrast lay atop the basic structural differences between the PHP and Java languages: Java has Object Oriented Programming (OOP) as a core part of it's design, PHP has OOP as an odd afterthought. Java has real exception handling, PHP awkwardly provides function calls to register error handlers and function to trigger an error. OO is a core element of code modularization, reuse and extension.
Additionally, while I have my misgivings about EJB's and their misuse, EJB's are an established framework for separating the business and persistence tiers from that of the UI. Service oriented architecture (SOA) patterns are also well established amongst the J2EE development community -- this also better enables collaborative development and clean separations of concern, ergo, long term maintainability.
A final point of comparison and contrast is how closely bound PHP is to the web server in a typical architecture. It's nice to have the ability to scale the HTTP interface independently from the application layer. With PHP, the only option there is to run another webserver; a reverse proxy to offload all of the HTTP servicing. With a servlet container there are various options to connect the HTTP interface to the Java engine via a connector. For example with Apache and Tomcat, you can use mod_jk to connect them, and just to sweeten the deal a bit, mod_jk provides a bit of scaffolding to support load balancing.
It's not my intention to sweepingly indict PHP. For the simple stuff, I like it. And I know it's extremely popular ("50 Million Elvis Fans Can't Be Wrong!"). But when you get beyond needing "Server Side Includes On Steroids" and have to deploy a scaled up database backended application, PHP's weaknesses come to the foreground. Yea, yea... I know that Yahoo! uses PHP and I bet there's a lot to learn from their experiences with it -- I expect PHP creator Rasmus Lerdorf's employment with Yahoo! to drive a lot of innovation in PHP's future. But at this point in time, for the web application requirements I'm looking at, I gotta give it to J2EE.
Other links of interest
After the next build was released, a new bug was filed that the browser "Back" button didn't work anymore. MSIE would display an error message about the content being expired (indeed, I'd instrumented the filter to send an HTTP Expires: header) whereas Mozilla (my browser) wasn't quite so facist with the shrill error messages.
The resolution was that the Expires header was ditched. Something else came up with screwy caching behavior and one of my colleagues turned off the filter, declaring that using META HTTP-EQUIV tags in the JSP was the "right" way to fix it. I never got a good explanation as to why that was "right" but as long my old bug wasn't reopened, I didn't lose any sleep over it.
I believe they say, "c'est la vie"
The content management stuff I used to do at Salon.com has flourished; going from being an ill-conceived spin-off business to a successful open source project (Bricolage) [warning: I like java as much as anyone but I also like Perl, if you're a Perl-phobe, don't click that link!]. The web server management stuff I did at Covalent was also admittedly ill-conceived but in the end it was an interesting exercise in identifying the customer's pain points, pinning down their concrete scenarios and appropriately scoping a product to fulfill those needs. These products had little in the way of end-user customization. The display that the user saw was the display that was coded into the UI logic. As a reference point, that's not necessarily a bad thing. But as one sees the different roles that end-users fulfill using an application, allowance for end-user customization of the display seems increasingly important. Thus, the value of decomposing the display elements into portlets and allowing them to be aggregated by a portal framework.
The next product I worked on at Covalent was an application management web interface. The first version had a nice dashboard oriented entryway portal but had hardly any end-user customization as it displayed system objects. The architecture that was decided upon for the next generation ("two oh") product specified that just about everything be presented as a portal, ostensibly allowing the varyingly-role-filling end-user to see what was important to them at all times.
The framework used for the portal was a homebrew built on struts and tiles, for two oh we had a homebrewed jsr-168'ish framework underway. I'm certainly glad we didn't paint ourselves into a costly, proprietary corner with one of the Big Commericial Portal Frameworks. I'm actually wondering how the traditional big boys in the web infrastructure market can sustain six-figure price tags for frameworks like that when there has been so much activity around jsr-168 and open source portals.
( Mar 09 2004, 08:20:45 AM PST )
Since the data from my resume is kept in an XML file and I've had requests to have it sent as plain text (instead of just sending the URL, which is what I'd been doing), I decided to turn it into an opportunity to mess with some XSLT. Everything was looking pretty good in my development sandbox (a Tomcat instance on my laptop and Eclipse) so I warred it up and deployed it on the production server.
The link to the plaintext version (which worked fine in my sandbox) was puking on the live server. It was generating a server 500 error, a NullPointerException in java.net.URL - oy vey! So I backed up, looked at the Parts inner class in the URL class... it wasn't readily apparent why it was NPE'ing on me - sonuvabitch!
After some slighly panicked puzzling ("I hope no prospective employer-types are clicking on that link now for the plaintext version"), it hit me: in my development sandbox, the webapp was deployed fully expanded, on the production server, it was deployed as a war file... that totally changes the way the XSLT file is accessed and turned into a stream for the Transformer class. The only reason I'd been accessing it as a URL to begin with was the Transformer's unhappiness with being given a plain-old InputStream from the ServletContext (it was throwing MalformedURLException).
The long and the short of it is: if you're accessing an XSLT stylesheet from inside a webapp, be careful how you access it and how you deploy the webapp -- having a request for your resume produce a server 500 error doesn't look so good.
( Mar 08 2004, 02:29:42 PM PST )
Since then, I decided to scratch an itch I've had. I've used Jakarta Struts for long time but have always found the maintenance of the deployment descriptor ("struts-config.xml") to scale poorly. Since I wanted to