I find attitudes like this to be ridiculously short-sighted.
Instead of a list of Java topics, I was faced instead by huge bold lettering that proclaimed that TSS was opening a new website for .NET developers (which, btw, remains a website wasteland with barely any comments)!
Ok, fine, it's a free world and even the publishers of JavaPro and JDJ crank out competing publications dedicated to our poor competition - but for gosh sakes, I subscribed in order to be kept aware of their JAVA topics, and NOT for any bombastic email heralding competing platforms!
For the last four years, pretty much all my professional programming (bar a few scripts here or there) has been in Java. It's paid my bills well, and continues to be a space in which a lot of nifty and interesting stuff is being done. Especially, building Confluence has been a big eye-opener as far as showing just how you can get things done in Java if you line up the right chain of tools.
But do I owe Java anything? No. I am the programmer who walks by himself, and all languages are alike to me.
I'd love to get the chance to mess around with .NET. Especially, it'd be cool to be able to sit down for a week with a copy of Visual Whatever, and throw together a Windows client for Confluence's remote API. It'd be a useful tool, it'd have the advantages of a native GUI, and thanks to the magic of SOAP it wouldn't care that it was talking to a Java application server, just as the server wouldn't care it was taking instructions from the competition.
Moreso, I'd learn something. If we start unsubscribing from every website that dares mention that there might be a competitor to Java, how are we going to learn from those things they do better than us? We could always sit around with blinkers on denying that such things exist, but that's not going to help anybody.
Given the state of the industry, you'd be mad not to be following the development of the .NET community (conversely, I frequently get links from .NET blogs to my articles). They're attacking the same problem-spaces that we are, with tools that are remarkably similar. Ant and JUnit have been ported to .NET, although the port of Hibernate seems to have stalled. If we shut our eyes, all the good ideas will continue to flow in one direction, and one direction only.
It's one thing when your only tool is a hammer. It's another when you have a full toolbox, but you're so loyal to the hammer that you'll devoutly apply it to every screw that you find.
This is mostly for my benefit, since I'm debugging nasty locking problems at the moment, but here's the query you run to list open locks on Postgresql, joined to tell you the name of the table the lock is against.
select pg_class.relname,pg_locks.* from pg_class,pg_locks where pg_class.relfilenode=pg_locks.relation;
This gives you something like the following (some rows elided):
As you can see here, process 27423 has a shared lock on the os_user table, probably due to some kind of read. Then process 27471 has asked for an exclusive lock, and since the former process is still holding the shared lock, that lock hasn't yet been granted.
The fact that this is causing a deadlock at a higher level, and 27471 will just wait indefinitely for a lock that isn't going to arrive isn't really the database's fault :)
There's a school just down the road from my apartment. Big building, incredible view of the harbour, the land alone must be worth an absolute fortune.
Recently, I've popped home during the middle of the day: once to get back into my apartment after I locked my keys inside that morning, and today just to grab a book I'd forgotten I needed. Both times, as I walked past the school from the train station, there was a hearse parked outside and a solemn funeral party was loading a casket into the back.
I can't help thinking that perhaps discipline at this school is a little harsh.
The primary purpose of the front page of a website is to introduce a visitor to the site. The front page should leave a visitor with a clear understanding of the purpose of the site, and of what they would expect to find in the rest of the site.
The secondary purpose of the front page of a website is to provide navigation to allow the visitor to visit the other content contained within. Thirdly, the front page provides news: it's a good place to say what's changed recently; what is interesting at this precise moment in time.
Too many websites get 2, mostly get 3, and totally forget about 1. I'm getting more than a little tired of project websites where I have to scan down the left-hand side to find the link that will take me to the page that finally tells me what the damn project is about.
Exercise for the reader: if you have a website for a project or product, forget everything you know about your project and read the front page. After reading, ask yourself "what do I now know about what I'm doing, and what incentive do I have to click on any of the links that will let me find out more?"
Today's lucky error message thankfully comes from someone else's product:
Null value for: 'null'
So. What value should null have?
One day, the novice came to the master and asked, "Master, how can I write perfect code?" to which the master replied:
"To write perfect code, you must not code."
The novice looked at the master and begged him to explain further, but the Master was silent.
After a week of worried meditation, the novice returned:
"Master," spoke the novice. "There is no code without bugs. However much we test, we will introduce bugs whenever we code. Entropy always increases. Each line of code that is added takes it further from perfection. Even with the most rigorous of refactoring, necessary compromises will need to be made between elegance and practicality, or even between conflicting ideals of elegance."
The master remained silent.
"Master," spoke the novice. "Every feature added to software increases the expectations of its users. If your program counts lines in a file, then its users will want it to also count words. If your program counts words, then its users will want it to also check they are spelled correctly."
"And if your program does anything, users will want it to also read email."
"Yet if your program does not count words, users will not miss a spell-checker, and if your program does not count lines, users will not desire a word-count."
"Did not the Buddha teach us that desire is the source of suffering?"
The master remained impassively silent.
"So, the way to write perfect software is to keep it as idea in your head, and never commit it to code, where it will acquire blemishes and imperfections, and be subject to the disfiguring desires of users. The perfect software must be unwritten. Un-coded, it is in harmony with the world."
The master handed the novice a copy of the LOAF specification.
The novice was enlightened.
Today was scripting day. The aim was to throw together a quick-and-dirty shell script that would:
- pull the latest source out of CVS
- build and deploy it on a test box
- trigger a second Confluence server to start a suite of FatCow tests, confirming that the build did, indeed, work
- spam the Confluence developers with the results.
All in all, it turned out pretty well. It's a particularly nice feeling to be using your software to test itself: just a little more proof that you might indeed be working on something useful.
The unfortunate end-result, though, was that I ended up using three different scripting languages to accomplish this end -- four if you count the pre-existing Maven build system.
The bulk of the scripting was done in a bash shell-script. Then as I neared the end of the task, I found I needed to send an HTML MIME email message and found a quick Python recipe on the net that suited my purpose well. Then, when someone's mail client wasn't coping very well with multipart/mixed content, I had to munge all the results into a single document. For this sort of text processing, of course, Perl seemed the obvious choice.
I did try to go back to two languages by rewriting the mail stuff in Perl's MIME::Lite, but I stuffed something up in the process, and the mail was coming through with rather serious formatting problems.
All this is possibly a side-effect of having a casual acquaintance with several languages, rather than a deep and abiding relationship with one. If I were a Python guy, or a Perl guy, or even a dedicated shell guy, I would have been able to throw everything together in a single script, instead of mashing together my fragments of knowledge of each language.
I would have attempted to do it in one language if I could have used Ruby, but it wasn't installed on the server and I didn't want to install an entirely new language just to run one page of script.
One idea I had was to rewrite the whole thing in Groovy, but the idea scares me. I fear that if the scripts have access to Java libraries, they will begin to accrete dependencies until we need a build script to manage the build scripts.
Eric Raymond has issued a press-release (his primary occupation these days), asking Sun to open Java:
Today, the big issue is Java. Sun's insistence on continuing tight control of the Java code has damaged Sun's long-term interests by throttling acceptance of the language in the open-source community, ceding the field (and probably the future) to scripting-language competitors like Python and Perl. Once again the choice is between control and ubiquity, and despite your claim that "open source is our friend" Sun appears to be choosing control.
It's good rhetoric, because it builds one highly questionable premise on top of another, and treats both as undisputable fact
Firstly, there's the premise that there is some lack of Open Source adoption of Java. Anybody who has even the most superficial knowledge of Java will know that this is a load of rubbish. Java is buried under the weight of Open Source development it attracts. One of the things that keeps me using Java is the sheer volume of Free (beer and speech) libraries there are that make it easier to do stuff. That Java itself is not Open Source doesn't seem to have done anything to prevent it attracting a lot of people who do believe in free software.
Then there's the premise that if Java were opened, it would see significantly wider adoption from people who are now instead using Python and Perl (which are free). Which is rubbish. People who use Python and Perl are generally doing so because they prefer Python and Perl as languages, not because of any strange Free Software fetish.
Using JINI as an example of closed-source slowing Java's adoption is a bit of a joke. JINI was never adopted widely because nobody ever found any convincing application for it. Raymond, therefore, has to gloss over the fact that unlike his NeWS/X11 example, there is no Open Source alternative that was adopted in its stead.
What Raymond really sees is a lack of adoption of Java from Unix/C Open Source nerds. From Raymond's point of view, the Open Source community is centered around the Linux community: so any Open Source that isn't related to the Linux community slips under his radar. Or at least is able to be ignored for rhetorical purposes.
I really can't see Scott McNealy reading Raymond's letter and thinking "Oh God! If I open up Java, all these Unix/C nerds who don't like Java anyway, are suddenly going to change their minds! After all. So few people use Java, it needs all the help it can get."
Sam Ruby has put the slides from his etcon talk on the Atom wiki online. Like all talk slides put up on the net, they make me wish I'd been there to hear what was said between the bullet-points, but Sam does a pretty good job of making the slides say something useful as well.
The main thrust of the talk isn't Atom itself, but the Wiki on which the discussions were first hosted: its strengths and weaknesses, and its appropriateness for the task it was put up to perform.
I've got a lot of thoughts about this that have been brewing ever since I saw the Atom wiki take off: they relate to a taxonomy of online communities that I was developing once upon a time, and should work on some more.
The defining nature of a Wiki is consensus. Every participant in a public wiki has the same power to create or destroy, and the resulting content is the consensus of the group. Where there is no consensus, the content remains self-contradictory. The natural mode of a disagreement on a Wiki is to start off with one page going back and forth in thread-mode, that is later rewritten as two pages stating each side of the disagreement, linked to each other.
The defining nature of a mailing-list is exhaustion. Debates continue well beyond their usefulness. On a chronological mailing-list, as opposed to the frozen-in-time wiki, there is a definitive "last word". Participants in a debate will continue not until all sides of the debate have been expressed, or until a consensus is reached, but until every participant but one has grown tired of the discussion.
Sadly, the only good community model we have for making decisions is one with a formal decision-making process. You need a point at which someone, or some procedure can come into force and say "Enough debate, this is how we decide which of the suggested options we will take." Communities without an explicit decision-making process will either never make a decision on any of the difficult subjects, or (more likely) develop some informal "back-room" process.
In the case of Atom, for example, the real choice of what Atom is going to be lies with content producers like Google/Blogger and SixApart. Whatever the various XML-nerds decide about ontology this and sixteen-ways-of-defining-a-link that, Atom will ultimately be what those few large implementors decide is worth their while implementing.
And it's interesting to note how rarely one sees any of those major parties getting involved in any of the interminable mailing-list debates.
After years of mediating between people who pronounce each letter individually, and people who say "sequel", I want to make it clear that the correct pronunciation of SQL is:
Thus, we have PostgreSquirrel, MySquirrel, and if you're a masochist, Microsoft Squirrel Server. HSQLDB is a little harder to pronounce, until you realise it's really called "HyperSquirrel".
At some point over the last two months, I seem to have slipped out of the blogging habit somewhat. I think it's the change of job more than anything else: it's disrupted my routine enough that I haven't quite adjusted to getting the other bits of my brain into place again. I tend to come home from work, sit down and think: "Should I write something? Watch TV? Play on the X-Box? Mess around with Reason? Chat on IRC? Work on some of my own code? Buy a fluffy white cat, steal two nuclear warheads and blackmail the British government?"
Well, the last one, at least, is out of the question -- my lease doesn't allow pets.
It turns out it is possible to spend five hours trying to work out what you're going to do with those five hours, and failing. I should just go to the pub more often. At least then I'm committing to doing something.
I'm going to try to do something about that. I blog because I enjoy writing, and because the exercise of putting my thoughts (or stupid stories) into words keeps my brain ticking over. Writing is often a process of examination: forcing myself to formulate what I really think. Other times, it's just a fun release. And as exciting as writing release notes can be, it's not quite the same kind of fun. :)
Or possibly, 2003 was an abberation, and I'm stepping back to a more reasonable level. I did a count-back over the new year, and my output was, at least in volume, enough for a good-sized novel. I doubt it though, because I'm starting to get to the stage where I'm finding myself twitching to write something.
I don't want to force myself to write, that would be totally missing the point. I just feel I should be organising my life slightly better so I'm in a position where it happens naturally again.
I remember once reading a FAQ about lucid dreaming: training yourself to notice you are dreaming, so you then have the power to manipulate the dream from within. I used to be pretty good at lucid dreaming as a teenager, and then sort of lost the knack in my early 20's. The FAQ said that learning to lucid dream is all about learning to notice when you're dreaming: to always be questioning reality just enough that when you're no longer in reality, you can tell. We spend all day (and much of the night) processing the input of our senses, but how often do we examine that input and ask how reliable it is?
The blogging habit, for me, is similar. You spend all day thinking. And being an incurable introvert, I tend to spend a lot of time inside my own head. Learning to blog was a process of learning to look at that stream of thoughts and recognise which ones should be expanded upon and written about. It's that habit that seems to be evading me at the moment: the ideas are slipping away before I recognise them for what they're worth.
I'm tempted to see if a change of format will break my routine enough to make me write more. Maybe if I snarfed a Confluence license for personal use, the plunge into non-linearity would be a jump-start...
In fact, what most amazes me about IT communities is the sheer ubiquity of argumentum ad hominem. I've always associated computing with the pursuit of understanding via scientifically inclined methodology. Yet most of the debate that occurs in the Java community consists of name-calling.
Cardboard.nu is listed in a few public aggregators, Javablogs and pyblagg being the main ones. I must admit to finding the childish behaviour of some Javablogs denizens frustrating. Maybe I’m just an old fart. Or maybe I’m just not macho enough to program in Java.
pyblagg, on the other hand, is a delight. In general, the Python blogging community is full of interesting people, who are capable of expressing themselves clearly, who are polite and who can respect alternative points of view. Does the language rub off on the people or do the people rub off on the language?
Also from RubyConf, one more answer to where we went wrong with J2EE, and Java in general. Matz -- the inventor of Ruby -- titled his keynote address How Ruby Sucks. Java folk have always taken the language too seriously. It's too late now -- it would incite an irrational panic among Java developers -- but we might be in a much better place today if, about five or six years ago, James Gosling had been able to deliver a talk about Java in that same spirit.
I think, to some extent, Java programmers suffer a seige mentality.
We're surrounded on all sides, you see. To C programmers, we're children who can't handle real complexity. To Smalltalkers and Lispers, we're misguided souls groping towards a better way, but trapped in the wicked grasp of Sun's marketing. To Perl and PHP nerds, we're too busy over-complicating things to ever get anything done. To Ruby and Python hackers, we're already dinosaurs. And to everyone, we're apparently the COBOL of the 21st Century.
Pretty much every other language has its niche. You can point at it and say that it's useful for this, or it pioneered that, or you'd use it in this circumstance. The only people who say anything like that about Java are, well, already Java programmers. C# programmers might look on Java as a slightly embarrassing parent, except we're the competition, and it's better to just not mention us at all.
I think that's what you get when your language was designed as a compromise between competing points of view, rather than striking out on its own path.
And like pretty much everyone who has nobody else to bully, we turn on each other. On a regular basis.
I'd be among the first to admit that Java has its flaws. Its design is a compromise, and it is thus compromised. But it still has a lot going for it: not the least of which being the quality of tool support and available libraries. And it is a language in which talented people can produce worthwhile software.
One of the features due to be rolled out in Confluence RC1 is the remote API. It comes in XML-RPC and SOAP flavours for your remote-editing pleasure. The only way to really test such a feature is to build a of client around it. Until you've built a client, you can't really know if your API is any good.
If you're designing an API, read the last sentence of that paragraph again. Keep reading it until it is embedded in your psyche.
Anyway, the first attempt at a client was written in Swing. we're a Java shop, after all, and you go with the tool that's most familiar first. And to Swing's credit, Mike had a Swing client up and running pretty quickly using IDEA's GUI-building tool.
The problem turned out to be HTML. The killer feature of the client: the one that would make people go "ooh, what a neat demo" instead of "yawn, its just a couple of list-boxes" was going to be the side-by-side editing. You write your page in Wiki-notation, and when you flip to the Preview pane, the client asks Confluence to convert it into nice shiny HTML for you to view. Unfortunately, Swing's HTML component still lives somewhere in the deep recesses of HTML3.2, so that was about as far as that client went.
This limited our options somewhat. If you want a decent HTML engine, your choices narrow quite considerably, especially if nobody owns up to knowing XUL or C, or wanting to program anything for Windows. :)
Apple's WebKit to the rescue. WebKit is so insanely easy to use that I'm amazed every OS X application doesn't do it somewhere, just for the fun of it. Maybe they do.
[[webView mainFrame] loadHTMLString:renderedContent baseUrl:pageBaseUrl];
That's basically... it. The entirety of the interaction you need to have with WebKit to render some HTML1.
By the end of the day we had about 200 lines of source-code, and a client that could drill down the spaces and pages in a Confluence site, view its unrendered and rendered content side-by-side, and preview changes in the HTML pane. About 70 lines of that code was the controller class, the other 130 were my painfully ugly and naive attempts to get XML-RPC working properly under Objective-C.
Ah yes, Objective-C. It took about four hours of on-off pairing to write those 200 lines of code. Despite my oft-stated affection for Cocoa, I only get to use it about once every six months, so while I have some vague notion of the syntax and how the pieces fit together, pretty much everything has to be looked up in the reference documentation first.
I might have been better off with PyObjC or RubyCocoa, especially as far as that line-number count is concerned: both scripting languages have powerful and simple interfaces to XML-RPC. Unfortunately, OS X only ships with Ruby 1.6, which doesn't include the XML-RPC libraries (1.8 does. Grr, Apple. Get up to date), and as much as I admire Python, I know even less about it than I do Objective-C, and coming to grips with Python and PyObjC and Cocoa at the same time would have been just that little bit too much.
Hopefully, we'll be able to polish the client (and its code) up in the next day or two so we can put the source-code up somewhere.
1 Well, the only programmatic interaction. You still, obviously, need to drag the WebView component onto the canvas in Interface Builder, and draw a line between it and the controller class. But that doesn't really count.