Blogging Roller

Dave Johnson on open web technologies, social software and software development


A couple links to help with Apache-JK2-Tomcat on Debian

During my recent re-installfest, I searched high and low for JK2 documentation. I could not find any "official" documentation on building JK2 for Debian, but I was able to fumble my way through by following the steps in a Debian mailing list post titled mod_jk and mod_jk2. I tried using the latest version of JK2, which is 2.0.4, but I could not get it to compile. I ended up using version 2.0.2. I'm using Debian testing, by the way.

Once I had built JK2, I followed the JK2 documentation on the Jakarta website. I was able to get JK2 working, but I kept getting intermittent HTTP 500 errors from the server. I started looking for alternative ways to configure JK2. I found some very helpful instructions at Greenfield Research titled Tomcat-Apache using JK2 Connector. I followed those instructions and I haven't seen a 500 since.

Tags: Java

Javablogs 1.2 using Informa.

Charles Miller posted an interesting write-up on the recent Javablogs 1.2 improvements. I found it especially interesting that Javablogs now uses the Informa RSS parser, which takes the strict XML approach to RSS feed parsing - if the XML is invalid it ignores the feed. They are considering using Mark Pilgrim's ultra-liberal feed Universal Feed Parser which is much more forgiving, but it is written in Python and may need to be run in a separate process. Wouldn't it would be nice if Informa provided ultra-liberal parsing capabilities? Hmmm... I wonder... how hard would it be to port Pilgrim's parser to Jython?

Tags: Java

Gosling responds

James Gosling responds to criticism of the Sun-Microsoft settlement and on Stallman's latest anti-Java jabs. I like his responses and I think it is great that he is using his weblog to respond, but his responses don't really shed any light on the partnership and technical cooperation aspects of the deal.

Tags: Java

Desktop application vs. Web application again

With the right amount of JavaScript and DHTML it is possible to create a slick Web application that behaves a whole lot like a traditional desktop application. Take a look at Microsoft Outlook Web Access, Microsoft's Web client for Outlook. It behaves a lot like a desktop application, even on Firefox.

Google's new GMail Web mail application apparently looks and acts a lot like a desktop application as well. I haven't seen it yet, but take a look at what Rafe Colburn had to say about it:

Rafe Colburn Very slick. Most impressive though is that this is the first email client that I've used (maybe ever) that does something completely different with email than the dominant paradigm. I'm glad to see innovation of some kind happening on the email front [...].

And Aaron's Scwartz's take on it:

Aaron's Scwartz I have also received a Gmail account and can concur. Gmail uses clever JavaScript tricks to try to come close to the usability of a GUI email client -- and it comes quite close. It's incredibly fast, it's got nice keyboard controls, and the interface is simple and clean. But it doesn't have any of the features of a web app. There are no URLs, the back button does not work, links are faked, pages are coded in JavaScript and not HTML. It isn't a web application, it's a GUI application that just happens to run inside a Web browser.

Maybe it shouldn't, but this troubles me. Everybody - and by everybody I mean enterprise software customers and product managers - seems to want Web applications to behave just like desktop applications. I don't like that, but perhaps I am just a lazy developer, spoiled by Swing, and yearning for sweet SWT. This leads me to two questions and these are not rhetorical questions. These are real questions and I do not know the answers to them.

First: is it possible to create a Web application that behaves just like the desktop application and is accessible to those who are differently-abled? Sure, you can create beautifully designed and aesthetically pleasing Web sites that are accessible, but can you create super-slick Web applications that behave just like desktop applications and are still accessible? Obviously, Google put a lot of effort into making Gmail behave like a desktop application and where did that get them? It got them on Mr. Accessibility's shit-list. See what I mean:

Mark Pilgrim: NOTE TO SERGEY BRIN: stop dressing yourself in drag, fire one of your PhDs, and use the money to buy yourself a cluestick. Then beat your developers with it until they start taking accessibility seriously. I don't want to read a single review of Gmail that doesn't contain the words 'discriminates against the blind'. This isn't rocket science, people. Try harder.

Second: assuming that it is possible to create a Web application that behaves just like a traditional desktop application and is accessible, does that mean it is a good thing to do so? Most people - and by most people I mean enterprise software customers - know how to use the Web. They know how to use My Yahoo, they know how to use Fidelity.com, and they expect Web applications to behave like Web applications - don't they?

Tags: Java

Poking around for substance in the Sun-MS deal.

I'm not the only one who sees nothing of technical substance in the Sun-Microsoft partnership. Tim Bray, who is now a Sun employee with access to Sun executives, has been poking around inside Sun, looking for details, and finding nothing.

Tags: Java

Partnership, schmartnership.

It's great that Microsoft and Sun have finally settled their legal disputes, but do they have to patronize us with this nonsense fluff-talk of partnership, inter-operability, and technology sharing. What a crock'o. Microsoft needed some good PR and Sun needed some cash. Is there anything more to this story than Microsoft saying "you are right Sun, here is $2 billion dollars, now call off your dogs." If there is something more -- something of substance -- it is certainly not being reported in the trade rags (CNet, eWeek, <a href= "http://www.computerworld.com/governmenttopics/government/legalissues/story/0,10801,91866,00.html">ComputerWorld).

Tags: Java

JSP Control Flow engine.

It's time for another installment in my ongoing series of articles on continuations in Java Web application development. In a previous installment I explained how I was able to rip the continuation-based Cocoon Control Flow engine free of Cocoon and make it work in a standalone unit test environment. For this installment, I have implemented a simple web application that uses that Control Flow engine for all application logic and uses JSP for presentation.

On the Cocoon web site, the Cocoon Control Flow tutorial uses the good-old Tomcat JSP number guess example to illustrate how the Cocoon Control Flow engine works, so I have done the same thing for my JSP Control Flow engine. There are five parts in my implementation of number guess: the numberguess.js JavaScript program that executes on the server side, a FlowServlet that starts and continues the JavaScript program, the Control Flow engine which runs the JavaScript program, the guess.jsp page which asks the user to guess, and the success.jsp page which informs the user of a successful guess.

I'm not going to go into any more detail on the FlowServlet or the Control Flow engine implementation at this time. The code is not yet packaged for release, but you can get it in the form of an Eclipse project here: JSPFlow-v1.zip (it's 2.4MB because it includes the way-too-many jars necessary for running MockRunner). I'll discuss FlowServlet implementation later, for now let's take a look at the JavaScript code for number guess.

function main(tray) {

  var random =  Math.round( Math.random() * 9 ) + 1;
  var hint = "No hint for you!"
  var guesses = 0;

  while (true) {

    // send guess page to user and wait for response
    forwardAndWait(tray, "guess.jsp", 
       { "random" : random, "hint" : hint, "guesses" : guesses} );

    // process user's guess
    var guess = parseInt( webapp.request.getParameter("guess") );
    guesses++;
    if (guess) {
      if (guess > random) {
        hint = "Nope, lower!"
      } 
      else if (guess 

As you can see, the code for my version of number guess is almost exactly the same as the code for the Cocoon version. There's no substantial difference. Now, let's take a look at guess.jsp. There are a couple of differences, but nothing major. Instead of the Cocoon ${thing} syntax, you see JSP syntax. Instead of making the continuation ID part of the POST URL as Cocoon Control Flow does, I've put the continuation ID in a hidden field.

<html>
<head>
  <title>JSPFlow number guessing game</title>
</head>
<body>
  <h1>Guess the Number Between 1 and 10</h1>
  <h2><%= request.getAttribute("hint") %></h2>
  <h3>You've guessed <%= request.getAttribute("guesses")%> times.</h3>
  <form method="post" action="/jspflow/FlowServlet">
    <input type="hidden" name="contid" value='<%=request.getAttribute("contid")%>' />
    <input type="text" name="guess"/>
    <input type="submit"/>
  </form>
</body>
</html>

Finally, let's take a look at the success.jsp. Again there is no substantial difference.

<html>
<head>
  <title>JSFlow number guessing game</title>
</head>
<body>
  <h1>Success!</h1>
  <h2>The number was: <%= request.getAttribute("random") %></h2>
  <h3>It took you <%= request.getAttribute("guesses")%> tries.</h3>
  <p><a href="/jspflow/FlowServlet">Play again</a></p>
</body>
</html>

Number guess is simple and not a very realistic. The input data is strings, all application logic is written in JavaScript, and the output data is also strings. In a real world application, we would probably want to call out to application logic written in Java and we would probably want to put some more complex objects into request scope for display on the JSP page. Despite that, I'm going to move on. I'll implement a more complex example once I've figured out how to make Control Flow work with Struts. In my next installment, I'll implement number guess again - this time using Struts and Control Flow.

Tags: Java

Don't miss the SourceBeat blogs.

Even if you don't buy into one of the "live" SourceBeat books, you can still subscribe to the excellent (and Roller-based) SourceBeat blogs. You can subscribe to the whole lot of them with one URL:

http://sourcebeat.com/roller/rss.

Tags: Java

A welcome break in June - JavaOne and NFJS!

This deadline stuff is getting old. I've got another one tomorrow and I'm toiling away again tonight. On the bright side, today I registered for both the JavaOne conference and the No Fluff, Just Stuff Research Triangle Software Symposium.

Tags: Java

Defending ugly old JSP.

Russell Beattie complains about the ugliness of JSP, even with the improvements of JSP 2.0. I have to agree. JSP is ugly. JSP also does very poorly in the separate-logic-from-presentation department, scoring an entanglement index of five - and JSTL does not help at all. JSP is butt ugly, but in JSP's defense:

  • It is possible for JSP source code to be valid XHTML. Russell could have done this in his mock-up example by setting a variable and then using the ${var} syntax instead of using "an embedded x:out tag within the href attribute". In theory, by validating your JSP source code as XML and by pre-compiling the JSP at build-time you can weed out a lot of potential errors.

  • Other popular web template languages are just as bad. Velocity, FreeMarker, and Tapestry's template language all have entanglement indexes of five as well.

  • The option of embedding Java code in JSP makes JSP very powerful. Like C++, JSP gives you enough fire-power to blow your entire leg off with one pull of the trigger.

  • Compiling down to Java byte code makes JSP very fast.

  • JSP is an accepted Java standard, it's built-in, it's well understood, and it's easy to find experienced JSP developers.

That last point seems important to me. Perhaps it is not justified and I'm just a Sun lemming, but I'm a little wary of Java web frameworks that attempt to completely side-step JSP.

Tags: Java

Why am I doing this Control Flow stuff?

Maybe I should explain why I'm wasting valuable late-night Roller development time with this continuations stuff. I'm experimenting with Control Flow because I'm frustrated with Struts (and other web-MVC frameworks) lack of support for building complex web applications where user-interactions extend over multiple pages. I'm tired of little ad-hoc tricks like session attibute here, request parameter there, breadcrumb stacks, and hidden fields that developers must remember to place on each page. There has got to be a better way and a continuations-based approach seems like it may be that better way. Ken McLeod explains the appeal of a continuations-based approach quite nicely:

<a href= "http://bitsko.slc.ut.us/blog/prevalent-continuations.html">Ken MacLeod: Continuation-based web frameworks let you write complex, modeless, interactive web applications in a top-down, linear fashion as simple as writing command-line based applications that prompt for input.

That sounds great, but I don't really want to switch to a new framework to take advantage of a continuations approach. I've got an investment in Struts and JSP and what I would really like to do is to learn from the continuations-based frameworks and, if possible, apply that knowledge to my existing webapps. What I would like to learn is:

  • Should you write entire webapps as "top-down, linear" programs, or should you just use a continuations-based approach for portions of webapps, perhaps only the parts that involve multi-page user-interactions. Charles Miller points out an important reason why you might not want to take the entire-app approach: webapps must be able to provide meaningful and bookmarkable URLs (cool URLs) and some continuations-based frameworks make this difficult.
  • Does it make sense to use Control Flow in the context of a plain-old web-MVC based framework (e.g. Struts, Webwork). How would you do this? Does the Control Flow script kick in before an Action is run, as part of the Front Controller, or after the Action completes?
  • Does it make sense to use Control Flow in the context of a next-generation web-MVC based framework with events and server-side UI components (e.g. JSF, Tapestry)? How would you do this? How should the Control Flow engine fit into the component request/response lifecycle?

There you have it. Please, leave a comment if you have any insight into any of the above questions.

Tags: Java

Control Flow is free!

After some late night hacking sessions, I've been able to rip Cocoon's Control Flow component free of Cocoon. I removed all dependencies on Cocoon and Avalon and pared my standalone version of Control Flow down to only 14 classes and a couple of JavaScript functions.

Below is the simple JavaScript code that I'm using to test Control Flow. This code will eventually run on the server side and will send a web page to the user when it needs input. The forwardAndWait() method puts the name of the page or Struts forward into a 'tray' object and suspends execution. Eventually, it will suspend execution of the script, call a JSP page or a Struts forward, and wait for the response to go out and the request to come back in.

function test(tray) 
{
   log.info("I called my script!");
   forwardAndWait(tray, "page1.html");
    
   log.info("I'm back in the script");
   forwardAndWait(tray, "page2.html");

   log.info("all done!");
}

Below is the code I'm using to run and test this script. Step #1 sets up the 'tray' that I use to get the forward name and continuation id out of the JavaScript world. I introduced the tray concept, and I don't really like it but I'm not sure how else to get the values I need out of JavaScript. Step #2 and #4 are the interesting bits. Step #2 calls the JavaScript method, which executes and then suspends the script execution inside the 1st JavaScript forwardAndWait() call. Step #4 resumes execution of the script using the continuation id found in the tray.

JavaScriptInterpreter interp = new JavaScriptInterpreter();      
interp.initialize();     
interp.register("C:\\allfiles\\scratch\\StrutsFlow\\src\\flow\\system.js");
interp.register("C:\\allfiles\\scratch\\StrutsFlow\\tests\\flow\\test.js");
      
Scriptable s = interp.enterContext();
      
// 1. setup tray param to hold forward
List params = new LinkedList();
List tray = new LinkedList();
params.add(new Argument("tray", tray));

// 2. call function
interp.callFunction("test", params);
     
// 3. funcion suspended, now tray should contain forward name
assertTrue(((String)tray.get(0)).equals("page1.html"));
// and the continuation id
String kontid = (String)tray.get(1);
      
// 4. resume exection of script using that contination id
interp.handleContinuation(kontid, new LinkedList());
      
// 5. function suspeded again, now tray should contain second forward name
assertTrue(((String)tray.get(0)).equals("page2.html"));
      
// 6. resume function, so it may complete execution
kontid = (String)tray.get(1);
interp.handleContinuation(kontid, new LinkedList());
      
interp.exitContext(s);

And below is the debug output from running the test code above.

JS-INFO: I called my script!
JS-DEBUG: WK: Just Created New Continuation 4d281a763e7c1b3f5a7b4e244b2e224729112160
JS-INFO: I'm back in the script
JS-DEBUG: WK: Just Created New Continuation 877d715e813c5a7c4e7f1a56612826332f528167
JS-INFO: all done!

Next, I'll try to implement the same NumberGuess example from the Control Flow tutorial, but with no Cocoon - only JSP and Servlets.

Tags: Java

TriJUG tonight: David Geary talks JSF.

Poised to become the preeminent--not to mention standard--Java Web application framework, JavaServer Faces is the next big thing for server-side Java. Come find out what all the fuss is about in this cutting-edge session given by a member of the JSF Expert Group. Learn what JSF has to offer, how it compares to Struts, and how you can start using it today.
For more info and directions: TriJUG JSF Talk Announcement
Tags: Java

Struts Flow

I'm having too much fun hacking apart Cocoon's uber cool Control Flow component to even think about blogging right now. I want to experiment with Control Flow in a simple Struts-based app, but at this point I'm still trying to get my standalone verson of Control Flow working in a simple unit test. If and when I come up for air, I promise a full report.

Tags: Java

Thou shalt separate business logic from display.

Terence Parr, Enforcing Model-View Separation in Template Engines (PDF): Without exception, programmers espouse separation of logic and display as an ideal principle. In, practice, however, programmers and engine producers are loath to enforce separation, fearing loss of power resulting in a crucial page that they cannot generate while satisfying the principle.
Excellent paper, found via Bill de hOra - a good read for any web developer.
Tags: Java

Hard to imagine a worse model for UI development than HTTP.

Abstract: Using Smalltalk to Redefine Web Development It would be hard to imagine a worse model for user interface development than HTTP. Would you use a GUI framework where every event from every widget in your application was handed to you at once, periodically, as a large hashtable full of strings? Where every time a single piece of data changed you had to regenerate a textual description of the entire interface? Where the event-based architecture was so strict that you couldn't ever, under any circumstances, open a modal dialog box and wait for it to return an answer?
[...]
For all its limitations, the web is fast becoming the most important deployment platform for many classes of application. The Java, Perl, PHP, and .NET worlds, to name a few, are pursuing it agressively. Many of us are going to have to play their game -- but we don't have to play by their rules.
That's part of the abstract for a talk on Seaside, a Smalltalk and continuation based web application development framework (via James Robertson's blog). Seaside is one of many continuation based frameworks. The more I read about these frameworks the more I become convinced that the holy grail of web development lies in the castle of continuations. I've previously mentioned the two Java entries in the quest for the grail: RIFE and Cocoon ControlFlow. I need to find some time to investigate these frameworks and figure out how they relate, if at all, to JSP and JSF.
Tags: Java

IBM to donate more goodies to Eclipse.

Via Don Brady on the TriJUG mailing list: according to this post on de.comp.lang.java, IBM is proposing to donate a number of editors from WSAD to Eclipse including ones for JSP, SQL, XSD, and WSDL (here are some screenshots) but not including the more advanced features like the Struts Builder and JSF support.

Tags: Java

Talk went well.

I was nervous as usual, but I think I did pretty well. Almost everybody stayed until the end and folks asked lots of questions after the talk. After I clean up the speakers notes in my slides, I will hand them over to TriJUG so they can post them on the TriJUG site.

Tags: Java

Triangle JUG tonight: Weblogs and Java

Looks like the dusting of snow is not going to postpone my talk at the Triangle Java Users Group tonight. I have my slides ready and I've rehearsed the talk several times. I'm ready. I will be talking about weblogs in the Java community, weblogs at work, and the architecture of the Roller Weblogger software. Here is my high level outline:

  • Java weblog community
  • Weblog software features
  • Weblog infrastructure
  • Weblogs & communities
  • Weblogs at work
  • Roller demo
  • Roller architecture and lessons learned

Tags: Java

Why wait for XDoclet2?

Merrick Schincarol provides code to add Velocity template support to XDoclet 1.2.

Tags: Java

« Previous page | Main | Next page »