Review Part 1
Strings Might Have More Than One Line
Java imposes such limitations on what can go in a String that it is all
but impossible to handle multi-line strings such as HTML text within Java.
JSP solves this problem by letting you write HTML as a .jsp file with
Java code embedded in any of several kinds of <% Java escape sequences %>.
The .jsp files are compiled into Java servlets at runtime at which time
the original multi-line strings (MLS) are converted to plain Java strings.
Java Web Application Architecture (JWAA) takes exactly the same approach except that the conversion is done at compile time. The MLS preprocessor converts long multi-line strings (HTML text) into ordinary .java files that Jikes compiles into .class files. Everything is done at compile time, so MLS eliminates the space and time overhead of JSP’s runtime approach.
Template languages like WebMacro and Velocity take the dynamic binding anti-pattern described in Part 1 two steps further. In addition to the inappropriate dynamic couplings
we described then, template languages add two more.
- Code to template
- The Java code in an object’s controller binds to the presentation
template by naming a template file. - Template to code
- Template languages provide varying degrees of support for executable
inclusions, conditionals, loops, and so forth. The template language provides
ways for this to access a hashtable that is built by the object’s controller
and through which the template language interacts with the application.
Caution: Dynamic binding is harmful only when abused. The
user interface designers (e.g., HTML coders) in your shop might well find
the ability to tweak the template/HTML files and reload the page to see them
absolutely indispensable. Their favorite HTML editing tool will almost
certainly insist on a traditional file-based approach.
I don’t use template languages because the file-focused data-oriented tools and designers that they accommodate do not exist in my shop. I use HTML editors only
to define a site’s overall look and feel and paste the HTML into an
application-specific abstract Page class to be automatically applied
to every page. The HTML is almost invariably supplemented with dynamically
computed navigational menus, time stamps, next/prev buttons, and the like.
In other words, every page is dynamic, so the entirely static pages that
HTML design tools support do not exist. The HTML text that does remain
(between <body> and </body> tags) is simple enough to edit
by hand; mainly table definitions and snippets of text. And I’m so used to
typing make
after a change that I do it automatically.
I don’t find Java class declaration boilerplate objectionable as an
HTML coder (and their tools) might, certainly not in comparison with
the boilerplate that they do tolerate with JSP. For example, compare
this permission-denied page from the JWAA demo (see Resources link below) with the JSP equivalent that follows:
package edu.virtualschool.page; import edu.virtualschool.jwaa.*; public class RefusePage extends Page { RefusePage() { super( "DemoRefusePage", Role.Unknown, "RefusePage", "Permission Denied"); } public final void controller(Ctx ctx) throws Exception { ctx.send({{ {{ asTitle(this) }} Account {{ ctx.getViewer() }} is not authorized to do that. }}); } }
Here is the same page from a comparable JSP application.
<%@ page extends="edu.virtualschool.states.Refuse" language="java" import="edu.virtualschool.exception.*,edu.virtualschool.beans.*, [code broken for readability] edu.virtualschool.franchisee.*, java.sql.*,edu.virtualschool.types.*" info="Access Denied" session="true" errorPage="error.jsp" %> <jsp:useBean id="thisAccount" scope="session" class="edu.virtualschool.beans.Account" /> <jsp:include page="bodyOpen.jsp" flush="true" /> <h2>Permission Denied</h2> Account <%= thisAccount %> is not authorized to do that. <jsp:include page="bodyClose.jsp" flush="true" />
Configurations Are Not Files
This is the most common anti-pattern example of all, and
the biggest offenders are Apache and Tomcat.
Apache can be excused for its baroque configuration files because it’s written
in C, which some users won’t know. But Tomcat has no excuse for requiring users
to learn yet another new language fad (XML) when every Tomcat user knows Java,
a perfectly serviceable configuration language that reports errors properly.
Tomcat compounds the problem by simply checking the XML configuration
for syntactic validity against the DTD at start-up and blithely assuming
semantic validity thereafter. If the configuration is wrong, Tomcat does
nothing to diagnose the likely cause and present it in terms the user
can understand. The best you can hope for is a stack trace from some
part of the runtime that you know nothing about and may not even have the
source for. The only alternative I know at that point is to download the
source and debug the problem with the (excellent!) VisualAge debugger.
Debugging an application’s source code to fix a configuration mistake
is simply unacceptable. Sigh. There, I feel much better now.
JWAA solves this in the obvious manner, by using Java as the configuration
language and avoids dynamic substitutes such as XML, properties files,
resource files, and the like, reserving dynamic binding for those rare cases
where only dynamic binding will do. For example, to configure an application’s
servlet, instead of editing a configuration file, you define an AbstractServlet subclass like this:
package edu.virtualschool.page; import edu.virtualschool.jwaa.*; import java.io.*; import java.text.*; import java.util.*; import java.sql.*; import javax.servlet.*; /** * The page servlet for the JWAA demo defines static links that * pages can use to access other and inherits a servlet via which * the same can be done via browsers. */ public class Demo extends AbstractServlet { private final static Page[] forceLoad = new Page[] { AccountPage.instance, AddressPage.instance, HomePage.instance, LoginPage.instance, LogoutPage.instance, RefusePage.instance, RegisterPage.instance, AdminPage.instance, }; public Demo() { super(); } public final String getContextName() { return Config.getContextName(); } public final String getServerName() { return Config.getServerName(); } public final String getServletName() { return Config.getServletName(); } public final AbstractPage getDefaultPage() { return HomePage.instance; } public final AbstractPage getLoginPage() { return LoginPage.instance; } public final AbstractPage getRefusePage() { return RefusePage.instance; } public final ConnectionPool getConnectionPool() throws PoolFault { return Config.getConnectionPool(); } public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); String fileName = "/www/logs/jwaa.log"; Log.info("Writing log to " + fileName); try { Log.setFile(fileName); } catch (IOException e) { Log.error("Couldn't write to " + fileName); } } }
Config is an application-specific class that encapsulates
the information needed to establish a JDBC connection (dataset name,
user name, password, drivers, etc) so that this information doesn’t
have to be hard-coded into servlets, test cases, and so forth.
The version provided here loads this information dynamically, from the
jdbc.properties file for the convenience of those who want to install
without changing the source code. (As explained elsewhere, I don’t normally
do this.)
Dynamic Binding Is Harmful Only When Used Inappropriately
Object-oriented old-timers will be familiar with my early work with Objective-C and will probably be surprised at what may seem a condemnation of dynamic binding from me. After all, Objective-C is a language that simply adds Smalltalk-style dynamic binding to C.
This misinterprets the point of this rant. This is not a condemnation of
dynamic binding, which can be invaluable when used appropriately. Many
problems can only be solved with dynamic binding.
Rather this is a condemnation of those who use it inappropriately for
problems that can be solved more straightforwardly, productively, and
efficiently with static alternatives.
Summary
JWAA provides statically bound alternatives that the builder that knows
how to choose the right tool for the job can use in lieu of the dynamically bound solutions of Web application environments such as JSP.
In shops such as mine where the HTML designers are also programmers,
JWAA can replace JSP and/or template languages altogether, accomplishing
the same thing with far less overhead in both space and time (70K total
versus Tomcat/JSP’s approximately 1000K). JWAA even improves deployment server
security by eliminating the requirement for an SDK on the deployment server.
JWAA applications only need a JRE.
Resources
- Java Web Application Architecture Version 1.3 [free] (includes complete presentation, demo, and download)
About the Author
Brad Cox’s background and interests are in software engineering and object-oriented software development. The connection with social and organizational learning is discussed in his collection of articles on the social construction of reality. Also see the book, Superdistribution: Objects as Property on the Electronic Frontier. He maintains the Middle of Nowhere Web as a vehicle for the distance education courses he teaches and to experience first-hand the bewildering phenomena that society has not yet mastered the taming of the electronic frontier.