<?xml version="1.0"?><rss version="2.0">
<channel>
  <title>Alan&#039;s Ramblings - j2ee tag</title>
  <link>http://bleaklow.com:80/tags/j2ee/</link>
  <description>My opinions may be incorrect, but they are my own</description>
  <language>en</language>
  <copyright>Alan Burlison</copyright>
  <lastBuildDate>Wed, 29 Feb 2012 20:50:00 GMT</lastBuildDate>
  <generator>Pebble (http://pebble.sourceforge.net)</generator>
  <docs>http://backend.userland.com/rss</docs>
  <image>
    <url>http://bleaklow.com/images/misc/logo.gif</url>
    <title>Alan&#039;s Ramblings</title>
    <link>http://bleaklow.com:80/</link>
  </image>
  <item>
    <title>Producing CSS with self-caching JSPs</title>
    <link>http://bleaklow.com:80/2007/10/15/producing_css_with_self_caching_jsps.html</link>
    <description>
          &lt;p&gt;
One thing that&#039;s always bugged me about CSS is that it doesn&#039;t have any sort of macro facility, so if you want to use (say) a HTML colour code in several places you need to hard-code it into all of them, which is a right pain.  As the app I&#039;m working on is written using JSPs, the obvious thing to do was to output the stylesheet from a JSP, and then use EL to define variables and then insert them in the appropriate places, e.g.:
&lt;/p&gt;
&lt;pre&gt;
&amp;lt;c:set var=&#034;background&#034; value=&#034;#292B4F&#034;/&amp;gt;

body {
    background-color:   ${background};
}
&lt;/pre&gt;
&lt;p&gt;
That works just fine, but each time the stylesheet is referenced it is regenerated, and as the content is completely static that was obviously a bit inefficient.  Some googling found a number of ways to cache the output of JSPs, from the simple to the extremely complex, e.g. using a servlet filter to intercept requests and cache output.  I wanted the simplest possible mechanism that would do the job, with no external dependencies.
&lt;/p&gt;
&lt;p&gt;
A fairly obvious technique is to cache the output in the servlet&#039;s application scope the first time it is generated, then on subsequent requests you just send back the cached output rather than regenerating the content.  The basic outline looks like this:
&lt;/p&gt;
&lt;pre&gt;
&amp;lt;c:if test=&#034;${empty cachedStylesheet}&#034;&amp;gt;
&amp;lt;c:set var=&#034;cachedStylesheet&#034; scope=&#034;application&#034;&amp;gt;

    &amp;lt;!%-- Cached content goes here --&amp;gt;

&amp;lt;/c:set&amp;gt;
${cachedStylesheet}
&lt;/pre&gt;
&lt;p&gt;
That works fine, but if you watch the conversation between the browser and the servlet, the cached content is still refetched each time this is referenced.  This is because JSP output is usually dynamic, so the servlet container sets things up so that the client browser doesn&#039;t cache the content obtained from JSPs.  To fix this we need to manually add the appropriate headers to the HTTP response we send back to the client to that it knows to cache the content, and we also need to respond to requests from the browser asking if the content has changed.  The relevant HTTP headers are &lt;code&gt;If-Modified-Since&lt;/code&gt;, &lt;code&gt;Last-Modified&lt;/code&gt; and &lt;code&gt;Expires&lt;/code&gt;, see the &lt;a href=&#034;http://www.w3.org/Protocols/rfc2616/rfc2616.html&#034;&gt;HTTP specification&lt;/a&gt; for more details.  This requires a little bit of additional inline Java code in the JSP, so the final version looks like this:
&lt;/p&gt;
&lt;pre&gt;
&amp;lt;%@page contentType=&#034;text/css; charset=UTF-8&#034; pageEncoding=&#034;UTF-8&#034; session=&#034;false&#034;%&amp;gt;
&amp;lt;%@taglib prefix=&#034;c&#034; uri=&#034;http://java.sun.com/jsp/jstl/core&#034;%&amp;gt;
&amp;lt;c:if test=&#034;${empty cachedStylesheet}&#034;&amp;gt;
&amp;lt;c:set var=&#034;cachedStylesheet&#034; scope=&#034;application&#034;&amp;gt;

&amp;lt;%-- Cached content goes here --&amp;gt;

&amp;lt;/c:set&amp;gt;
&amp;lt;c:set var=&#034;cachedStylesheetDate&#034;
  value=&#034;&lt;%= new Long(new java.util.Date().getTime()) %&amp;gt;&#034;
  scope=&#034;application&#034;/&amp;gt;
&amp;lt;/c:if&amp;gt;
&amp;lt;%
  long date = (Long) application.getAttribute(&#034;cachedStylesheetDate&#034;);
  long mod = request.getDateHeader(&#034;If-Modified-Since&#034;);
  if (mod &gt; date) {
      response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
      return;
  }
  response.setDateHeader(&#034;Last-Modified&#034;, date);
  response.setDateHeader(&#034;Expires&#034;, new java.util.Date().getTime() + 86400000);
%&amp;gt;
${cachedStylesheet}
&lt;/pre&gt;
&lt;p&gt;
Here&#039;s how it works:  We cache the content the first time the JSP is accessed as before, but we also set a session scope variable &lt;code&gt;cachedStylesheetDate&lt;/code&gt; that records the time when the output was generated.  Then on each request we fetch the value of any &lt;code&gt;If-Modified-Since&lt;/code&gt; header specified by the browser.  If the content was generated before the date, the browser already has an up-to-date version of the content, so we just send back a 304 response (Not Modified) to indicate that fact.  Otherwise we set the &lt;code&gt;Last-Modified&lt;/code&gt; header to the date when the content was generated, and then set the &lt;code&gt;Expires&lt;/code&gt; header to tell the browser to check again in (60 * 60 * 24) * 1000 = 86400000 milliseconds, i.e. in 24 hours, and then we send the cached output.  That way, after the initial fetch, the browser will only check once a day to see if the content has been updated - that figure can of course be adjusted as necessary.  
&lt;/p&gt;</description>
      <category>Web</category>
    <category>Tech</category>
    <comments>http://bleaklow.com:80/2007/10/15/producing_css_with_self_caching_jsps.html#comments</comments>
    <guid isPermaLink="true">http://bleaklow.com:80/2007/10/15/producing_css_with_self_caching_jsps.html</guid>
    <pubDate>Mon, 15 Oct 2007 06:29:59 GMT</pubDate>
  </item>
  <item>
    <title>XML-based J2EE frameworks considered harmful</title>
    <link>http://bleaklow.com:80/2007/05/03/xml_based_j2ee_frameworks_considered_harmful.html</link>
    <description>
          &lt;p&gt;
Are you using one of the XML-based web frameworks such as Spring, WebWork or 
Struts? Then you&#039;ve been duped. Conned. Flimflammed. Bamboozled. Hornswoggled. 
(Yes, this &lt;i&gt;is&lt;/i&gt; a rant ;-) Here&#039;s why:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;XML doesn&#039;t get executed, it gets read&lt;/b&gt;&lt;br /&gt;
Unlike Java source code, XML just gets read once rather than being executed. That means that it 
can&#039;t respond dynamically to changes in the application environment. You are 
stuck with whatever is configured at the time the XML is read - usually this is 
at the very beginning of your applications startup processing.&lt;br /&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;XML doesn&#039;t have constants or variables&lt;/b&gt;&lt;br /&gt;Want to use the 
same configuration value across multiple XML files? Tough, you can&#039;t. The only 
way you can get even remotely near to this is to use &lt;a 
href=&#034;http://blogs.sun.com/alanbur/entry/why_i_hate_xml_configuration&#034; 
target=&#034;_blank&#034;&gt;vile preprocessing hacks&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;XML 
doesn&#039;t have flow-of-control&lt;/b&gt;&lt;br /&gt;Want to put some conditional logic or 
loops in your XML? Sorry, there&#039;s no standard way of doing this. Sure, some 
frameworks attempt to provide this using their own custom XML entities, but 
every one of them does it differently.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;XML files aren&#039;t 
programs&lt;/b&gt;&lt;br /&gt;All that good stuff you were taught in your CS classes about 
type safety, information hiding, coupling, cohesion and so forth? Forget it, 
thanks to XML you are now back in the 1960&#039;s.&lt;br /&gt; &lt;/li&gt;&lt;li&gt;&lt;b&gt;Welcome to 
action at a distance&lt;/b&gt;&lt;br /&gt;See that attribute you set in your XML? Well, 
that probably has to map onto a method call on an object. Which method and 
which object? Prepare to spend hours pouring over the source of your framework 
to find out.&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You can&#039;t garbage-collect XML&lt;/b&gt;&lt;br 
/&gt;See all that XML goop you&#039;ve lovingly crafted? Well, say goodbye to large 
chunks of the memory on your machine. The application frameworks usually like 
instantiate all of the objects you might ever need at startup, because they 
have no way of knowing if they are ever used. And the frameworks make sure they 
are nailed into place, so forget about them ever being GC&#039;d if they aren&#039;t 
actually used.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You&#039;d better understand all about 
classloader leaks&lt;/b&gt;&lt;br /&gt;All this XML you&#039;ve used requires all sorts of 
introspective sleight of hand by your application framework. And that involves 
getting it&#039;s grubby little hands into the Java runtime support mechanisms, and 
holding references to bits of its innards such as classloaders. And the next 
time you redeploy your application, all those references probably aren&#039;t going 
to be cleaned up properly, so say goodbye to lots of &lt;a target=&#034;_blank&#034; 
href=&#034;http://opensource.atlassian.com/confluence/spring/pages/viewpage.action?pa
geId=2669&#034;&gt;leaked memory&lt;/a&gt;. And if you redeploy just a few times more, expect 
your application to fall over completely as it runs out of memory.&lt;br /&gt;&lt;br 
/&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You&#039;ve defeated type checking&lt;/b&gt;&lt;br /&gt;Most everything in XML 
ends up being a text string. That includes class names, method names and method 
parameters. Got one of them wrong? Oops, more mysterious exceptions will be 
heading your way at some random point in the future.&lt;br /&gt;&lt;br 
/&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Debuggers don&#039;t debug XML&lt;/b&gt;&lt;br /&gt;That cool debugger your IDE 
has? Don&#039;t bother. It doesn&#039;t work on XML files. The important bits of your 
application logic are now buried in some introspective labyrinth buried deep 
inside a library that you probably don&#039;t understand fully. Welcome instead to 
the world of cryptic stack traces and sleepless nights.&lt;br /&gt;&lt;br 
/&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You can&#039;t run &lt;a target=&#034;_blank&#034; 
href=&#034;http://findbugs.sourceforge.net/&#034;&gt;FindBugs&lt;/a&gt; or &lt;a target=&#034;_blank&#034; 
href=&#034;http://pmd.sourceforge.net/&#034;&gt;PMD&lt;/a&gt; on XML&lt;/b&gt;&lt;br /&gt;Those nice tools 
that check your source code for programming errors? Guess what? They don&#039;t work 
on XML. You&#039;ve just thrown away another tool in your armoury.&lt;br /&gt;&lt;br 
/&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You&#039;ve moved bug detection to run-time&lt;/b&gt;&lt;br /&gt;All that 
wonderful checking that the Java compiler does to make sure your application is 
correct? Gone, javac doesn&#039;t do XML. You aren&#039;t going to know if your 
application is even minimally correct until you try running it - and there&#039;s a 
fair chance that it will run for some considerable time before you find out 
that you&#039;ve made some simple programming error or other.&lt;br /&gt;&lt;br 
/&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You still have to rebuild your application if you modify 
it&lt;/b&gt;&lt;br /&gt;XML proponents tell us that one of the major benefits of XML for 
configuring J2EE frameworks is that you can reconfigure your application 
without changing the source. Really? How? Does anyone ever change the XML files 
in a deployed WAR file? Of course not, that would be insane. Ah, you have to 
edit the source XML files then rebuild and redeploy your WAR file - Oh dear, 
you still would have had to do that even if you didn&#039;t use XML at all.&lt;br /&gt;&lt;br 
/&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;You&#039;ve just doubled your troubles&lt;/b&gt;&lt;br /&gt;Think that Java is a 
big, complicated language? You &#039;aint seen nothing yet. Faced with a big complex 
application and want to figure out who is calling a method? Well, don&#039;t expect 
your IDE to be of any help, it doesn&#039;t understand your application framework&#039;s 
XML files. Trying to trace through the code and figure out what happens? Forget 
it. You&#039;ll go insane hopping between Java and XML source and trying to figure 
out which bit of opaque magic provided by your application framework is doing 
what, where and when.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I&#039;m fully aware that the list above is 
crammed with generalisations, and that there are various hacks and workarounds 
for some of the issues. However the overall point I&#039;m making is that XML isn&#039;t 
a programming language, yet virtually all of the major J2EE frameworks use it 
as if it is. The pervasive use of XML for tasks for which it is not suited has 
effectively discarded the last 30 years of software engineering advances. This 
is a huge mistake, and I expect that in 5 years time people will look back at 
the current XML mania and say &amp;quot;What the hell were we thinking 
of?&amp;quot;&lt;/p&gt;

</description>
      <category>Web</category>
    <category>Tech</category>
    <comments>http://bleaklow.com:80/2007/05/03/xml_based_j2ee_frameworks_considered_harmful.html#comments</comments>
    <guid isPermaLink="true">http://bleaklow.com:80/2007/05/03/xml_based_j2ee_frameworks_considered_harmful.html</guid>
    <pubDate>Thu, 03 May 2007 03:44:05 GMT</pubDate>
  </item>
  </channel>
</rss>

