Some time ago a friend forwarded me an audio recording of an interview he conducted. No names are used (except for John's), no companies are identified--to protect the (very) guilty. A few words were unintelligible. An MP3 of the interview is available here for your listening pleasure--while the transcript it entertaining on its own, when read along with the audio it's borderline hysterical.
Update update... meeaaah update!
N: We're going to move on to Struts questions, I see that you've done some Struts here?
S: Yeah.
N: Okay. Ah have you used Struts 2 at all?
S: Yeah yeah Struts 2.
N: Ah, can you tell me a key difference between Struts 1 and Struts 2?
S: Umm mmmah Struts umm mahhh in Struts 2 mmmahh ahhh is ah Struts 1 is implemented using MVC-1 architecture whereas in Struts 2 ahhhh ah is basically defined and ah ah improved version of the Struts 1 ah which defines um which is defined by MVC-2 or model 2 architecture.
N: Isn't ah model 2 architecture just using servlets and JSP, as opposed to...
S: Yeah.
N: ... C... GI?
S: Mmm ah CGI also inserted into Struts 2.
N: Oh. Okay. Um... if I have... Have you ever seen... Are you familiar with ah wizards in the Windows OS?
S: Yeah.
N: Okay. If I had to do the same thing on a website where I have a tax form but I don't want to collect all thirty pieces of information at once, I want to collect five pieces of information at a time and then submit at the end after showing a user a a uh confirmation page that redisplays all the information they added, how can I collect five pieces of information at a time then on the last page display all that information?
S: Nnnyeah ah that we can do by nyehhh specific uh amounts of um nehh we can call ah mm nn eh we can call the uh servlet engine in such a way that uh one way we neuh we need five uh five of something ah um we need nyeahh any number then we can also ah ah nah such way nyeahtoken by token process we can do it.
N: Okay. Um... Have you used JSPs at all?
S: Yeah JS-
N: I'm sorry, I'm sorry; JavaScript.
S: JavaScript, yeah.
N: Ahhh... have you used AJAX?
S: Yeah AJAX uh I know theoretical concept and uh I just mmnnuh not the implementation in the AJAX. I know it's just ah uh uh it's nuh there is an uh jax engine in between the web server and the last ??? and web server am and the ehhh process so neh the jax engine mmm aiinh eh work uh like um ah ??? for loading the web page directly into the server um ah jax engine ah do the transaction between the data ah day data transaction um by calling in the Java ???.
N: Okay. Tell me about your work with the ah I'm I'm assuming this is Google Web Toolkit?
S: Ahhhh Google Web Toolkit I have but um Yes! Google Web euh Web Toolkit is an ahhh um just like an API which um
N: But what did... what did you do with it?
S: No ah I have not used that.
N: Umm okay it says GWT on your um
S: Yeah Google Web Toolkit.
N: But you haven't used it.
S: Uhhhhh used instance of ah just not ??? theoretical ??? and ah while developing while developing a portlet ah portlet development we have just uh eeah do uh uh time submission by mmmby implementing googling and that web Google Web Toolkit is a ready toolkit that um nyeah that ??? information which helps to develop the portal developortal.
N: Okay ummm. The last couple questions will be on SQL.
S: Sure.
N: Can you tell me the syntax for an update statement.
S: Sorry?
N: Can you tell me the syntax for an update statement.
S: Ahhhh select um eeeah insert ob ahhh ahh insert update ah hm insert update um neah table ??? ??? insert update oy ah table parameter mmm na for mmm for uhhhhm uhhhh nuh ??? ??? um by mm by inserting uh we can ah by insert mmnnyea eh insert mm Update! Update! uhm Update! table name ah nn by inserting ah some parameter name into the table. Like that neuhhh nuh up ah trigger I mean ueh the eh select star from select star from the table name neaaah nuh for to return the different parameters from the table name.
N: Okay. Um well that wraps up ahhh our portion of this; ah we'll get back in touch with... whom. Ah I don't know who got these but we'll get in touch with that person.
S: Ya sure.
J: Thank you.
S: Heaya thank you, myeah John, and thank you...
J&N: Bye.
N: He forgot my name.
Saturday, June 20, 2009
Thursday, April 30, 2009
Good Programmers ARE Lazy...
...but not in the way this article seems to think the phrase means. Did anybody really think that by saying "Good programmers are lazy" we meant "showing a lack of effort or care", or "characterized by lack of effort or activity"? Come on: it's a humorous expression with enough truth in it to take seriously.
When people say that "good programmers are lazy" it means that good programmers try to find ways to cut down the amount of time spent on boring and/or repetitive things. Boring and repetitive things include build and deploy processes, boilerplate code and documentation, repeating oneself, and so on. We *could* do all those things manually. We *could* write the same code over and over and change only a few details. We *could* execute our tests by hand.
But we'd rather not. We'd rather our tools did our builds. We'd rather abstract our code so we can re-use it across projects. We'd rather spend the time and effort to create something we can use over and over again--thus saving *more* time in the future (and maybe even saving *other* people's time).
Does that mean we're lazy in the strictest, non-humorous sense of the word? Of course not. It's usually much more time-consuming, the first time around, to produce something that will save time in the future. It requires more thought, more testing, more development, more of just about everything.
But we do it anyway, because we're lazy: we don't want to have to do the same work *again*. Cort Dougan took a humorous aphorism and turned it into a diatribe against... well, something the aphorism never was. His article continues an assault against several unrelated topics.
Testing is no longer part of the development process?! If anything the burgeoning TDD movement has brought it closer to the forefront than ever before. Apprenticeship is gone? Hardly--mentoring is stronger now than ever before, in both professional and amateur programming.
XP couples distinct modules because it encourages making sure changes don't break existing code? Continuous integration doesn't promote tight coupling--only code can be tightly coupled. How often code is checked in, built, and tested has nothing to do with our architecture.
The article then moves into a "solutions" section, including things like "have a list of tasks that must be completed". Even us "lazy" programmers have a TODO list. "Design then write?" Even the *most* extreme of extreme programmers will usually sketch out a data model or high-level system overview. "Write an example." Oh, you mean XP and/or TDD. Check.
Then it moves into bizzarro world: "fire software testers." Right, because I'm guaranteed to catch every error present in a system. "Know what you're doing at all times." Okay, thanks for that.
"Good programmers are lazy" doesn't mean we sit around in a pile of our own filth and make the pizza delivery guy step over empty boxes to hand us our next meal. It means that good programmers attempt to find reusable solutions to problems so that the next time we face them we *can* be lazy, push a button, and have our work done for us.
Being lazy often means a large up-front investment: that's not lazy, that's just prudent.
When people say that "good programmers are lazy" it means that good programmers try to find ways to cut down the amount of time spent on boring and/or repetitive things. Boring and repetitive things include build and deploy processes, boilerplate code and documentation, repeating oneself, and so on. We *could* do all those things manually. We *could* write the same code over and over and change only a few details. We *could* execute our tests by hand.
But we'd rather not. We'd rather our tools did our builds. We'd rather abstract our code so we can re-use it across projects. We'd rather spend the time and effort to create something we can use over and over again--thus saving *more* time in the future (and maybe even saving *other* people's time).
Does that mean we're lazy in the strictest, non-humorous sense of the word? Of course not. It's usually much more time-consuming, the first time around, to produce something that will save time in the future. It requires more thought, more testing, more development, more of just about everything.
But we do it anyway, because we're lazy: we don't want to have to do the same work *again*. Cort Dougan took a humorous aphorism and turned it into a diatribe against... well, something the aphorism never was. His article continues an assault against several unrelated topics.
Testing is no longer part of the development process?! If anything the burgeoning TDD movement has brought it closer to the forefront than ever before. Apprenticeship is gone? Hardly--mentoring is stronger now than ever before, in both professional and amateur programming.
XP couples distinct modules because it encourages making sure changes don't break existing code? Continuous integration doesn't promote tight coupling--only code can be tightly coupled. How often code is checked in, built, and tested has nothing to do with our architecture.
"Languages with garbage collection and sophisticated data types hide complexities from programmers. These languages are useful for teaching programming but are dangerous for production use."I don't even know where to begin on that one. How is a language with GC dangerous for production? Java is dangerous for production? What kind of production are we talking about here? If we're talking a resource-constrained, deterministic real-time system maybe it is (and even that is just a maybe). What constitutes a "sophisticated data type"? Don't we *want* to shield ourselves from complexity when practical?
The article then moves into a "solutions" section, including things like "have a list of tasks that must be completed". Even us "lazy" programmers have a TODO list. "Design then write?" Even the *most* extreme of extreme programmers will usually sketch out a data model or high-level system overview. "Write an example." Oh, you mean XP and/or TDD. Check.
Then it moves into bizzarro world: "fire software testers." Right, because I'm guaranteed to catch every error present in a system. "Know what you're doing at all times." Okay, thanks for that.
"A useful exercise I used for someone I worked with once was to stop him every 10 minutes and ask him what he was trying to do."I'm trying to get you to STOP INTERRUPTING ME EVERY 10 MINUTES, so I don't have to spend an additional 15 minutes getting back into flow. I'm trying not to punch you in the face. I'm trying to find another job.
"Good programmers are lazy" doesn't mean we sit around in a pile of our own filth and make the pizza delivery guy step over empty boxes to hand us our next meal. It means that good programmers attempt to find reusable solutions to problems so that the next time we face them we *can* be lazy, push a button, and have our work done for us.
Being lazy often means a large up-front investment: that's not lazy, that's just prudent.
Thursday, April 23, 2009
Java is NOT Design by Contract.
In a recent DZone comment thread somebody stated:
Here's a simple example highlighting the weakness in thinking Java is DbC. A simple bank system might expose the following interface:
We know the operations we can perform on an account, but know absolutely nothing about the behavior of an account or the expectations of the interface methods. Can the amount be null? Negative? We don't know. Does making a deposit actually increase the amount of money in the account? We don't know. Sure, we can check the Javadocs, but they're not tied directly to the code.
There is nothing contained in an interface definition other than the operations we can perform.
In Eiffel, a strong DbC language, the deposit() method would look something similar to the following. It turns out the Eiffel tutorial has this exact example, which I didn't know when I started. I've removed some of the example for clarity.
Now we know, as does the compiler and runtime, that sum must be zero or above, as stated in the require section. We also know that when we're done that the new balance will equal the old balance plus what we just deposited, as defined in the ensure section.
Now that is DbC. But that isn't even all of it: Eiffel also allows class-level contractual information. The following is part of the tutorial's account class:
Still want to claim that Java is a DbC language? Yes, we can do all of this in Java code--but we can do that in any language, no matter how DbC (or not).
Interfaces may be *a* form of DbC, but they're the weakest form possible. Interfaces define only *what* we may do, and provide zero information about expectations.
In a previous post I discussed DbC for Java via SpringContracts; it's a step in making Java much more DbC-like. With a fuller expression language it would be a pretty good solution.
[...] Java did great in pushing design-by-contract [...]This caught me off-guard; I've never heard anybody refer to Java as a DbC language before. The rationale provided was that Java was the first general-purpose language to push interfaces--but interfaces are probably the weakest form of DbC I can think of. (We'll ignore that Eiffel predates Java by something approaching a decade.)
Here's a simple example highlighting the weakness in thinking Java is DbC. A simple bank system might expose the following interface:
interface Account {
void deposit(Money amount);
void withdraw(Money amount);
Money getBalance();
}
We know the operations we can perform on an account, but know absolutely nothing about the behavior of an account or the expectations of the interface methods. Can the amount be null? Negative? We don't know. Does making a deposit actually increase the amount of money in the account? We don't know. Sure, we can check the Javadocs, but they're not tied directly to the code.
There is nothing contained in an interface definition other than the operations we can perform.
In Eiffel, a strong DbC language, the deposit() method would look something similar to the following. It turns out the Eiffel tutorial has this exact example, which I didn't know when I started. I've removed some of the example for clarity.
deposit (sum: INTEGER) is
require
non_negative: sum >= 0
do
balance := balance + sum
ensure
updated: balance = old balance + sum
end
Now we know, as does the compiler and runtime, that sum must be zero or above, as stated in the require section. We also know that when we're done that the new balance will equal the old balance plus what we just deposited, as defined in the ensure section.
Now that is DbC. But that isn't even all of it: Eiffel also allows class-level contractual information. The following is part of the tutorial's account class:
invariant
consistent_balance:
(all_deposits /= Void) implies (balance = all_deposits . total)
zero_if_no_deposits:
(all_deposits = Void) implies (balance = 0)
Still want to claim that Java is a DbC language? Yes, we can do all of this in Java code--but we can do that in any language, no matter how DbC (or not).
Interfaces may be *a* form of DbC, but they're the weakest form possible. Interfaces define only *what* we may do, and provide zero information about expectations.
In a previous post I discussed DbC for Java via SpringContracts; it's a step in making Java much more DbC-like. With a fuller expression language it would be a pretty good solution.
Labels:
design by contract,
eiffel,
java
Monday, April 20, 2009
People Still Do JSP Wrong--But Why?
The JavaRanch is a site for "Java greenhorns" (although it caters to quite advanced users as well). As such sometimes things are posted there that make even relatively new Java programmers cringe.
A recent post in the Struts forum asked a question about frames, which ends up being the least of the problems. The code snippet posted looked like this, spacing preserved:
I wonder about the environment and mindset that allows code like this to exist. I'm not (merely) singling out the person that asked the original question; I see code like this all the time. I do, however, have problems understanding how, in 2009, there exist places where code like this can be written. Where are the mentors? Where are the examples that beat code like this into a bloody pulp and make even the thought of writing it unimaginable?
Code written by people that care (almost!) never looks like this. Attention to detail pervades well-written code: take indentation, for example. I don't know of any editors that make indentation impossible. Indentation matters: it's a drop-dead simple way of indicating structure and hierarchy. Indentation can reveal flaws in structure and hierarchy, the snippet above having several. Incorrect indentation is misleading, impedes understanding, and creates unnecessary cognitive overhead. Indentation doesn't matter to the compiler: a valid point--but it matters to *people*.
The indentation isn't the most disturbing part of the code above--once I corrected the indentation (as best as I could, considering the snippet's incompleteness) the real killer is the chunk of XML processing code sitting in the JSP. Ignore that it's parsing an XML file on every page load, ignore that it's iterating over a *map* to retrieve a single mapped value (the id).
Come on: even apps that used servlets and JSP can be written to remove the need for this kind of programming. And this is *Struts* (Struts 1, but even still)... why bother using Struts at all if this is the code you're going to write?
Do the XML processing in a *real* Java file, where it belongs. Put it in a service object so when caching is implemented all you need to do is change the service implementation used by the action.
Even *Java* has mechanisms that allow (relatively, let's be realistic here) concise JSP. Hide the inner per-cabinet HTML in a JSP-based custom tag. Use JSTL. Use JSP EL. Drop the monstrosity above down to this:
I rag on Java a *lot*, and I have reasons to--but this is 2009, and people writing the same kind of apps that people were writing circa 1998-2000 is inexcusable. In what company would the original example have survived even a *minimal* code review? It's not even acceptable for a rapid prototype, at least nowhere that I've been associated with. So where did the breakdown occur? Is it this particular developer? No, because code like this exists all over the place. That said, *good* developers strive to understand and work with the environment they're in, and use it to the best advantage possible.
Is it the company the developer works for? *Somebody* approved this code. Yes, the approver might have been the original developer--but that leads to a host of associated problems. Code reviews should be an integral part of a good development process. Mentoring can be part of, or parallel to, a code review process. This code should not have existed for more than a single checkin.
Is it the sample code found in books and the internet? Let's be honest--book code is highly edited for space and educational purposes. Internet code is largely the same, although some sample code is clearly better than others. "Graduated" code samples, where the code is drillable, with the basics covered first but that allow access to a complete code sample (you know, error handling, I18N, whatever) should be encouraged. We can't make people *use* good code, but we can get it in people's faces much, much more than we are now.
Some thing, or things, are broken when code like this is posted and the question is anything other than "How can I make this code tolerable, readable, extensible, and debuggable?" I don't know how to fix it, or to make people indent their code, or to convert all existing examples to be more instructive about something other than just the laser-focused point the example is trying to make--but I know that code like the original snippet makes me wonder about several steps in the coding process at at least one programming house, and it makes me want to make sure that my code, and the code of places I'm associated with, never looks like it.
A recent post in the Struts forum asked a question about frames, which ends up being the least of the problems. The code snippet posted looked like this, spacing preserved:
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr class="topbanner">
<td height="81">
<%
String contextPath = (String)request.getContextPath();
IDfCollection cabinetList = (IDfCollection)session.getAttribute("allCabinets");
try{
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse (new File("tree.xml"));
doc.getDocumentElement().normalize();
NodeList listOfCabinets = doc.getElementsByTagName("branch");
int noOfCabinets = listOfCabinets.getLength();
for(int i=0; i<noOfCabinets; i++){
Node cabinet = listOfCabinets.item(i);
NamedNodeMap attributeMap = cabinet.getAttributes();
for(int j=0; j<attributeMap.getLength(); j++){
Node attribute = attributeMap.item(j);
if(attribute.getNodeName().equalsIgnoreCase("id")){
String value = attribute.getNodeValue();
%>
<tr bgcolor="#CCD3D9">
<td height="1" colspan="2" class="helptextbold2">
<div class="trigger" onclick="javascript:showBranch(<%=value%>);swapFolder(<%=value%>)" id="<%=value%>">
<img src="images/closed.gif" border="0">
<table align="left" width="20%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td bgcolor="white">
<html:frame>
<a
target="<%=contextPath%>/DocumentManagement.do?cabinetName=<%=value%>&methodName=getCabinetContents"
onclick="javascript:showBranch(<%=value%>);swapFolder(<%=value%>)">
<%=value%>
</a>
</html:frame>
<%
}
}
}
%>
</div>
<br>
</td></tr></table>
I wonder about the environment and mindset that allows code like this to exist. I'm not (merely) singling out the person that asked the original question; I see code like this all the time. I do, however, have problems understanding how, in 2009, there exist places where code like this can be written. Where are the mentors? Where are the examples that beat code like this into a bloody pulp and make even the thought of writing it unimaginable?
Code written by people that care (almost!) never looks like this. Attention to detail pervades well-written code: take indentation, for example. I don't know of any editors that make indentation impossible. Indentation matters: it's a drop-dead simple way of indicating structure and hierarchy. Indentation can reveal flaws in structure and hierarchy, the snippet above having several. Incorrect indentation is misleading, impedes understanding, and creates unnecessary cognitive overhead. Indentation doesn't matter to the compiler: a valid point--but it matters to *people*.
The indentation isn't the most disturbing part of the code above--once I corrected the indentation (as best as I could, considering the snippet's incompleteness) the real killer is the chunk of XML processing code sitting in the JSP. Ignore that it's parsing an XML file on every page load, ignore that it's iterating over a *map* to retrieve a single mapped value (the id).
Come on: even apps that used servlets and JSP can be written to remove the need for this kind of programming. And this is *Struts* (Struts 1, but even still)... why bother using Struts at all if this is the code you're going to write?
Do the XML processing in a *real* Java file, where it belongs. Put it in a service object so when caching is implemented all you need to do is change the service implementation used by the action.
Even *Java* has mechanisms that allow (relatively, let's be realistic here) concise JSP. Hide the inner per-cabinet HTML in a JSP-based custom tag. Use JSTL. Use JSP EL. Drop the monstrosity above down to this:
<table class="cabinets">
<tr>
<td>
<c:forEach var="cabinetName" items="${cabinetNames}">
<app:cabinetInfo cabinetName="${cabinetName}"/>
</c:forEach>
</td>
</tr>
</table>
I rag on Java a *lot*, and I have reasons to--but this is 2009, and people writing the same kind of apps that people were writing circa 1998-2000 is inexcusable. In what company would the original example have survived even a *minimal* code review? It's not even acceptable for a rapid prototype, at least nowhere that I've been associated with. So where did the breakdown occur? Is it this particular developer? No, because code like this exists all over the place. That said, *good* developers strive to understand and work with the environment they're in, and use it to the best advantage possible.
Is it the company the developer works for? *Somebody* approved this code. Yes, the approver might have been the original developer--but that leads to a host of associated problems. Code reviews should be an integral part of a good development process. Mentoring can be part of, or parallel to, a code review process. This code should not have existed for more than a single checkin.
Is it the sample code found in books and the internet? Let's be honest--book code is highly edited for space and educational purposes. Internet code is largely the same, although some sample code is clearly better than others. "Graduated" code samples, where the code is drillable, with the basics covered first but that allow access to a complete code sample (you know, error handling, I18N, whatever) should be encouraged. We can't make people *use* good code, but we can get it in people's faces much, much more than we are now.
Some thing, or things, are broken when code like this is posted and the question is anything other than "How can I make this code tolerable, readable, extensible, and debuggable?" I don't know how to fix it, or to make people indent their code, or to convert all existing examples to be more instructive about something other than just the laser-focused point the example is trying to make--but I know that code like the original snippet makes me wonder about several steps in the coding process at at least one programming house, and it makes me want to make sure that my code, and the code of places I'm associated with, never looks like it.
Sunday, April 19, 2009
Does Anyone Love Java? Nah.
A posting claims that some people love Java. Fair enough: I'm sure some people love Java. I then have to ask whether or not those people's opinions are worth listening to.
How many thought leaders love Java? How many people whose opinions we care about love Java? I'd wager it's a very, very small number. Many of the most prominent in the Java world spend much of their time *working around* Java's limitations via frameworks, environments, and tools.
Do they "love Java", or do they react to its weaknesses because that's the environment they're working in and they want to make it suck as little as possible? They're spending their energy making the Java *ecosystem* a better place in which to live.
The article continues: "Why love Java? Let’s look at what Java offers: portability, automatic garbage collection, object orientation." These features aren't unique to Java: why love *Java in particular*? What's compelling about Java *the language*?
Why love Java? Because there are great tools and libraries? That's a reason to love the Java *ecosystem•. What about Java the *language*? What does Java bring to the table that makes it worth *loving*? Okay, static typing makes tool development pretty easy. It's also one of its greatest hinderances, and makes for a *lot* of redundant, boiler-plate programming. So there's a reason to *like* Java in one regard, but *detest* it in another--and for me, reducing the amount of cognitive overhead is more important.
Using a google search for '"I hate Java" programming'? Come on: at the *very* least search for "Java sucks" (~14000) or "Smalltalk sucks" (345) or "Ruby sucks" (2390) or "Lisp sucks" (3120). '"I love Java" programming'? I got results for t-shirts. Sorry, that doesn't count.
Show me *why* people say the "love Java". Here's one answer I found (and I found surprisingly few, despite the "high" number of hits: 4910): "I love the fact that Javadocs exist! I love the fact that Java makes it easy for sane people to write decent software, relatively easily. I love the fact that I have tons of pro tools that make development a breeze (IntelliJ IDEA and JFormDesigner amongst many others). I love that I have ant. And I love that compiler."
Javadocs? Allows sane people to write decent software relatively easily?! Ant? The compiler? These aren't reasons: Javadoc-like tools *abound* for essentially every language. The second point doesn't even deserve a response. Ant is arguably a step up from make--but several steps away from better tools. "Love that compiler" isn't even a reason.
Here's another: "I love Java for how advanced it is, for the standards (see JCP and JSRs) that have been defined, for the other languages that you can run on top of it, for its rich frameworks and libraries, ..."
Advanced compared to *what*?! The standards... oy. The languages you run on top of it? That's the JVM, not Java. There *are* a lot of frameworks and libraries for Java--but they're all saddled by the same things that make Java broken, or exist solely to help alleviate Java's deficiencies.
Another: "I'm a big fan of programming in Java because it's so easy and fun." Compared to what? Obviously you're not familiar with the slew of *easier* languages, most of which are more fun, precisely because they're easier, more natural, and so on.
So sure. Some people may "love" Java. But until we see some concrete reasons *why* they love Java-the-language, and until there's some accounting for what they're comparing it to, I think I'll look at such claims somewhat skeptically. So far the only people I've run in to that "love Java" are people that (a) know very few other languages, and the languages they *do* know are things like VB and C, not Lisp, Smalltalk, Ruby, Python, and so on, and/or (b) simply aren't very good programmers.
I know good Java programmers, but they don't "love Java": they tolerate it. The programmers that *I* happen to respect and listen to don't "love" Java, most dismiss it out of hand, and can provide reasons for doing so.
How many thought leaders love Java? How many people whose opinions we care about love Java? I'd wager it's a very, very small number. Many of the most prominent in the Java world spend much of their time *working around* Java's limitations via frameworks, environments, and tools.
Do they "love Java", or do they react to its weaknesses because that's the environment they're working in and they want to make it suck as little as possible? They're spending their energy making the Java *ecosystem* a better place in which to live.
The article continues: "Why love Java? Let’s look at what Java offers: portability, automatic garbage collection, object orientation." These features aren't unique to Java: why love *Java in particular*? What's compelling about Java *the language*?
Why love Java? Because there are great tools and libraries? That's a reason to love the Java *ecosystem•. What about Java the *language*? What does Java bring to the table that makes it worth *loving*? Okay, static typing makes tool development pretty easy. It's also one of its greatest hinderances, and makes for a *lot* of redundant, boiler-plate programming. So there's a reason to *like* Java in one regard, but *detest* it in another--and for me, reducing the amount of cognitive overhead is more important.
Using a google search for '"I hate Java" programming'? Come on: at the *very* least search for "Java sucks" (~14000) or "Smalltalk sucks" (345) or "Ruby sucks" (2390) or "Lisp sucks" (3120). '"I love Java" programming'? I got results for t-shirts. Sorry, that doesn't count.
Show me *why* people say the "love Java". Here's one answer I found (and I found surprisingly few, despite the "high" number of hits: 4910): "I love the fact that Javadocs exist! I love the fact that Java makes it easy for sane people to write decent software, relatively easily. I love the fact that I have tons of pro tools that make development a breeze (IntelliJ IDEA and JFormDesigner amongst many others). I love that I have ant. And I love that compiler."
Javadocs? Allows sane people to write decent software relatively easily?! Ant? The compiler? These aren't reasons: Javadoc-like tools *abound* for essentially every language. The second point doesn't even deserve a response. Ant is arguably a step up from make--but several steps away from better tools. "Love that compiler" isn't even a reason.
Here's another: "I love Java for how advanced it is, for the standards (see JCP and JSRs) that have been defined, for the other languages that you can run on top of it, for its rich frameworks and libraries, ..."
Advanced compared to *what*?! The standards... oy. The languages you run on top of it? That's the JVM, not Java. There *are* a lot of frameworks and libraries for Java--but they're all saddled by the same things that make Java broken, or exist solely to help alleviate Java's deficiencies.
Another: "I'm a big fan of programming in Java because it's so easy and fun." Compared to what? Obviously you're not familiar with the slew of *easier* languages, most of which are more fun, precisely because they're easier, more natural, and so on.
So sure. Some people may "love" Java. But until we see some concrete reasons *why* they love Java-the-language, and until there's some accounting for what they're comparing it to, I think I'll look at such claims somewhat skeptically. So far the only people I've run in to that "love Java" are people that (a) know very few other languages, and the languages they *do* know are things like VB and C, not Lisp, Smalltalk, Ruby, Python, and so on, and/or (b) simply aren't very good programmers.
I know good Java programmers, but they don't "love Java": they tolerate it. The programmers that *I* happen to respect and listen to don't "love" Java, most dismiss it out of hand, and can provide reasons for doing so.
Sunday, November 23, 2008
Do Java Web Application Frameworks *Really* Provide Too Much?
The other day we witnessed a DZone disaster. The article (Web Frameworks - We Need Less, But They Keep Adding More (Part 1)) was a five-paragraph claim that typical/most Java web frameworks were full of bloat and too complex, and that this is bad. I don't think anybody would argue that. The disaster's underpinnings? He was voted down, and called the downvoter a jerk.
I also voted the article down--I didn't like the article. IMO that's what the voting system is for. I was also called a jerk, and great hilarity ensued. Yes, I should have stopped feeding the troll, and I take full responsibility for my end of the discussion. I still, however, don't like the article, and believe his reaction was about as ridiculous as I've ever seen.
Are Java web frameworks actually "adding more"? Does "doing a simple task requires pages of code and configuration..." and do current frameworks want "... control of both sides of the web application coding (server and browser)"? Do "... many/most web frameworks is the fact that they try to do too much and require large amounts of configuration (usually with XML)"?
The popularity of Ruby on Rails prodded most Java-based web frameworks to move, often rapidly, *away* from static configuration. Some have moved towards annotations (still configuration), some towards convention-over-configuration, many allow multiple configuration (and configuration-less) styles. Even the annotation-based solutions are, at this point, pretty minimal in terms of cognitive overhead (which is the ultimate issue), although annotations are still configuration. Most frameworks, even *with* XML configuration, allow convention-style configuration via wildcards and the like, often allowing large web applications to be configured, even in XML, with only a few lines.
Do frameworks "force me to use your embedded code and/or tags in my HTML"? I know of very few that *force* us to use framework tags, although it's often unreasonable not to. The article is basically a commercial for jWebApp, and several jWebApp examples use jWebApp-specific tags. The explanation given in the DZone meltdown is "The tags are framework independent and optional, but are obviously needed to repopulate the form if validation fails." I'll largely discount the entire tag issue, then, if they're obviously needed for functionality normally associated with a web application. I'll admit a certain amount of confusion as to why it was brought up, however.
The second article begins the actual technical discussion, using the "perfect web framework" (which turns out to be jWebApp). It includes code and configuration (which we didn't want, if I recall) samples as well as a laundry list of features.
The example request handler skeleton given is this (slightly reformatted and redacted):
Directly tying to the servlet spec creates an awkward dependency that unnecessarily complicates testing. These days it's relatively unusual to find a framework with such an explicit dependency on the servlet specification. If time has taught us anything it's that dependencies like this are (largely) unnecessary and impede development.
The Hello World example on the jWebApp site shows an example with a similar skeleton:
This example is intended to service the
The first mapping is reasonable, the
Note that as with most other modern Java frameworks it's possible to use convention-based URLs in jWebApp, but we're then back to comparing apples to apples.
The article then goes on to say that he would like to "optionally define simple configuration":
This brings us back into the realm of a typical XML-configured framework, which seems to go against the grain of part one, which makes me wonder what the point was in the first place. At the end of part two is a laundry list of features desired in "the perfect framework", but none of them seem to be features that are particularly lacking in other modern frameworks.
Some features present in jWebApp *are* nice to have, and it's cool they're integrated into jWebApp--but those features aren't necessarily features that *should* be integrated into a web application framework. If they meet the needs of the developer and/or project then that's a Good Thing, and a definite win. Some of the features, however, like emailing, payment processing (I only found support for PayPal, but I suspect there's more), and so on may be so project- or environment-specific that having them included in the framework itself is at best useless, at worst an unnecessary distraction. It may not be *fundamentally* bad they're included, but directly integrating cross-cutting concerns like that always raises my eyebrow.
Moving away from the articles and towards the framework itself there are several claims made regarding the features of jWebApp. The lack of need for custom tags is mentioned (no *need*, but again--they're used by the framework to provide the same functionality provided by most other frameworks' tags). Easy AJAX support is touted, but appears to be handled by creating a JSP page that returns JSON-formatted data which is then evaled in JavaScript, rather than the automatic JSON de/serialization offered by other frameworks (often including automatic help in avoiding scripting attacks).
Something not mentioned in the jWebApp documentation is Spring integration, which for the types of applications I write is a very important requirement: yes, Spring *can* be complicated and it's definitely overkill for many types of applications--but those aren't the applications I write. If all we need is dependency injection (something I didn't find support for in jWebApp--again, that doesn't mean it isn't there) then Spring is a pretty heavy solution--there are much lighter-weight DI containers. Once we throw in transaction management, AOP, and so on, I find out-of-the-box Spring support compelling, although there are other good solutions.
Simply put, I don't find anything compelling about jWebApp. That doesn't mean it's not an adequate for some problem domains or developers--it simply doesn't meet my needs. For quick, one-off, Java-based e-commerce apps it may be exactly what somebody is looking for, since it has typical functionality built-in.
The bottom line is that I still don't find the article I voted down interesting, particularly well-written (although it's not *badly* written), or of any great value. It was five paragraphs that didn't say very much. I feel badly that the author reacted so poorly--quit frankly if I'd known he'd fly off the handle like that I probably wouldn't have bothered voting it down, but part of the point of voting is to provide feedback to the community at large, and at the time I read it I didn't think it provided enough value to recommend it to others, and it seems to ignore the Java web app frameworks that alleviate the bulk of what's being complained about.
On the social aspects of the original DZone submissions, I'm somewhat at a loss. The author decries the childishness of "arbitrary" downvoting, then downvotes *multiple* submissions by his downvoters in retaliation... We may just be operating under different definitions of "childish", but IMO that's even *more* childish. It appears that the tantrums brought nothing more than *more* "arbitrary" downvoting. Is this a Good Thing? No, he's right that downvoting just because he played the fool isn't appropriate behavior: the only thing that should enter in to submission voting is the article itself. His playing tit-for-tat, however, completely demolishes any credibility he has to complain about arbitrary downvoting. I was called a jerk because I didn't like the article--this is also inappropriate behavior; not liking the article *is* an appropriate reason to vote it down.
Lesson(s) learned? For my part, I'm less likely to downvote an article I think has no redeeming value, depriving other readers of a reasoned opinion. On his part? I don't know--I'd like to think he'll come out the wiser, and I hope he does. I'm glad he's developed a framework that meets his needs, and if it meets the needs of others, I think that's terrific; more power to everybody involved. Despite his sarcastic parting comment: "Thank you all! You've shown me what the open-source community and netizenship is all about." (it was originally followed by a "Fuck off", but that part was deleted, which is good) I actually *do* believe this is what the open-source community and netizenship is all about: open discussion that sometimes happens to go horribly, horribly wrong.
I also voted the article down--I didn't like the article. IMO that's what the voting system is for. I was also called a jerk, and great hilarity ensued. Yes, I should have stopped feeding the troll, and I take full responsibility for my end of the discussion. I still, however, don't like the article, and believe his reaction was about as ridiculous as I've ever seen.
Are Java web frameworks actually "adding more"? Does "doing a simple task requires pages of code and configuration..." and do current frameworks want "... control of both sides of the web application coding (server and browser)"? Do "... many/most web frameworks is the fact that they try to do too much and require large amounts of configuration (usually with XML)"?
The popularity of Ruby on Rails prodded most Java-based web frameworks to move, often rapidly, *away* from static configuration. Some have moved towards annotations (still configuration), some towards convention-over-configuration, many allow multiple configuration (and configuration-less) styles. Even the annotation-based solutions are, at this point, pretty minimal in terms of cognitive overhead (which is the ultimate issue), although annotations are still configuration. Most frameworks, even *with* XML configuration, allow convention-style configuration via wildcards and the like, often allowing large web applications to be configured, even in XML, with only a few lines.
Do frameworks "force me to use your embedded code and/or tags in my HTML"? I know of very few that *force* us to use framework tags, although it's often unreasonable not to. The article is basically a commercial for jWebApp, and several jWebApp examples use jWebApp-specific tags. The explanation given in the DZone meltdown is "The tags are framework independent and optional, but are obviously needed to repopulate the form if validation fails." I'll largely discount the entire tag issue, then, if they're obviously needed for functionality normally associated with a web application. I'll admit a certain amount of confusion as to why it was brought up, however.
The second article begins the actual technical discussion, using the "perfect web framework" (which turns out to be jWebApp). It includes code and configuration (which we didn't want, if I recall) samples as well as a laundry list of features.
The example request handler skeleton given is this (slightly reformatted and redacted):
public class Customer extends RequestHandler {
public String validateSaveCustomer(ServerInterface serverInterface) { ... }
public String processSaveCustomer(ServerInterface serverInterface) { ... }
public String processGetCustomer(ServerInterface serverInterface) { ... }
}
ServerInterface is a wrapper around an HttpServletRequest, HttpServletResponse, and ServletContext, directly tying request handlers to the servlet framework. The wrapper class also defines a slew of convenience methods that access things like request objects and so on.Directly tying to the servlet spec creates an awkward dependency that unnecessarily complicates testing. These days it's relatively unusual to find a framework with such an explicit dependency on the servlet specification. If time has taught us anything it's that dependencies like this are (largely) unnecessary and impede development.
The Hello World example on the jWebApp site shows an example with a similar skeleton:
public class HelloWorld extends RequestHandler {
public String processHello(ServerInterface serverInterface) { ... }
public String processHelloAgain(ServerInterface serverInterface) { ... }
}
This example is intended to service the
/helloWorld/hello and /helloWorld/helloAgain URLs. The "configuration-less" configuration, however, looks like this:
jwaRequestServlet
jwebapp.RequestServlet
jwaRequestServlet
/helloWorld/hello
jwaRequestServlet
/helloWorld/helloAgain
The first mapping is reasonable, the
jwaRequestServlet is acting as a controller. What's less clear to me is why the next two servlet mappings are necessary: they seem redundant and unnecessary. Again, in modern Java frameworks this would be handled automatically via convention, wildcarding (XML or annotation configuration), or classpath-scanning convention (configuration-free or annotations).Note that as with most other modern Java frameworks it's possible to use convention-based URLs in jWebApp, but we're then back to comparing apples to apples.
The article then goes on to say that he would like to "optionally define simple configuration":
This brings us back into the realm of a typical XML-configured framework, which seems to go against the grain of part one, which makes me wonder what the point was in the first place. At the end of part two is a laundry list of features desired in "the perfect framework", but none of them seem to be features that are particularly lacking in other modern frameworks.
Some features present in jWebApp *are* nice to have, and it's cool they're integrated into jWebApp--but those features aren't necessarily features that *should* be integrated into a web application framework. If they meet the needs of the developer and/or project then that's a Good Thing, and a definite win. Some of the features, however, like emailing, payment processing (I only found support for PayPal, but I suspect there's more), and so on may be so project- or environment-specific that having them included in the framework itself is at best useless, at worst an unnecessary distraction. It may not be *fundamentally* bad they're included, but directly integrating cross-cutting concerns like that always raises my eyebrow.
Moving away from the articles and towards the framework itself there are several claims made regarding the features of jWebApp. The lack of need for custom tags is mentioned (no *need*, but again--they're used by the framework to provide the same functionality provided by most other frameworks' tags). Easy AJAX support is touted, but appears to be handled by creating a JSP page that returns JSON-formatted data which is then evaled in JavaScript, rather than the automatic JSON de/serialization offered by other frameworks (often including automatic help in avoiding scripting attacks).
Something not mentioned in the jWebApp documentation is Spring integration, which for the types of applications I write is a very important requirement: yes, Spring *can* be complicated and it's definitely overkill for many types of applications--but those aren't the applications I write. If all we need is dependency injection (something I didn't find support for in jWebApp--again, that doesn't mean it isn't there) then Spring is a pretty heavy solution--there are much lighter-weight DI containers. Once we throw in transaction management, AOP, and so on, I find out-of-the-box Spring support compelling, although there are other good solutions.
Simply put, I don't find anything compelling about jWebApp. That doesn't mean it's not an adequate for some problem domains or developers--it simply doesn't meet my needs. For quick, one-off, Java-based e-commerce apps it may be exactly what somebody is looking for, since it has typical functionality built-in.
The bottom line is that I still don't find the article I voted down interesting, particularly well-written (although it's not *badly* written), or of any great value. It was five paragraphs that didn't say very much. I feel badly that the author reacted so poorly--quit frankly if I'd known he'd fly off the handle like that I probably wouldn't have bothered voting it down, but part of the point of voting is to provide feedback to the community at large, and at the time I read it I didn't think it provided enough value to recommend it to others, and it seems to ignore the Java web app frameworks that alleviate the bulk of what's being complained about.
On the social aspects of the original DZone submissions, I'm somewhat at a loss. The author decries the childishness of "arbitrary" downvoting, then downvotes *multiple* submissions by his downvoters in retaliation... We may just be operating under different definitions of "childish", but IMO that's even *more* childish. It appears that the tantrums brought nothing more than *more* "arbitrary" downvoting. Is this a Good Thing? No, he's right that downvoting just because he played the fool isn't appropriate behavior: the only thing that should enter in to submission voting is the article itself. His playing tit-for-tat, however, completely demolishes any credibility he has to complain about arbitrary downvoting. I was called a jerk because I didn't like the article--this is also inappropriate behavior; not liking the article *is* an appropriate reason to vote it down.
Lesson(s) learned? For my part, I'm less likely to downvote an article I think has no redeeming value, depriving other readers of a reasoned opinion. On his part? I don't know--I'd like to think he'll come out the wiser, and I hope he does. I'm glad he's developed a framework that meets his needs, and if it meets the needs of others, I think that's terrific; more power to everybody involved. Despite his sarcastic parting comment: "Thank you all! You've shown me what the open-source community and netizenship is all about." (it was originally followed by a "Fuck off", but that part was deleted, which is good) I actually *do* believe this is what the open-source community and netizenship is all about: open discussion that sometimes happens to go horribly, horribly wrong.
Friday, February 01, 2008
Today's Java Irritant: No sense of closure.
There's still enough back-and-forth about the inclusion of closures in Java 7 that I'm nervous it might not make it in to the language.
James Gosling supports the addition of closures and states that the reason they weren't there in the first place was due to time pressures and seems to have some regret about their absence (understandable; he's a Pretty Smart Dude and probably feels the pain of Java wartage more keenly than most).
Ricky Clarkson blogs about why we need a new syntactic construct to make the use of closures cleaner and less verbose, even while admitting that Java does, in fact, have a form of support for closures already.
My languages of choice (Lisp, Smalltalk, Ruby, etc.) all have cleaner support for closures without the syntactic overhead that current Java has. For a trivial example we can compare the use of closures for processing a file.
With current Java syntax we might end up with something like this:
We could also create a
This isn't the Worst Syntax in the World, but it still makes me think more when writing the code and when I'm reading it later.
A relatively minor point is that any variable used in the closure must be declared as
It'll be interesting to see what finally happens; I hope that (a) support for closures is added and (b) it doesn't irritate me too much.
James Gosling supports the addition of closures and states that the reason they weren't there in the first place was due to time pressures and seems to have some regret about their absence (understandable; he's a Pretty Smart Dude and probably feels the pain of Java wartage more keenly than most).
Ricky Clarkson blogs about why we need a new syntactic construct to make the use of closures cleaner and less verbose, even while admitting that Java does, in fact, have a form of support for closures already.
My languages of choice (Lisp, Smalltalk, Ruby, etc.) all have cleaner support for closures without the syntactic overhead that current Java has. For a trivial example we can compare the use of closures for processing a file.
file.each_line do |line|
# Process line of file.
end
With current Java syntax we might end up with something like this:
import static bar.baz.eachLine;
...
eachLine(file, new EachLine() {
void doLine(String line) {
// Process line of file.
}
});
We could also create a
File-like object with an eachLine method.This isn't the Worst Syntax in the World, but it still makes me think more when writing the code and when I'm reading it later.
A relatively minor point is that any variable used in the closure must be declared as
final in the enclosing method. This may obfuscate the actual functionality of the enclosing method and, in some cases, require the introduction of a final variable just to satisfy the requirements of Java's current "closure" syntax/implementation.It'll be interesting to see what finally happens; I hope that (a) support for closures is added and (b) it doesn't irritate me too much.
Subscribe to:
Posts (Atom)








