1 2 3 Previous Next

driscoll

96 posts

In my other blogging site, I've been using JDK 8 features to answer some sample interview questions. Here's a quick recap:

To learn the Java 8 API’s, I relied on Cay Horstman‘s just released book, Java SE 8 for the Really Impatient, and I can’t recommend it enough. It’s quite good.

The topics I covered were:

See the individual posts for more.

driscoll

DSLs in Groovy Blog

Posted by driscoll Oct 20, 2012

In my other blogging site, I've covered many of the basics of creating DSLs in Groovy:

Check them out if this looks interesting - I'm about to tackle my first real example - implementing a Turtle Graphics control language.

driscoll

A Turtle Graphics DSL Blog

Posted by driscoll Oct 6, 2012

In my previous post, I discussed the example program that I wrote to exercise the things I've described so far.

My very first programming language was BASIC.

driscoll

JavaOne on the Cheap Blog

Posted by driscoll Sep 29, 2012

I won't be speaking at JavaOne this year, and didn't get a pass through work.

Regular tickets to JavaOne are

Now that we've gone over some Groovy basics, it's time to switch back to writing in the Java language, and talk about how to run Groovy programs inside your Java programs.

In my previous post, I started with a simple Java program (which also worked in Groovy), and slowly stripped out the cruft until I was left with the following Groovy script:

def sayHello(name) {
    println("Hello $name!")
}
def name = 'world'
sayHello(name)

Now, let's add a little change to use an array.

Before I start talking about using Groovy's capabilities to create a DSL (mostly in Java), let's take a few minutes to go over what Groovy is.

Groovy is a general purpose scripting language which runs on the JVM, and can largely be viewed as a superset of Java.

I've been neglecting my blog, but just a quick note to mention that my latest talk at JavaOne, DSLs with Groovy, is posted up on Slideshare.

The talk's designed for someone with no significant Groovy experience (unlike most Groovy DSL talks), so if it's interesting to you, check it out.

I'm hoping (but not promising) to turn the talk into a series of Blog entries in the coming weeks.

driscoll

Testing JSF Blog

Posted by driscoll Jan 22, 2011

It's been a while since I've blogged last (ok, it's been a year), but I recently came across a question that I have a little insight into, and I thought I'd tackle it briefly.

The question was simple:

driscoll

JavaOne CFP Opens Blog

Posted by driscoll Feb 11, 2010
Although I'm not involved in the talk selection process this year, I'm still paying attention to JavaOne. The Call For Papers appears to be open now, through March 14th. Be sure to read the Submission Criteria before submitting a proposal for a paper. Trust me, it'll help your ideas get noticed. Good luck, everyone.  
driscoll

HTML5 Semantic Tags Blog

Posted by driscoll Feb 8, 2010

Over the weekend, I was reading Mark Pilgrim's great book on HTML5- and when I got to the part about the semantic tags, I thought it might be worth a quick mention.

In case you've missed out on HTML5 in general (and don't want to take the time to read that book I linked above), the idea behind semantic tags is that many sites use div blocks to mark out the same kinds of content, over and over. Content like headers, footers, and nav bars. Changing straight <div> tags to tags like <header>, <footer>, and <nav> is granting these tags semantic meaning, hence the name - semantic tags.

Semantic tags are a great idea. They offer a lot advantages over plain vanilla divs, especially for screen readers... but support in IE is pretty broken... The essential problem is this: unlike all other major browsers, IE doesn't know how to style unknown tags. So the following code won't work:

 

<style>
    .border {
        border: solid black;
    }
</style>
...
<section class="border">test3</section>

Ah, I hear the more informed folks in the audience say, there exists a library to fix this problem: the HTML5 Shiv. You can use it like so:

 

<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

This simple script will allow styles to be placed on unknown tags in IE... So, that's a good start, but there are a few problems with it. For one thing, it relies on JavaScript, so if JavaScript is disabled, your styling will fail catastrophically. Similarly, applying print styles may not work, since JavaScript won't necessarily be run as part of the print process (note: I haven't tested this fully, but that's sure what it looks like in brief testing). There are reports that nesting seems to mess stuff up applying styles correctly, but my testing hasn't found anything broken in this way that isn't already broken in IE's CSS support.

Of course, there is a way around even that: If you are running JSF or some other server side processing on your backend, you could do User Agent detection, and emit <div>'s to IE and the semantic tags to all other browsers. Then, by styling the tags solely with classes and ID's, it should be possible to make something that gets around the client side issues. Here's a section from a component that does just that.

 

@FacesComponent(value = "navtag")
public class NavTag extends UIComponentBase {
    
    @Override
    public void encodeBegin(FacesContext context) throws IOException {
        boolean isIE = false;
        UIComponent component = getCurrentComponent(context);
        String style = (String) component.getAttributes().get("style");
        String styleClass = (String) component.getAttributes().get("styleClass");
        ResponseWriter responseWriter = context.getResponseWriter();
        String ua = context.getExternalContext().getRequestHeaderMap().get("User-Agent");
        if (ua != null && ua.contains("MSIE") && !ua.contains("Opera")) {
            isIE = true;
        }
        if (isIE) {
            responseWriter.startElement("div", null);
        } else {
            responseWriter.startElement("nav", null);
        }
        responseWriter.writeAttribute("id", getClientId(context), "id");
        responseWriter.writeAttribute("name", getClientId(context), "clientId");
        if (styleClass != null) {
            responseWriter.writeAttribute("class", styleClass, "styleClass");
        }
        if (style != null) {
            responseWriter.writeAttribute("style", style, "style");
        }
    }

Should JSF add these tags to JSF 2.1? I'd love to hear your comments, below...

Progressive Enhancement is a philosophy of web design - start with simple pages, and build them up based on the capabilities of the browser viewing the page. It’s related to (and in some ways, the opposite of) the idea of Graceful Degradation, starting with a nice, fancy page, and dealing with any browser faults in an elegant manner.

Prehaps the simplest example to see this in action is the case of JavaScript being disabled in the browser - this is occasionally true for certain corporate clients concerned about security, and sometimes the case for very old browsers.

JSF handles this usecase pretty well - consider the following code:


   1
   2 <f:ajax render="grace :text">
   3   <h:selectBooleanCheckbox value="#{grace.checked}"/>
   4 </f:ajax>
 

This creates a checkbox input with an onclick event handler registered. If there’s no JavaScript enabled, it will continue to function as thought the ajax tag wasn’t there at all. But the user will need to submit the form with a button press...

There is another way to handle this: we could instead create a link, which uses view parameters:

 

   1 <f:metadata>
   2     <f:viewParam name="checked" value="#{grace.checked}"/>
   3 </f:metadata>
   4 <h:link value="check me">
   5     <f:param name="checked" value="#{!grace.checked}"/>
   6 </h:link>

That works, but isn’t as clean looking as the first, ajax method. Combining these approachs should provide a better user experience - and doing so isn’t especially difficult:

   1 <f:metadata>
   2     <f:viewParam name="checked" value="#{grace.checked}"/>
   3 </f:metadata>
   4 <h:outputText id="text" value="Checked: #{grace.checked}"/>
   5 <h:form id="form">
   6     <h:panelGroup id="grace" layout="block">
   7         <h:panelGroup id="default">
   8             <h:link value="check me">
   9                 <f:param name="checked" value="#{!grace.checked}"/>
  10             </h:link>
  11         </h:panelGroup>
  12         <h:panelGroup id="enhanced" style="display: none">
  13             <f:ajax render="grace :text">
  14                 <h:selectBooleanCheckbox value="#{grace.checked}"/>
  15             </f:ajax>
  16         </h:panelGroup>
  17         <script type="text/javascript">
  18             var def = document.getElementById("form:default");
  19             var enh = document.getElementById("form:enhanced"); 
  20             def.style.display = "none";
  21             enh.style.display = "block";
  22         </script>
  23     </h:panelGroup>
  24 </h:form>

First, create two divs, one with the link and the other with the checkbox, which is hidden by default. If JavaScript is enabled, then hide the link and show the checkbox. This is the basic idea behind Progressive Enhancement - first, create something that you’ll be happy with in any browser, then add features (in this case, an Ajaxified checkbox) as needed.

That’s all for today. One personal note: Today is my last day officially employed by Sun Microsystems - I wasn’t offered a position at Oracle, and I’m currently actively looking for something. Please feel free to checkout my resume, and let me know if you know of any openings that you think might be a fit for me.

In a recent blog, commenters took me to task for a perceived IE 6 memory leak. It wasn't actually there (they were wrong), but in attempting to prove myself right, I found a couple of memory leaks under IE in JSF's Ajax support. Since I just spent a week learning how all this functioned, I thought I'd set it down so that others could learn from my efforts. 

Now, none of the information that I'll present here is new - it's been discussed among Ajax programmers for at least the last 4 years. If you're a web guru, it's likely that you're not going to learn anything new here (thought I'd welcome any additional information and corrections). But at least a couple of the points I'll illustrate below are either poorly communicated or misunderstood. I'll include a number of links at the end of this article. There are also very significant differences between IE 8 (which mostly works), IE 7 (which is bad), and IE 6 (which is just awful). I'll try to point out the differences as they matter for each.

Tools

First - use the right tool for the job: In order to spot leaks, you'll need to download a tool that can detect them. By all accounts, sIEve is the way to go. It uses IE itself, and introspects to get it's data. The UI is pretty primitive, but I can't recommend it enough - it's truely invaluable. Since it uses IE for it's work, you'll need to run it on a machine that has IE6 installed - presumably in a VM. You'll also want to have it running on a machine that has IE 7 and IE 8 as well, just to be sure. XP fits nicely on a VM that runs on my Mac, and this is how I use it. 

Cyclic Leak

Now that that's out of the way, it's time to talk about the very worst of the memory leaks in IE - the dreaded cyclic reference, which the commenters thought that I'd committed. Under certain conditions, IE 6 will "leak" DOM nodes, retaining them, and the javascript objects that point to them, until the browser is either shut down, or crashes entirely due to lack of memory. Ugh! To understand how this happens, you really only need to know two things: 
  1. IE 6 (and 7!) reportedly has very primitive garbage collection using reference counting
  2. There are two memory spaces in IE, one for JavaScript, and the other for the DOM, and they don't communicate well.
What could go wrong? Well, lots. The commenters thought that the rule was: A leak will occur if any reference is made in JavaScript to an element that isn't eventually set to null. That's close, but not quite correct. The real rule is: A leak will occur if the JavaScript code contains any reference to the DOM that isn't released in some way, either by going out of scope or being explicitly unset. 

When IE 6 sees a JavaScript variable that is pointing to something in the DOM (typically, an element or node), it will record that reference, and not collect it - even when you surf over to a new page. And the DOM won't be collected, since there's a reference to it from JavaScript. These two objects, and all the stuff that references them, will stick around until shutdown. In IE 7, the geniuses at Microsoft saw the bug, and said "Hey, I know how to fix that, let's garbage collect everything when we leave the page.". Nice improvement, but it still doesn't fix the bug, since if you're developing a page that is designed to be used for a long period of time (like many page-as-application apps are now), it'll still crash the browser. Apparently, they saw the error of their ways eventually, since this behavior is no longer present in IE8. (All this is confirmed by my testing with sIEve.)

So, in the example that had in my previous blog, there was no memory leak, because the variable that pointed to the element eventually went out of scope. So - how to you create variables that don't go out of scope? The easiest way is to put them in an object - this was the leak that I eventually found in JSF. The fix there was to null out the object manually. But there's another, more insidious way to create an object - create a closure. That creates a function object implicitly under the window object, and that will never go out of scope. But the key thing to remember is that you need to be aware of when things go out of scope when coding in IE, and act accordingly.

But wait! There's more

If that was the only problem, life would have been fairly easy for me the last week. But that's not the only bug that the Web Wizards of Redmond chose to deliver to their unsuspecting consumers. There's another bug in IE (again, only in IE 6 and 7 - IE 8 appears to have fixed it per my testing), which also leaks DOM nodes that aren't cleaned up until you leave the page. Apparently, when the IE DOM receives a call from the removeChild or replaceChild functions, it doesn't actually, err, remove the nodes. It just leaves them there, hanging around the DOM like party guests that don't have the sense to leave after the host has started handing out coats. While these nodes will eventually be cleaned up when the user leaves the page, this still causes problems for page-as-app programs, as in the cyclic leak for IE 7, above. While the removeChild call is fairly notorious for this, I had to find out about replaceChild with my own testing (though I did find a few obscure references once I went looking for it). 

That means that instead of sayingnode.parentNode.replaceChild(newNode, node), you instead should say something like:node.parentNode.insertBefore(newNode, node); deleteNode(node); (with an appropriate if statement for isIE(), and a deleteNode function that doesn't use removeChild). And instead of saying node.parentNode.removeChild(node); you instead are reduced to coding something like: node.outerHTML = ''; (again, with browser check). Except that when you combine that with IE's horrible problems with manipulating tables, it may fail. So instead, you're probably better off with something like this:

 
                var temp = document.createElement('div');
                try {
                    temp.appendChild(node.parentNode.removeChild(node));
                    temp.innerHTML = ""; // Prevent leak in IE
                } catch (e) {
                    // at least we tried
                }
                deleteNode(temp);

Again, possibly with an isIE() check. 

Hopefully you found this description of IE's Memory "Management" useful. Here's a few of the links that I used for research, that I found the most helpful.

As always, I look forward to any comments. Especially about this topic - I'm far from expert in this area.

UPDATE: John Resig just posted about a very interesting looking tool. Haven't checked it out yet, but if it's got him excited...

Just a short post to note that we've now shipped Mojarra 2.0.1. This version fixes a very serious bug when running on Tomcat. You can pick up the files from the usual places, see the release notes for more information. If you're using GlassFish, and already running 2.0.0 (you leading edge adopter!), there's probably no reason to upgrade - though the new v3 (b69) has the updated jar, and it will be propagated via the usual Update Center distribution.  

Filter Blog

By date: