Jim Driscoll's Blog

Notes on Technology and the Web

Archive for the ‘web’ Category

Eval JavaScript in a global context

leave a comment »

Even though it’s considered bad practice, it’s often handy to eval code in JavaScript.  And in my case, it was simply necessary, since the JSF specification requires eval of scripts. And it’s also necessary to execute those evaluated scripts in the global scope. It’s not as easy as it first looks.

For our first naive implementation, we’d simply used eval(src) in our first pass at the implementation.

This is utterly wrong, and to understand why, you’ll need to understand scopes. JavaScript has what you can think of as two different scopes – function scope, where you’re executing something in the context of a function, and global scope, where you’re executing something in a global context – for instance, if I say var j = 1; within a function’s scope, then the variable j is set to 1 within that function. If I say the same expression, var j = 1 within the global scope, then j is set to 1 everywhere in the program – in every function, provided that that function doesn’t define a j variable in its local scope. In browsers, the global context is window – this is the default object that everything gets hung off of if you don’t specify any other object.

So, when we said eval(src), we were executing the src scripts within the local scope of the function where eval was called – that meant that I would be getting different results when variables were declared and set than would be expected – in fact, for some cases, it just seemed like the scripts weren’t being executed at all.

So, what to do? Well, as is usual for the browser JavaScript, there’s Internet Explorer, then there’s everyone else. As is usual, IE, the crazy cousin Larry of the browser world, has a convenient, well intentioned, and utterly nonstandard way to do this: window.execScript(src) It works great – and the other ways I’ll detail here break rather infamously, so use this non-standard function on IE.

For more standards-respecting browsers, the way to do this should be to use the call function, which is a standard function attached to every Function object. So, eval.call(window, src) should work. But to understand why, it’s important to know about context, in addition to scope. Every function call has it’s own context: this is the object that’s represented by the special value this. When we use the call function, the first parameter is the context object we’ll use for this. This is handy for all kinds of purposes, but for us, it’s just nice to use to set the context to the window object – which, you’ll recall, is the global.

Sadly, eval.call(window,src) breaks on Chrome – it complains about contexts not matching. Odd – and I was unable to Google up why this might be so. But a couple lucky guesses later, and I discovered that window.eval.call(window,src) works on all non-IE browsers. Now, when I say “var j = 1”, the window[j] is the variable that’s set… So, that’s good. Why do we have to add the extra window. on Chrome? Not sure – I could guess, but it’s too likely to be wrong.

At this point, I thought we’d licked the problem. No such luck. Sure, global variables are getting set, but it turns out that if you say: alert(this) – then you would correctly receive the global object back on Chrome and Safari, but not Firefox – there, you’d get back the object that was the enclosing object before the call function got called. Very odd, and likely a bug in their implementation.

With a little help from Werner Punz, we figured out that they best way to get around this issue is to wrap the calling function in an anonymous globally scoped function. Like the Chrome bug, I can guess why this might work, but it would only be a guess. Better not to clutter up the internets with more guesses – I’ll just stick to what I know works.

Here’s the code that I now use to do a global eval:


var globalEval = function globalEval(src) {
    if (window.execScript) {
        window.execScript(src);
        return;
    }
    var fn = function() {
        window.eval.call(window,src);
    };
    fn();
};

Hope this list of tricks is helpful to someone else who’s looking to do something similar.

(This article originally published on my java.net blog on September 8, 2009.)

Written by jamesgdriscoll

February 9, 2010 at 10:17 PM

Posted in JavaScript, web

A simple Ajax JSF 2.0 example

leave a comment »

In my previous blog post, I talked about the New Composite Component feature of JSF. I’ll come back to that shortly, but I’d like to talk about another new feature: integrated Ajax support. While this part of the specification is still being finalized, I thought it might be worthwhile to see what a simple example of the Ajax support in JSF 2.0 will look like. (Don’t worry, I’ll tie this together with Composite Components in a future posting.


Now, before I start, please keep in mind that the final version of JSF 2.0 will make this even easier, with a declarative (tag based) way to call out to Ajax in JSF. But for now, we’ll have to be content with the Javascript centric approach described below. Also, to use this example, you’ll have to use Glassfish v3 prelude, updated to build 5 of the JSF 2.0 EDR2 release via the updatetool – just released a couple hours ago. And if that doesn’t say “this is Alpha level code”, I don’t know what does.


A fairly common “hello world” type ajax example is a counter – so let’s build an app that counts upward. We’ll need a simple bean to store the count, as well as increment it and reset it:


import javax.faces.event.ActionEvent;
import javax.faces.model.ManagedBean;
import javax.faces.model.SessionScoped;

@ManagedBean(name = "count")
@SessionScoped
public class Count {
    Integer count = 0;

    public Integer getCount() {
        return count++;
    }

    public void reset(ActionEvent ae) {
        count = 0;
    }
}



Note that unlike JSF 1.2, you can set up your managed bean without using the facesconfig.xml file – instead, you can just use annotations.


Now, we’ll look at the facelets file that we’ll be using, and then we’ll go through line by line. Here’s the facelets file:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:h="http://java.sun.com/jsf/html">
<h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
    <title>Ajax</title>
</h:head>
<h:body>
    <h:form id="form1" prependId="false">
        <h:outputScript name="jsf.js" library="javax.faces" target="head"/>
        <h:outputText id="out1" value="#{count.count}"/>
        <br/>
        <!-- Increment the counter on the server, and the client -->
        <h:commandButton id="button1" value="Count"
                         onclick="jsf.ajax.request(this, event, {execute: this.id, render: 'out1'}); return false;"/>
        <br/>
        <!-- Resets the counter -->
        <h:commandButton id="reset" value="reset"
                            onclick="jsf.ajax.request(this, event, {execute:'reset', render: 'out1'}); return false;"
                            actionListener="#{count.reset}"/>
    </h:form>
</h:body>
</html>



This form paints three widgets: An outputText, and two commandButtons.
outputText “out1” has the contents of the count value. “button1”, when pressed updates (and hence increments) the “out1” field and only that field” – there’s no full page reload. Similarly, “reset” resets the counter value, and updates the “out1” field, and only that field. Useful? Not really, unless you were to put a bunch of other things on the page, and didn’t want to refresh the entire page.


The h:outputScript tag says that we should include the JSF ajax library into our page. This is necessary for the call to jsf.ajax.request that we later make.


Note that even though the “out1” output text is the target of our ajax, it doesn’t contain any unusual markup.


Then, we have “button1” – it’s onclick method does two things – call jsf.ajax.request, and return false. The false return, for those not versed in JavaScript, means that it doesn’t actually call submit on the enclosing form.


The jsf.ajax.request call, on the other hand, takes three parameters. The first is the calling object, this. The second is the calling event, event. You’ll typically just use these values, so don’t worry too much about them.


The last parameter is a JavaScript object with two properties – an execute property, which takes list of the ids of all the JSF components that we would like to execute – since we’re executing this button, we’ll include it in the list as ‘this.id’. The second property is all the JSF components that we want to render – in this case, that’s just ‘out1’. That tells JSF to update the displayed value of the outputText component, above.


Lastly, we have ‘reset’ – it’s onclick is pretty much identical, but there’s an additional attribute, “actionListener”. Since we’re already executing ‘reset’, that means that JSF will call that method as part of the button push.


Hopefully this example was pretty clear – and fairly simple. Any questions? Ask below. (I’ll be doing more complex examples as the month progresses.)


Update: I’ve updated this example to be more clear, and to conform with the latest JSF 2.0 PR release.

(This article was originally published on my java.net blog on November 5, 2008.)

Written by jamesgdriscoll

February 9, 2010 at 6:31 PM

Posted in Java, JSF, web

Writing a simple Composite Component with JSF 2.0

leave a comment »


One of the pain points for JSF has always been the complexity that you face in creating components. In JSF 2.0, creating a new component that’s made up of existing components is a snap.


Here’s a quick example of how you can create a new component, and use it in your page.


For this example, I wanted to create a simple text box that has a yellow background. Useful? No. Simple? Yes 🙂 In fact, it only needs two files. (This may look like a bit of code for a blog entry, but bear with me – most of it is just xhtml fluff. There’s only about 4 or 5 lines that you’ll actually need to learn.)


The first file is the page itself. Since JSF 2.0 uses Facelets as the preferred way to create pages, we’ll use that. Here’s the page:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ez="http://java.sun.com/jsf/composite/simpleout">
<h:head>
    <title>Yellow Text Example</title>
</h:head>
<h:body>
        <h1>Output Text Example</h1>
        <h:form id="form1">
                <ez:out value="Test Value"/>
            <p><h:commandButton value="reload"/></p>
            <h:messages/>
        </h:form>
</h:body>
</html>



Two lines you need to care about here:

xmlns:ez="http://java.sun.com/jsf/composite/simpleout"

defines the composite component library, and
<ez:out value="Test Value"/>
then uses the composite component. But where is the “simpleout” component library? It’s in the directory WEB-INF/resources/simpleout, and the “out” component is defined in a file named out.xhtml in that directory. Here’s the contents of that file:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:composite="http://java.sun.com/jsf/composite">
<head>
<title>This will not be present in rendered output</title>
</head>
<body>

<composite:interface>
    <composite:attribute name="value" required="false"/>
</composite:interface>

<composite:implementation>
    <h:outputText value="#{cc.attrs.value}" style="background-color: yellow"/>
</composite:implementation>
</body>
</html>



Again, there’s really two bits to look at here. The first is
<composite:attribute name="value" required="false"/>
says that our out component can take one attribute, named “value”, and that it’s presence is optional. Then,

<h:outputText value="#{cc.attrs.value}" style="background-color: yellow"/>

is where we actually define the component, with the “value” attribute set to the value attribute that’s been passed in.


And that’s it. No Java code is required for this very simple example.


I’ll do other blogs about how to create more complex composite components, but I hope that I’ve made my point about how very simple this new way of component creation can be.


As always, if you have any questions, feel free to ask. And remember that you can try out this example by downloading GlassFish, and updating to JSF EDR2.


Update: I’ve updated this example to be more clear, and to conform with the latest JSF 2.0 PR release.

(This article was originally published on my java.net blog on November 1, 2008.)

Written by jamesgdriscoll

February 9, 2010 at 6:30 PM

Posted in Java, JSF, web

Comet TicTacToe

leave a comment »

Here’s the Comet TicTacToe that I went over in my BOF on Comet on Wednesday night. It’s pretty simple (though not as simple as my first example, or even the somewhat improved version) – just 200 lines of Java code (including the game logic), 50 lines of JavaScript (embedded in an HTML page), 50 lines of HTML, and a 75 line CSS file. Simple stuff, but if you’re looking to write your own Comet app, this might help get you started.


You can find the full Netbeans project here.


Essentially, the program logic is contained in only two files: ttt1.html, and CometServlet.java. Check ’em out. After my initial example two posts ago, these should be pretty self explanatory. If you have any questions, by all means ask in the comments below.

(This article was originally published on my java.net blog on May 8, 2008.)

Written by jamesgdriscoll

February 9, 2010 at 6:27 PM

Posted in comet, Java, web

Solving the Comet timeout problem

leave a comment »

In my previous blog, I mentioned that I didn’t like the hack of reloading the iframe via the post action – it’s hacky, and it’s not hard to imagine it messing things up in a more complex program.


Turns out the answer is both easy and blindingly obvious once you think of it: the iframe onload event. And while we’re add it, we’ll add a onerror event too.


In my previous program, I had had a hidden iframe, and on every update, I would reset the source for the iframe using the location property.


We’ll still do that, but add a new function:

       <iframe name="hidden" src="CometCount" frameborder="0" height="0" width="100%"
       onload="restartPoll()" onerror="restartPoll()" ></iframe>


Note the onload and onerror events – whenever the server closes the connection, these will be called. And here’s the function that’s called:

            var retries = 0;
            function restartPoll() {
                if (retries++ > 10) {
                    alert("The connection has errored out too many times");                    
                } else {
                    hidden.location = url;                    
                }
            }


Also, I’ve added a retry limit in there – it wouldn’t do to have the client go into a fatal spin just because the server is down.


Now when the server closes the connection (from a timeout, or an error), the client will continue to function, automatically calling back into the server. Not a solution you’ll want for every situation, but useful enough, especially for our small example.


Lastly, there was a bug in my previous version under IE – sorry about that. It turns out that if you send a POST via IE, you need to have a content body, or IE gets fussy. The fix is to change the line

            xhReq.send(null);
to
            xhReq.send("null");

I’ve uploaded new versions of the files index.html and CometCount.java, so you can see the complete code in context.

(This article was originally published on my java.net blog on May 5, 2008.)

Written by jamesgdriscoll

February 9, 2010 at 6:22 PM

Posted in comet, Java, web

Dead Simple Comet Example on Glassfish v3 / Grizzly

with 2 comments

I was looking at a recent blog by Shing Wai Chan and going through the Comet example, when I noticed that the example wasn’t working correctly. Although he updated his example to get around that problem, I was still a bit unsatisfied, and decided to sit down, using his basic example, and see if I could make it even simpler.

I’ve whittled it down to about 100 lines, and only 2 files, and I thought I’d go over it here. The full example (both files) are
index.html and CometCount.java. So this will be a little long, but if you’re tired of reading my rambling, just look at the files, and the code should speak for itself.

First, about the app: It’s a simple counter, which is updated every time you hit a button on the page. Pretty basic, except – every other web browser viewing that page will have the counter updated as well, through the magic of Comet.
About setting it up: make sure that the url mapping points to /CometCount, the value is hardcoded in a few places. Also, to compile you’ll need access to the Grizzly Comet APIs – you can either get them from Grizzly, or Glassfish v3 tp2. You’ll need to also add the jar in the modules directory named grizzly-optionals to your classpath in order to build, along with the standard Servlet API. You’ll also need to update the domain.xml of the v3 instance to add the property cometSupport=true, as you see below:


 

Now on to the description of the program flow. On startup, the servet is initialized, and registers itself with with the Comet Engine (make sure the servlet is installed with a url CometCount, or it won’t work). We set a timeout of 2 minutes.

 

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        ServletContext context = config.getServletContext();
        contextPath = context.getContextPath() + "/MyComet";

        CometEngine engine = CometEngine.getEngine();
        CometContext cometContext = engine.register(contextPath);
        cometContext.setExpirationDelay(120 * 1000);
    }

Then on the first load of index.html in the browser, the hidden iframe makes a call to the doGet of the servlet – this call suspends, awaiting further action. It does this by attaching the response to a handler (of type CounterHandler), and attaching the handler to the servlet’s CometContext. This also gives rise to the first bug of the program – there’s no display of initial result.

So this:
<iframe name="hidden" src="CometCount" frameborder="0" height="0" width="100%"></iframe>
calls this:
   protected void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {

        CounterHandler handler = new CounterHandler();
        handler.attach(res);

        CometEngine engine = CometEngine.getEngine();
        CometContext context = engine.getCometContext(contextPath);

        context.addCometHandler(handler);
    }

Next, someone, somewhere, who’s also using the program, hits the button marked “click”. This calls the onclick method, postMe(). postMe sends an empty POST to the servlet, triggering the doPost method.

So this:
<input type="button" onclick="postMe();" value="Click">
Calls this:
            var url = "CometCount";
            function postMe() {
                function createXMLHttpRequest() {
                    try { return new XMLHttpRequest(); } catch(e) {}
                    try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}
                    try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {}
                    alert("Sorry, you're not running a supported browser - XMLHttpRequest not supported");
                    return null;
                };
                var xhReq = new createXMLHttpRequest();
                xhReq.open("POST", url, false);
                xhReq.send(null);
                hidden.location = url;
            };

The doPost method increments the counter, and then sends a notify event to the servlet’s CometHandler.

    protected void doPost(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {

        counter.incrementAndGet();

        CometEngine engine = CometEngine.getEngine();
        CometContext context = engine.getCometContext(contextPath);
        context.notify(null);
    }

This event now wakes up that initial GET request, and sends a bit of javascript down the line. Lastly, we call resumeCometHandler, which marks the current event as completed, removing it from the active queue.

        public void onEvent(CometEvent event) throws IOException {
            if (CometEvent.NOTIFY == event.getType()) {
                int count = counter.get();
                PrintWriter writer = response.getWriter();
                writer.write("<script type='text/javascript'>parent.updateCount('" + count + "')</script>\n");
                writer.flush();
                event.getCometContext().resumeCometHandler(this);
            }
        }

Back at the client, that javascript that got sent down gets put into the hidden iFrame, and then executed. This calls the updateCount function, which updates the counter with the new value. Then, we set the iframes’ location object, which reconnects with GET to the servlet, and we’re ready for our next request.

            function updateCount(c) {
                document.getElementById('count').innerHTML = c;
                hidden.location = url;
            }

That is, unless we time out. If we time out (remember, we set the timeout to 2 minutes, not “infinite”), the iframe goes dead, the GET polling loop is broken, and we never again update the counter on the webpage, though the user’s increasing frustrated button pushing on the client will happily update counter on the server. So, to get around this, we add a single line at the end of our postMe function, updating the hidden iframe’s location again. This is the one really hacky part of the program, and I’d love to know a better way to do it. Also, it gives rise to the second bug of our program, related to the first – if the connection dies, you need to click the button twice to see an update of the counter on the client.
So – ta da! We have a bare bones, long polling comet application in two files and about 100 lines.
Again, here’s the programs
Download file index.html
Download file CometCount.java
Jeanfrancois Arcand and I have a BOF on Wednesday night (May 7th, 2008) at JavaOne. If you’re at JavaOne and are just getting started with Comet, come on by.

(This article was originally published on my java.net blog on May 1, 2008.)

Written by jamesgdriscoll

February 9, 2010 at 6:04 PM

Posted in comet, Java, web

Servlet History

leave a comment »

I’ve been doing servlets and JSPs longer than any other person on the planet (which in itself is a story for another time), so when I read a few things about the history of servlets in Beyond Java by Bruce Tate, I cringed. But I realize that such ancient history (10 years ago!) isn’t recorded anywhere, so I thought that I’d set the record straight.

In his book, Bruce says: “In the halls of Netscape, server-side Java emerged. Servlets (a term originally coined by O’Reilly) made server-driven Internet applications available to application developers. Sun capitalized on this movement quickly with a standard, and an open source implementation of a servlet engine called Tomcat.”

Whoosh, where to start. Prehaps at the beginning:

Servlets were originally conceived of by James Gosling in 1995, but put aside for other interests. After some time, the concept was picked up by Pavani Diwanji, who built on the concept to create servlets as part of a project then called Jeeves (from a fictional character). This project was eventually productized into the Java Web Server, which many of us in Java EE land remember fondly to this day. I still have a shirt showing Duke in a Tux holding a platter, the symbol for Java Web Server. And incidently, the first versions of the servlet package were called java.servlet.*, since the javax extension hadn’t been invented yet.

Incidently, JSP was invented over a weekend by Anselm Baird-Smith, then later elaborated on as a specification by Satish Dharmaraj (now of Zimbra). (Just in case anyone was curious.)

The server-side Java container conceived of by Netscape was done as a parallel effort, as was another similar thing done by Oracle. (I was part of the team that visited both companies to try to sell them on this technology.)

The Tomcat stuff came a few years later, as did the first version of the servlet spec, written by James Davidson.

As for O’Reilly coining the term servlets, I don’t know for sure about that, but given the history I do know, I’m skeptical.

There, I’ve gotten that off my chest.

Know something I don’t? Please comment below.

(Originally published on my java.net blog, on Dec 11, 2005.)

Written by jamesgdriscoll

February 9, 2010 at 5:10 AM

Posted in history, Java, servlet, web