Category Archives: javascript

Wrap Google map geocoder.geocode in a Promise

Futures and promises are a programming construct to make asynchronous programming easier to apply. They are provided in many JavaScript libraries and frameworks. Below we use Dojo’s implementation to wrap a non-promised based async operation, getting a Geocode from the Google Map API.

The Google geocode service takes a request object (which contains address information) and a callback function that takes a results object and a status string. If status is ok, the results object contains the geocode information (and a lot of other useful information).

In listing one the geoCode function wraps this in a Promise. Inside the function we create a deferred object, then invoke the above async geocode service, then we return the Promise interface of the Deferred object. Note, this is taken from a working application code, and that code works, this below, not tested.

Listing 1.

var geocoder = new google.maps.Geocoder();
 
function geoCode(request) {
    var deferred;
    require([ 'dojo/Deferred' ], function(Deferred) {
        deferred = new Deferred();        
        geocoder.geocode(request, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                deferred.resolve(results);
            } else {
                deferred.reject(status);
            }
        });
        
    });
    
    return deferred.promise;
    
}

You can use this as follows:

var promise = getGeocode(request);

Note that we don’t wait for the async operation to complete, or more correctly, invoke our callback function. The invoker of our geoCode function just gets a Promise object. So?

The Promise object is something that may get a value when it is fulfilled or it may get rejected. You find this out by reacting to those states. How? By using callbacks. So we are right back to where we started, after all the original geocode function also used callbacks. Ah, but here is the difference. With Promises, you are using something with more features and power. The Promise framework allows you to work with async code in a more frameworky way.

One of the nice features of Promises is that they can be “then’able”. “then” functions return a Promise, so they can be chained together: p.then(….).then(….).then(…..); Within each ‘then’, you supply a left and a right callback function, the left is for the resolved, the right is for the rejected state. Example:

var p = getGeocode(request)
p.then(successFunction,failureFunction);

You could also inline everything:

getGeocode(request).then(
    function(results){
       var x = do_something_with_result(results);
       return x;
    },
    function(status){
       do_something_with_status(results);
       throw "failed"
    }
});

These left and right are not chains themselves, there is one chain, but the left or right could be invoked depending on whether the preceding “then” resolved or rejected the promise. Of course, there are more details and each Promise implementation adds their own terminology and features. For example, Dojo has an always function that accepts a callback to invoke no matter what the previous ‘then’ did with the promise.

Apparently moves are afoot to make ‘futures’ part of the core JavaScript standard. These may be following the Promises/A+ specification.

A future blog post will provide a very easy to understand intro to Promises. There doesn’t seem to be a Promise for dummies on the web.

Further reading

YouTube

JavaScript Promises: Thinking Sync in an Async World

Redemption from Callback Hell

Times Developer Network – Promises, Promises

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

JavaScript focus event has wrong target?

I had an amusing debugging experience. Well, now it’s funny, then not so much. A focus event handler was getting events that said the same field was generating them. Even if other fields were selected.

I am using Dojo’s event API. This, like most other frameworks, make JavaScript event handling very simple, and most importantly handle the cross-browser issues.

The event tracer
I put a listener on a field’s ‘change‘ event using dojo/on, example:

on( theNode,'change',
      function(evt){
          mode = 'rent';			
      }
);

The callback handler just set a state variable. I also attached a listener to the ‘focusin’ event on a few other fields using the ‘on‘ method of Dojo’s NodeList:

query.NodeList().concat([moeNode,larryNode,curlyNode]).on('focusin',function(evt){
	evt.stopPropagation(); // needed?
	if(mode == 'rent'){
	    doSomeRentyThings(evt);
        }
});

This second handler used the value of the state variable. That is, I wanted to know that the user went from a particular field ‘A’ to another group of fields ‘B’. Hopefully someone can tell me the correct way to do something like this. Yes, a kludge, but it had to be done immediately, not on a single ‘submit’ button.

What should happen is that when the mouse leaves the first field (or user tabs away) and lands on one of the second fields, the status variable would have the correct value and be used by the second handler. It works!

Since the field setting is very fast, very few users could be faster. I know, async stuff; the browser could have a delay, etc. Don’t try this at home. Hmmm, but the browser is single threaded, so how could …. Anyway, in this app that would not be a disaster.

It stopped working
But, then I was developing something else on the same page using the Chrome debugger, and the above kludge stopped working. Huh? Even if I clicked on empty space in the browser, the event captured would be from the last field that the mouse was on. I re-read the Dojo docs, went back to the W3C stuff on Events, etc. Could find no web site where someone experienced a similar issue. I started blaming the Dojo toolkit, maybe there is a bug or the docs are incorrect.

I asked a co-worker, but they didn’t want to solve the problem just tell me that the app requirements were wrong, it’s too complex, blub, blub, blub. Most of the time feedback like this is important. One can get stuck in fruitless paths or need to see a different view of the goals. Perhaps, but in this case something obvious was wrong and I will probably face the same debug problem in the future.

Solution
Then I noticed that when I went from the Debugger back to the browser and clicked on another field, a very brief underline appeared in the previously selected field. Ah, how dumbskevisky, when I click on the browser anywhere, the previously selected field regains the focus and the focus event is generated. Obviously. The switch from debugger window to the browser window was the real change.

How did I confirm my observation? I closed the debugger window, and added console logging, like: console.log(“focus event on: ” + evt.currentTarget.name);

Take away

  1. Blame the tools last.
  2. Was working now not, what really changed?
  3. If it is hard to find a similar problem on web, your doing something wrong.
  4. When you ask co-workers for input be mindful of changing the context.
  5. Debuggers, while useful, can cause problems. The console is your friend.
  6. Take a break and work on something else.

What’s next?
There just has to be a better way of satisfying my web page requirements. No app at any point in time wanted to know what was previously changed?

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Template Method Pattern using JavaScript callbacks

JavaScript callbacks are usually discussed in terms of asynchronous behavior. Primary examples given of this are event handlers in the browser or XHR. Callbacks are used so much in JavaScript that there is even a new evil in the world, Callback Hell.

Callbacks are very useful for more familiar coding tasks and it doesn’t have to be about asynchronous services, or journeys into the compsci land of Functional Programming, or Monad this or that.

Template Method Pattern
The term ‘template’ is not related to templates as used in text substitution libraries. This pattern is used when an algorithm or operation has common behavior and the uncommon behavior can be ‘substituted” or deferred by various means.

Though this pattern is usually presented in terms of Inheritance in Class-based Object Oriented Programming, that is just an implementation example. JavaScript can and does implement this pattern; it is just not called by that name.

Simple example
Lets give a very very simple example of what this means. Lets say you have some widget on a web page that presents to the user some recipe based on some input conditions or properties. For simplicity, lets assume that this can be done in one function that consists of a series of statements that are the same except for a few steps.

The usual way to do this is to create multiple functions that change the widget in the required manner, or create one function that uses conditional statements to invoke the correct steps that vary for each type of recipe.

Below in listing 1, we have the behavior for the widget. Some statements come before and after the call of the doSomething() function. The problem with this code is that if we have to do different things, we must complicate the conditional or create other widgetRecipe type of functions that perform the recipe differently.

Listing 1, psuedo code of conditional use
functions widgetRecipe(){
statements before
if(something){
doSomething()
}
statements after
}

Example with callbacks
Since we have a process that differs in only one or more “steps”, the Template Method Pattern is applicable.

The recipe function in listing 1, can be simplified by replacing the conditional statement with the actual function to invoke. Functions in JavaScript are objects, so can be assigned to a variable.

In listing 2, we use the argument name secretSauce for that function that will be passed in. Some tutorials out on the web use the name ‘callBack’ to make it obvious that this is a callback function. Note how the passed in function is invoked, using “()”.

Listing 2, psuedo code using callback
functions widgetRecipe(secretSauce){
statements before
secretSauce();
statements after
}

We can define that function as: var bitterSauce = function(){ alert(“Add a dash of pepper”);}
Then invoke widgetRecipe like: widgetRecipe(bitterSauce);

One famous programmer, Chuck Moore, inventor of the FORTH language, said: don’t decide, compute. Here the function is computed elsewhere, perhaps a table of some kind.

Of course, you can have multiple callback arguments to a function, even an array of callback functions. You can even inline callback functions or make them anonymous. And, a callback function could have arguments too.

Complexities
Used in certain ways, a Callback function is a Closure. This can have, if not used correctly, very subtle issues. In addition, if the callback function uses this internally, you have to invoke it a certain way.

Some of the links below give more information on how to use callbacks and things to watch for.

Real world use?
I am almost done solving a programming problem where I have a ‘Callback Hell’ situation, and to make matters worse, the various slices of this hell needed to be reused. I think I solved it by abstracting out the variable behavior into a callback. Lets see if it survives code review.

Alternatives?
Since JavaScript is Object Oriented, but not via Classes as in Java, it can do inheritance, via prototypes. Thus, the Template Method Pattern can be implemented using prototypical inheritance. This approach is present here, JavaScript Template Method.

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

dojo on.emit won’t work in FireFox?

Seems simple enough, using the Dojo toolkit click a div and trigger an anchor tag on the page.

The code in listing 1 below works on:
Chrome version 35
Internet Explorer 11

Won’t work on FireFox ver 30.

Dojo’s dojo/on module has the emit() method that provides a normalized way to dispatch events. It is supposed to be cross-browser.

From the info on this page, Disabling native events when using Firefox with WebDriver, it sounds like Dojo may, like WebDriver, be using FireFox’s native event facilities and failing.

<!DOCTYPE html>
<html >
<head>
    <script>dojoConfig = {async: true, parseOnLoad: false}</script>
    <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.10.0/dojo/dojo.js"></script>
    
    <style media="screen" type="text/css">
        .bold {font-weight: bold;}
        .box {border:1px black solid;margin-top:4em;margin-left:8em;}       
    </style> 
    
    <script>
        require(['dojo/ready','dojo/on','dojo/dom',
                   'dojo/query','dojo/domReady'],
        function(ready,on,dom,query){
            ready(function(){
                var nde = query('#div123');
                nde.on("click",function(evt){
                    on.emit(dom.byId('target'),"click",
                     {bubbles:false,cancelable:false});
                });                 
            });
        });             
    </script>       
    
</head>
<body class="claro">
    <div id="div123" class="bold box">click me!</div>
    <div class="box">
     <a id="target" href="javascript:alert('hello')">will trigger this link</a>
    </div>
</body>
</html>

Listing 1

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Understanding JSON

There seems to be a little bit of confusion among some developers as to what JSON is.

Some think some that JSON is a JavaScript serialization, or that it is just a way to pass JavaScript data around. Well, there are good reasons why this may be assumed. One is that JSON is usually used in HTML based client UIs, and it does have JavaScript in its acronym, JavaScript Object Notation. There are also many sites and YouTube videos that present JSON in a very JavaScript and browser client centric way.

It is not these things, though it is used like that (to some extent). The definition is plain enough:

JSON … is a lightweight data-interchange format. … It is based on a subset of … JavaScript …. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. — http://json.org/

The important points are:

  • data-interchange
  • text based
  • began as a subset of JavaScript’s collections
  • language independent

Note that there is nothing about Objects in there. The Object, that comes later in the spec, is what would be called a Map or Table in other scenarios. Yes, “but, JavaScript has Object Literal Syntax”, no matter.

I expect that the JSON word will lose its acroynm-ity in time and just become the name for a format. A similar thing happened to the OSGi trademark, it no longer means what it used to mean, and XML, means pointy brackets everywhere.

Updates
Aug 2, 2014: There is one scenario where thinking that JSON is just JavaScript object serialization is correct. When your working with JavaScript object serialization. Thus, when you send JSON from a browser client to a backend Java middleware, a library, such as GSON, will be used to deserialize the JSON to Java objects. In this case, contextualizing that in JSON “{ }” is an object, makes it clear that your process will need a Java class at that point.

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Diagnostic Differential Logging with JavaScript Example

Synopsis
Reducing the quantity of information to what is essential is very important in maintaining complex software. Modern development environments have debuggers and other tools to assist in this effort: conditional breakpoints, watch expressions, logging, stop on change techniques, and so forth.
As a supplementary technique an approach to debugging is shown which uses the dynamic differences in a running system to output a reduced level of information. A simple programmatic implementation is shown in a JavaScript scenario, but the technique is applicable using other languages and automated techniques.

KEYWORDS: logging, diff, debugging, diagnostics, BIST, JavaScript, AOP, BIST

Context
Recently I was debugging a legacy JavaScript program. I used the outstanding FireBug plug-in in the FireFox browser. By the way, FireBug is truly indispensible, such a wealth of features and it is FOSS. Now combine that with Selenium which gives you the ability automate the browser and you have a powerful Integrated Development Environment (IDE). All that could be lacking is time and skill.
Unfortunately, I was not finding the problem. Later at home I got an idea. What if I could simply log what changed? That way I could more clearly see how the program behaves. All programs are just obfuscated state machines. Through a use-case or scenario, state variables are being manipulated and non-state data is being changed. Correlating these two with the events that drive the system, is a prime aspect of debugging.

Forces
• You want to log what is happening in a system, but you don’t want to be inundated with non-useful data.
• You or someone else want to be able to quickly resume this investigation in another situation or project.
• By saving ‘interests’, a Built-in-self-test aid can be implemented.
• During development hooks can be put in place to provide differential logging.
• You want to capture the live system not a system which is controlled by a debugger.
• You cannot install new systems, tools, or frameworks to help.
• Breakpoints will break as the system is maintained.

Solution
My solution was to dynamically log the differences. I’m sure this is not new. However, it probably is not explicitly discussed. The usual approach is to log as much as possible, but since this is prohibitive, instead the logging is limited, level filters, and contexts are used to control the output. Breakpoints and watches while usually enough to do the job are in the long term brittle since the target program may change during the dev and debug process. Thus, dynamic difference reporting would be a better approach in this situation.

Consequences
Todo.

Implementation
There are a few implementation choices.

API
One is to declare the data of interest. Then the logging system will track these and only output anything when there is a change in any of the data. With this approach the logger must be triggered either manually or automated. Manually is very easy; at an event change or at enter and exit points of a module or function, the differential logger is invoked.

Automated
To avoid changing the source code (it may not even be available), AOP could be used to implement the above. For example, an Around advise can be used to differentially trace the changes in methods.

Framework Plugin
If the system under test is running as part of a debug or is instrumented, it may already have a facility to capture change events. For example, FireBug, the FireFox plugin has this and the FireBug plug-in, FireDiff, implements a change monitor and visualization output. There may be or should be a comparable plug-in for other systems like the Eclipse IDE.

Code Example
To illustrate this concept it is used to debug a web page’s DOM changes via JavaScript. The page has a button that when clicked will randomly change two input field’s content. Notice that when the change involves just an ordering of two adjacent characters in a field, it is not readily apparent. The Differential logging makes it explicit. The log output is just the result object converted to JSON. An example: {“event”:”run”,”record”:{“foo2”:[“”,”accd”],”foo4″:[“”,”ollrr”]}}. A real implementation would do otherwise.

To specify which DOM nodes to monitor, a JavaScript object is used:

{"foo2":{"get":"v"},"foo4":{"get":"v"}};

The “get” field is used to specify how to get the value from the browser DOM. Another method would be “innerHTML” access. A better approach is to detect the appropriate ‘getter’ via using the node type.

demo screen capture

Listing 1, implementation


/**
 * 
 * Differ constructor.
 * 
 * @param data which nodes to record
 * @param formatter how to show results
 * @returns
 */
function Differ(data, formatter){
	this.data = data;
	this.formatter = formatter;
	
	if(!formatter){
		this.formatter =this.format;
	}
};

/**
 * Data and methods of class.
 * 
 */
Differ.prototype = {
  MAXSIZE : 15,
	
  /**
   * Detect changes and save latest.
   * 
   * @param event Where was diff created
   * @returns result object
   */
  diff : function(event){
    var results = {};
		
    if(!data){
    	return results;
    }
		
    if(event){
    	results = {"event":event};
    }
		
    results["record"] = {};
		
    var record = results["record"];
		
    for(var key in data){			
      var ref = document.getElementById(key);			
      var domValue = "";			
			
      switch (data[key].get) {
        case "v":
          domValue = ref ? this.shorten(ref.value) : "";
          break;
        }
			
        var prior = data[key].value ? data[key].value : "";
			
        if((domValue != prior)){
          record[key] = [prior, domValue];
          data[key].value = domValue;
        }
    } // end for	
		
    return results;
		
  }, 

  /**
   * Convert results to message.
   * 
   * @param results object
   * @returns JSON
   */
  toMessage : function(results){
    var obj = results;
    if(!results){
      obj ={"error":"results is undefined or null"};
    }		
		
    return this.format(JSON.stringify(obj));
  },
	
  /**
   * Get size of an object
   * @param obj
   * @returns {Number}
   */
  size : function(obj){
    var len = 0;
    for(var key in obj){
      if(obj.hasOwnProperty(key)){
        len++;
      }
    }
		
    return len;
  },
	
  /**
   * Limit size of value.
   * 
   * @param value
   * @returns
   */
  shorten : function(value){
    return (value.length > this.MAXSIZE) ? 
	value.substring(0,this.MAXSIZE-1):value;		
  },
	
  /**
   * Make message human readable.
   * 
   * @param message
   */
  format : function(str){
  	return str + '<br/>';
  }	
	
};	

Listing 2, Demo script

var data = {
  "foo2" : {
    "get" : "v"
   },
  "foo4" : {
    "get" : "v"
   }
};

var differ = new Differ(data);
differ.diff(); // prime values

function runIt() {
  var ref2 = document.getElementById('foo2');
  var ref4 = document.getElementById('foo4');
	
  if(Math.floor(Math.random()*101) > 60){
    swapInputs(ref2,ref4);
  }else{
    scramble(ref2,ref4);
  }

  var msg = differ.toMessage(differ.diff("run"));
  document.getElementById('output').innerHTML += msg;
  document.getElementById('output').innerHTML += 
    Array(60).join("-") + "<br/>";
}

function scramble(ref2, ref4){
  var ch = ref2.value.charAt(1);
  var r2v = ref2.value;
  ref2.value = replaceChar(r2v, 2, ch);
  ref4.value = replaceChar(ref4.value, 2, ref4.value.
    charAt(1));
}

function swapInputs(ref2,ref4){
  var temp = ref2.value;
  ref2.value = ref4.value;
  ref4.value = temp;	
}

function replaceChar(str, ndx, v) {
  return str.substr(0, ndx) + v + 
    str.substr(ndx + v.length);
}

Listing 3, the demo web page

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; 
    charset=iso-8859-1">
  <link rel="stylesheet" type="text/css" href="style.css" />	
  <script type="text/javascript" src="DebugUtils.js"></script>	
  <script type="text/javascript" src="DemoDiff.js"></script>	
</head>
<body>
  <span class="mytitle">Differential Logging Example</span>
  <div style="width:600px;">
	<div class="box inputBox">		
		1: <input type="text" id="foo1" value="xyyz"/>
		2: <input type="text" id="foo2" value="acbd"/><br/>
		3: <input type="text" id="foo3" value="wzlm"/>
		4: <input type="text" id="foo4" value="olxrr"/>

          <span class="buttonClass">
	    <input type="button" id="run" value="Test" 
               onclick="runIt()"/>
	  </span>		
	</div>
	Output
	<div id="output" class="box inputBox"></div>
	<span style="float:right;margin-right:10em;font-size:xx-small;">
           &copy; Josef Betancourt</span>		
	</div>
</body>
</html>

Listing 3, css

body {
  background-color:#E6E6E6;margin:3em 8em 12em 3em;
}	
.box{
  border: 3px solid #D4D4D4;padding:8px;
  padding:2em 1em 2em;margin:10px 5px 20px;
}
.inputBox{
   background-color:Beige;margin-right:36px;
   width:475px;font-family:monospace;
}
.buttonClass{
    float:right;margin-left:1em;margin-right:3em;
}
.mytitle{
   text-decoration:underline;font-weight:bold;
}

Related Patterns
None.

Related Intellectual Property
None.

Further Reading

Debuggers are for Losers

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Java’s HTTP Server for browser-based Groovy app

Code illustrating use of the HTTP server included in Java JDK 1.6. via Groovy to present a browser-based UI to an app.

Result

The code allows this usage:

main.SimpleServer.serve(0){ s, t, p -&gt;
    // handle the request, response here...
    // now shut down,
    s.stopServer()
}

Listing 1, How it’s used.

This will create a web server using the host “localhost” at an unused port p, and then automatically open the default browser at “http://localhost:p/”. The closure will be the application. Neat. Of course, you would only use this behind a firewall, etc.

The above code, as a I later discovered, is very similar to other frameworks. Here is a new one I just learned about:

vertx.createHttpServer().requestHandler { req -&gt;
    def file = req.uri == &quot;/&quot; ? &quot;index.html&quot; : req.uri
    req.response.sendFile &quot;webroot/$file&quot;
}.listen(8080)
See also: vert.io. “Effortless asynchronous application development for the modern web and enterprise”

See also “Java development 2.0: Ultra-lightweight Java web services with Gretty” link, for an approach using Gretty.

Hmmm, just noticed that this is the ‘look’ of a simple node.js example. No way to dupe node.js of course, it is a low level thing, but can streaming event based programming be done with Groovy? Perhaps with GPars. See this discussion node.groovy?.

5/9/2011: Check out blog post on concurrent websockets. Instead of the Java 1.6 embedded server, this is based on Gretty. See also, Gretty/GridGain/REST/Websockets.

A sample session running the example code and using telnet is:

telnet localhost 21224
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /?reply=24 HTTP/1.1

HTTP/1.1 200 OK
Content-length: 15&lt;/pre&gt;
&lt;h1&gt;Wrong!&lt;/h1&gt;
&lt;pre&gt;Connection closed by foreign host.

The Eclipse console contains:

+++++++ Simple Server ++++++++++++++++++
uri: [/?reply=24]
protocol: [HTTP/1.1]
query: [reply=24]
path: [/]
params: [[reply:[24]]]
-------------------------

Stopping server ... stopped!

The browser will show:

The app as seen on browser

Scenario

You have to supply a GUI for running a local Java application. One example could be the setup of a product build. Builds, though usually executed with Ant, Maven, or Gradle, may still require the user to select some target parameters or build type. Why not just use the browser? It can present a more modern interface and with good design, allow more fault tolerant use then that with command line or multiple prompt boxes.

This approach also allows future remote build server use, since the designed browser UI can be reused. The browser is ubiquitous and creating web pages is relatively easy (though can be a hair pulling nightmare sometimes). And, with the use of AJAX and high-level frameworks, like Dojo, JQuery, or React, browser clients can more easily duplicate the usability of dedicated thick client apps. HTML5 (see HTML Cheatsheet) is also helping to obliterate any remaining reasons for using a thick-client app.

An embedded server as used here, is great when the task is ad hoc, short lived, or single user. In the provided example, once the input is received the server shuts down. For more complex or ubiquitous use a standard server or more powerful embedded server should be used.

Embedded Server

For a local application that accesses system resources and uses the browser as the UI, using an embedded server is the simplest approach. Pure Javascript, Applets, and other means are very complex and may run against configuration issues with Browser security settings and so forth. In the Java world, that would mean using the more popular Tomcat or Jetty servers.

However, Java 1.6 now includes a light-weight HTTP Server. So, the configuration and requirements are more tractable. Nothing more to download and programmatic configuration concerns are minor. Note that the Java HTTP server does not offer many features, one augments this with custom code. For example, parsing of the request query is not present.

That the package of this server is com.sun… is problematic. Will it stay around, become part of the javax packages, etc? Should the JDK even have this built in? According to this post by M. MacMahone

… is that the API and implementation are a fully supported, publicly accessible component of Sun’s implementation of Java SE 6. It does mean however, that the packages are not formally part of the Java SE platform, and are therefore not guaranteed to be available on all other (non Sun) implementations of Java SE 6.

Incidentally, the Groovy language has an import system, Grape, that can also make use of Tomcat or Jetty as transparently as using the JDK embedded server. See the Further Reading below for an example using Groovlets.

This code illustrates

(more for my future reference)
The list below was some of the things the code used and the final code listed here may no longer have them.

  • com.sun.net.httpserver API use.
  • Using JQuery in external js files.
  • How to stop the server.
    • With AJAX post
    • Timeout
    • HTTP context
  • Using ScheduledExecutorService to limit runtime.
  • A console ASCII spinner.
  • Groovy GString use.
  • Launching the default browser.
  • Selecting an unused port.
  • Simplistic state machine configuration.
  • Detecting Java version.
  • AJAX using JQuery.
  • Groovy object construction from script.
  • Use of Closure.
  • Basic authentication
  • Quasi Anonymous class use in Groovy
  • access to resources

Of course, not great example of the above, but … Warning, code is not production ready, etc. There is no real exception handling!

How it works.

TODO: Give some idea what all that code does.

The index.html creates a simple form with three buttons (submit, ping, and end), an input field, and a ‘console’ output area.

submit: send the answer to the server which then gives feedback, correct or wrong. The server then deliberately shuts down.
ping: sends an AJAX request to the ping context which just sends back the time, the response is appended to the console.
end: sends an AJAX request to the ‘stop’ context. The server responds with ‘stopping server …’, then shuts down. All buttons are disabled.

Why Groovy

Groovy is a dynamic JVM based language whose most prominent feature is that it extends the Java syntax to be more usable, i.e., less wordy,. From the example, a method that prints the contents of a map can be defined as:

def showInfo(info){info.each{ k,v -> println "$k = $v" }}

Then invoked as:

showInfo(uri:uri,protocol:protocol,query:query,path:path)

The Groovy In Action book is pretty thorough. Chapter 1 makes a good case, and may still be available here.

Why not Groovy? Well, being dynamic can be rough, especially if it impacts the ability of a IDE to offer the features that come from using Java, like completions, etc. The Eclipse plug-in is getting much better, and I read the IntelliJ IDEA groovy support is top-notch. But, the worlds most popular language, JavaScript, is dynamic, and it hasn’t bothered too many people (maybe end users?).

Source

When I first wrote this, I created a complicated “app” with a bunch of class files and so forth. Then I simplified it. Later I said, yuck. Finally I decided that this should just be a simple one method invocation as shown at the beginning of this post. Consequently, a bunch of stuff in this sample code is guarded by conditionals and it works but sure can be simplified.

While coding I ran into a strange classloader issue see this post. There are a few files in this demo

 
The source code can be downloaded at: here

Listing 4. TestServe.groovy (not a unit test, btw)

//import static main.SimpleServer as SS;   // still won't work!!! GROOVY-4386
import com.sun.net.httpserver.HttpExchange;
import main.SimpleServer

main.SimpleServer.serve(0){
	ss, t, params ->

	if(!(params.size())){
		def path = t.getRequestURI().getRawPath()

		if(path.length()>1){
			ss.sendPage(t,path)
		}else if(path =="/") {
			ss.sendPage(t,"/src/index.html")
		}
	}else{
		def answer = params.get("reply")
		reply = (!answer || answer[0] != '"42"') ? "Wrong!" : "Correct!"

		ss.sendString(t,"</pre>
<h1>$reply</h1>
<pre>")
		ss.stopServer()
	}
}

Listing 5 SimpleServer.groovy

/**
 * File: SimpleServer.groovy
 * Date: 20110314T2125-05:00
 * Author: jbetancourt
 */

package main

import java.io.IOException;
import java.io.OutputStream;
import java.net.Authenticator;
import java.nio.channels.*
import java.nio.*
import java.text.SimpleDateFormat
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit as TU;
import java.util.zip.*;
import com.sun.net.httpserver.Authenticator;
import com.sun.net.httpserver.Authenticator.*;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.BasicAuthenticator;
import java.util.concurrent.ScheduledExecutorService;
import org.codehaus.groovy.reflection.ReflectionUtils

import edu.stanford.ejalbert.BrowserLauncher;

/**
 * Example of using the Java 1.6 HTTP server com.sun.net.httpserver.
 *
 * @see "http://download.oracle.com/javase/6/docs/jre/api/net/httpserver/
 * spec/com/sun/net/httpserver/package-summary.html"
 *
 * Version 0.02
 *
 * @author jbetancourt
 */
class SimpleServer implements HttpHandler{
	static final STOP_WAIT = 2
	static final HOST = "localhost"
	static final HTTP_PROTOCOL = "http://"
	static final splashText = " Embedded Java 1.6 HTTP server example (ver $version) "
	static final company = " 20110314T2125-05:00 jbetancourt"
	static final UTF_8 = "UTF-8"
	static final version = "0.3"
	static final realmName = "my realm"

	static port =0 // if zero, get unused port
	static url
	static int  counter = 0 // for spinner
	static String basedir   // docbase
	static String scriptDir

	HttpServer server
	static SimpleServer simpleServer
	def SRC_INDEX_HTML = "/src/index.html"
	def serverPropFilePath = "server.properties"
	def props = new Properties()
	def browserLauncher
	def ScheduledExecutorService cancelExec
	def authenticate = false
	def Closure handleParams

	/**
	 * The only thing you really need.
	 * @param port   if 0, unused port will be used
	 * @param closure  handles the request,response
	 * @return
	 */
	static serve(port, Closure closure){
		def ss = new SimpleServer()
		ss.port = port
		ss.handleParams = closure
		ss.serverPropFilePath = ""
		ss.exec(new String[0])
		return ss
	}

	/**
	 * Entry point into the demo.
         * @param args
	 */
	static main(args) {
		splash()
		if(!validJavaVersion()){
			return
		}

		simpleServer = new SimpleServer()
		simpleServer.exec(args)

	} // end main

	/**  */
	def exec(args){
		def basedir = new java.io.File(".").getAbsolutePath()
		configure(args)
		createHTTPServer()
		start()
		println("server started. url=$url,basedir=$basedir,scriptDir=$scriptDir,")

		def spb = props.getProperty("progressBar")
		cancelExec = Executors.newScheduledThreadPool(1)
		keepAlive(false,
				TU.MILLISECONDS.convert(1L, TU.MINUTES))
	}

	/**
	 * Handle the given request/response.
	 *
	 * The first response is the input form.  The subsequent
	 * request evaluates the answer if any, and then the server
	 * is stopped.  Any exception will also stop the server.
	 *
	 */
	@Override
	public void handle(HttpExchange t) throws IOException {
		try{
			def uri = t.getRequestURI()
			def query = uri.getRawQuery()
			def path = uri.getRawPath()
			def params = parseQuery(query)
			showInfo(
				uri:uri,protocol:t.getProtocol(),
				query:query,path:path,params:params)			

			if(handleParams){
				handleParams(this, t, params)
			}else{
				if(query == null){
					if(path.length()>1){
						sendPage(t,path)
					}else if(path =="/") {
						sendPage(t,SRC_INDEX_HTML)
					}
				}
			}			

		}catch(Exception ex){
			ex.printStackTrace()
			stopServer()
			throw ex;
		}
	}

	/**  */
	def showInfo(info){
		println "+++++++ Simple Server ++++++++++++++++++"
		info.each{ k,v ->
			println k + (v ? ': [' + v +']' : ": []")
		}
		println "-------------------------"	

	}

	/**  */
	static splash(){
		println("$splashTextnn$company")
	}

	/**  */
	def configure(args){
		try{
			basedir = new java.io.File(".").getAbsolutePath()
			scriptDir = "$basedir/src/"
			def propFileName = (args.length) >0 ? args[0] :serverPropFilePath
			port  = unusedPort(HOST)
			url = "$HTTP_PROTOCOL$HOST:$port/"

			if(propFileName){
				def getResource = {def resource->
					ReflectionUtils.getCallingClass(0).
							getResourceAsStream(resource)
				}

				InputStream context = getResource(propFileName)
				if(context){
					props.load(context)
					context.close()
				}
			}	

		}catch(Throwable ex){
			handleException(ex)
		}finally {
			//System.exit(1)
		}
	}

	/**  */
	def createHTTPServer(){
		server = HttpServer.create(new InetSocketAddress(port),0);

		props.propertyNames().iterator().each{key ->
			if(key.matches(".*Context$")){
				def conf = props.get(key).split(",")
				def className = conf[0]
				def contextPath = conf[1]? conf[1].trim(): "/"

				def obj = createObjectFromScript(className, this)
				def context = server.createContext(contextPath, obj)

				if(conf.length>2){
					def authClassName = conf[2]
					def ac = createObjectFromScript(authClassName,
							conf.length > 3? conf[3] : realmName)

					context.setAuthenticator(ac)
				}

				def iProp = key + ".initialState"
				if(props.containsKey(iProp)){
					obj.currentState = props.getProperty(iProp)
				}

				iProp = key + ".transitions"
				if(props.containsKey(iProp)){
					obj.setTransitions(props.getProperty(iProp))
				}
			}
		}

		def context = server.createContext("/", this)
		if(authenticate){
			context.setAuthenticator(new MyAuthenticator("my realm"))
		}		

		server.createContext("/stop", [
					handle:{
						println("in handler for stop .. t[" + it + "]")
						sendString(it,"stopping server ....")
						stopServer()
					}
				] as HttpHandler);

		server.createContext("/ping", [
					handle:{ ct ->
						println("pinging ...")
						ping(ct);
					}
				] as HttpHandler);

	} // end createHTTPServer

	/**
	 *
	 * @return
	 */
	static boolean validJavaVersion(){
		def flag = true
		def ver = System.getProperty("java.version");
		if(!ver.contains("1.6")  &amp;&amp; !ver.contains("1.7")){
			println("ERROR *** Requires Java 1.6 or above. Detected: $ver");
			flag = false;
		}

		return flag;
	}

	/**
	 * Send the initial query page.
	 *
	 * @param t the request handler
	 * @param filePath the html file
	 * @return nothing
	 */
	static sendPage(HttpExchange t, String filePath) throws IOException {
		OutputStream os = null;
		try{
			def fPath = new File(basedir + filePath)
			def uri = fPath.toURI()
			Map>map = t.getResponseHeaders()

			def binary = false

			if(filePath.endsWith( ".js")){
				map.set("Content-Type", "text/javascript; charset=UTF-8")
			}else if(filePath.endsWith(".gif")){
				map.set("Content-Type", "image/gif;")
				binary = true
			}else if (filePath.endsWith(".jpg")) {
				map.set("Content-Type", "image/jpeg;")
				binary = true
			}		

			println("sending .... " + fPath)
			if(binary){
				byte[] bytes = readFile(fPath.getPath())
				t.getResponseHeaders().set("Content-Encoding", "gzip")
				t.sendResponseHeaders(HttpURLConnection.HTTP_OK,0)
				GZIPOutputStream gos = new GZIPOutputStream(t.getResponseBody())
				gos.write(bytes)
				gos.finish()
				t.close()
			}else{
				def response = fPath.getText()
				t.sendResponseHeaders(HttpURLConnection.HTTP_ACCEPTED, response.length());
				os = t.getResponseBody();
				os.write(response.getBytes());
				t.close()
			}
		}catch(FileNotFoundException ex){
			println(ex.getMessage())
		}catch(Exception ex){
			ex.printStackTrace()
			if(os){
				println("close output stream ...")
				os.close();
			}
		}
	}

	/**
	 *  Read file into buffer.
	 * @param path
	 * @return
	 */
	static byte[] readFile(String path){
		File file = new File(path)

		FileInputStream inStream = new FileInputStream(file)
		FileChannel inChannel = inStream.getChannel();
		def bb = ByteBuffer.allocate(1024*1024)

		while(true){
			int bytesRead = inChannel.read bb
			if(bytesRead == -1){
				break;
			}
		}

		return bb.array()
	}

	/**
	 * Send the resulting score based on response content.
	 * @param t
	 * @param answer
	 * @return
	 */
	static sendString(t, answer ) throws IOException {
		t.sendResponseHeaders(HttpURLConnection.HTTP_OK, answer.length());
		OutputStream os = t.getResponseBody();
		os.write(answer.getBytes());
		os.close();
	}

	/**
	 * Just followed example at:
	 * @see http://download.oracle.com/javase/6/docs/api/java/util
	 * /concurrent/ScheduledExecutorService.html
	 */
	def keepAlive(showProgressBar, Long maxTime){
		def handleBeep = cancelExec.scheduleAtFixedRate(new Runnable(){
					public void run(){
						if(showProgressBar){
							progressBar()
						}
					}

				}, 1, 4, TU.SECONDS);

		cancelExec.schedule(new Runnable(){
					public void run(){
						println("ncancel beeping")
						handleBeep.cancel(true)
						stopServer()
						System.exit(0)
					}

				},4, TU.MINUTES);
	}

	/**
	 *  In shell console, ASCII spinner gives visual feedback of running server.
	 *  Got idea for approach at
	 *  @see http://blogs.msdn.com/b/brada/archive/2005/06/11/428308.aspx
	 *  But, then took out the use of a switch.  As Charles Moore would say,
	 *  never use conditionals when it can be calculated.
	 */
	static def progressBar(){
		print("b${["/","-","","-"][counter++ % 4]}")
	}

	/**  */
	Object createObjectFromScript( String className, Object... args ) throws Exception {
		println "Creating $className"
		def gcl = new GroovyClassLoader(this.class.classLoader)
		def path = "$scriptDir${className.replace('.','/')}.groovy"
		def cl = gcl.parseClass( new File(path))
		def ni = cl.newInstance(args)
		return ni;
	}

	/**
	 * Get an unused port for server and browser url.
	 * If port is non-zero.
	 * BTW, at shell:
	 *   On windows:  netstat -an
	 *   On linux: netstat -an | grep -i listen
	 *
	 * @see http://stackoverflow.com/questions/573361
	 * /how-can-i-detect-a-free-port-on-the-server-by-code-from-client-side
	 *
	 * I tried simpler ways, but they didn't work. Like using 0 as port.
	 *
	 * @param hostname
	 * @return port number
	 */
	static int unusedPort(String hostname) throws IOException {
		if(port){
			return port
		}

		int minPort = 8000
		int range = 0xFFFF - 8000
		while (true) {
			int port = minPort + (int) (range * Math.random());
			try {
				Socket s = new Socket(hostname, port);
				s.close(); // is this wise?
			} catch (ConnectException e) {
				return port;
			} catch (IOException e) {
				if (e.getMessage().contains("refused")){
					return port;
				}
				throw e;
			}
		}
	}

	/**	 	 */
	def ping(t){
		def now = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date())
		sendString(t, "$now")
	}

	/**  */
	String getServerProperty(key){
		return props.getProperty(key)
	}

	/**  */
	def start(){
		server.start();
		launchBrowser(url)
	}

	/**  */
	def launchBrowser(url){
		new BrowserLauncher().openURLinBrowser(url)
	}

	/**  */
	def stopServer(){
		print("nStopping server ... ")
		((HttpServer)server).stop(2)
		print("stopped!")
		System.exit(0)
	}

	/**  */
	static handleException(Exception ex){
		println("ERROR: ${ex.getMessage()}")
		ex.printStackTrace()
		throw ex
	}

	/**
	 * Parse query into list of values array.
	 *
	 * @see http://stackoverflow.com/questions/1667278/parsing-query-strings-in-java
	 * @param query
	 * @return
	 */
	static Map parseQuery(final String query){
		Map params = new HashMap();

		if(!query || query.length() == 0){
			return params
		}

		def key,val

		for (String param : query.split("&amp;")) {
			String[] pair = param.split("=");

			if(pair.length > 0){
				key = URLDecoder.decode(pair[0], UTF_8);
			}

			val=""
			if(pair.length > 1){
				val = URLDecoder.decode(pair[1], UTF_8);
			}

			List values = params.get(key);
			if (values == null) {
				values = new ArrayList();
				params.put(key, values);
			}
			values.add(!val ? "":val );
		}

		return params;
	}

} // end SimpleServer

// the authenticator class.  Should have been just a simple inner class.
class MyAuthenticator extends BasicAuthenticator {
	/**  */
	public MyAuthenticator(String realm){
		super(realm)
	}

	@Override
	public Authenticator.Result authenticate(HttpExchange t){
		return super.authenticate(t)
	}

	@Override
	public boolean checkCredentials(String username, String password){
		//printf("user=%s, pass=%s%n", username, password)
		return true
	}
} // end MyAuthenticator class

Listing 6 server.properties If there is a setting for a property file it will be loaded and used. This is an example:

# SimpleServer configuration
#
# context = FQCN,path[,authenticator FQCN, domain name]*
controllerContext = main.AppContext,/question
controllerContext.initialState = running
# simple state transitions = state:next_state[,state:next_state]*
controllerContext.transitions = init:running,running:end
# Misc
host=localhost
stop_wait = 2
basedir=
scriptdir=
progressBar=true
browserLauncher=main.BrowserLauncher

Listing 7 index.html The ‘app’ UI:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
	<!--  <script src="/src/jquery.blockUI.js" type="text/javascript"></script> --><script type="text/javascript" src="/src/scripts.js"></script><script type="text/javascript">// <![CDATA[
 		$(document).ready(function(){ 				//$(document).ajaxStart($.blockUI).ajaxStop($.unblockUI); 				pingServer();	 				stopServer(); 		});
// ]]></script></pre>
<div class="box middle lightGrey">
<div class="middle">Embedded HttpServer Demo <span class="tiny">(com.sun.net.httpserver)</span></div>

<hr />

<form id="form1" class="box internal grey" action="/question" method="get" name="form1">
<input id="mode" type="hidden" name="mode" value="mathInput" />
<table width="100%">
<tbody>
<tr>
<td></td>
</tr>
<tr style="margin: 12px;">
<td><span id="lblReply" class="heavy"> What is "4"+"2"? </span></td>
<td><input id="reply" type="text" name="reply" /></td>
<td><input id="submitButton" title="submit" type="submit" value="submit" /></td>
<td><input id="pingButton" type="button" value="ping" /></td>
<td><input id="stopButton" type="button" value="end" /></td>
</tr>
<tr>
<td></td>
</tr>
</tbody>
</table>
</form></div>
<pre></pre>
<pre> 

Listing 8 scripts.js JQuery stuff:

// file: scrips.js
// author: jbetancourt
//
// External JQuery use.
// technique reference:  http://www.latentmotion.com/separating-jquery-functions-into-external-files-without-selectors/
/* <![CDATA[ */ var pingServer; var stopServer; (function($){ 	pingServer = function(){ 		$('#pingButton').click(function(){ 			$.get('/ping', {mode:"ping"}, 				function(data){ 				    $('#target').append(" "+data) 				},"html") 			    .error(function(response,status,xhr){ 					var msg = "Server does not responsd: "; 					$("#target").html(msg + " " + status + 						(xhr.status ? " xhr.status: [" + xhr.status + "] " 							 + "] xhr.statusText: [" + xhr.statusText + "]" 							 : "") 					); 				}); 		}); 	}; })(jQuery); (function($){ 	stopServer = function(){ 		$('#stopButton').click(function(){ 			$("#submitButton").attr('disabled','disabled'); 			$("#pingButton").attr('disabled','disabled'); 			$("#stopButton").attr('disabled','disabled'); 			$('#target').load('/stop', function(response,status,xhr){ 				if(status == "error"){ 					var msg = "Server does not responsd; "; 					$("#target").html(msg + xhr.status + " " + xhr.statusText); 				} 			}); 		}); 	}; })(jQuery); /* ]]> */

Listing 9 stylesheet.css

.heavy{ font-weight:bolder;}
.box{ border:2px solid black;}
.middle{ margin-left:auto;margin-right:auto;width:60%;}
.internal{ margin:2em;background:#F8F8F8 ;}
.horzCenter { margin-left:auto;margin-right:auto;width:50%;}
.grey { background:#F8F8F8;} .lightGrey { background:#F0F0F0;}
.large{ font-size:xx-large;padding-top:4px; padding-bottom:4px}
body{ width:960px }  .tiny{font-size:small;}

Listing 10 example app AppContext.groovy

/**
 * File: AppContext.groovy
 * Date: 20110320T1952-05:00
 * Author: jbetancourt
 */

package main

import java.text.DateFormat;
import java.text.SimpleDateFormat

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;

/**
 *  The context that hosts the application.
 *
 * @author jbetancourt
 *
 */
class AppContext  implements HttpHandler{
	def SimpleServer server;
	def static RUNNING = 'running'
	def currentState
	def transitions = [:]

	/**  */
	AppContext(SimpleServer server){
		this.server = server
		currentState = server.getServerProperty("initialState")
		def statesProperty = server.getServerProperty("transitions")
	}

	/**
	 * Handle the given request/response.
	 *
	 * The first response is the input form.  The subsequent
	 * request evaluates the answer if any, and then the server
	 * is stopped.  Any exception will also stop the server.
	 *
	 */
	@Override
	public void handle(HttpExchange t) throws IOException {
		try{
			def uri = t.getRequestURI()
			def final query = uri.getRawQuery()
			def path = uri.getRawPath()
			def params = server.parseQuery(query)
			showInfo([query:query,uri:uri,path:path,currentState:currentState,params:params])

			def mode = params.get("mode")
			if(atState("running")){
				if(mode){
					if(mode[0] == "mathInput"){
						def reply = params.get("reply")
						evaluateAnswer(t,reply)
						transitionNextState()
					}else if (mode[0]=="ping") {
						server.sendString(t,"huh?")
					}
				}
			}

			if(atState("end")){
				server.stopServer()
			}
		}catch(Exception ex){
			ex.printStackTrace()
			server.stopServer()
			throw ex;
		}
	}

	/**
	* And, send response.
	*/
   def evaluateAnswer(t,answer){
	   def reply
	   try{
		   reply = (answer[0] != '"23"') ? "Wrong!" : "Correct!"
	   }catch(Exception ex){
		   reply = "wrong"
	   }

server.sendString(t,"</pre>
<center>
<h1>$reply</h1>
</center>
<pre>")
   }

   /**  */
	def showInfo(info){
		println "++++++++ AppContext +++++++++++++++++"
		info.each{ k,v ->
			println k + (v ? ': [' + v +']' : ": []")
		}
		println "-------------------------"
	}

	/**	 	 */
	def ping(t){
		def now = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(new Date())
		server.sendString(t, "$now")
	}

	/**  */
	def setTransitions(s){
		s.split(",").each{ tran ->
			def kv = tran.split(":")
			transitions.put(kv[0],kv[1])
		}
	}

	/**   */
	def atState(s){
		return currentState == s
	}

	/**   */
	def transitionNextState(){
		print("currentState[$currentState],")
		def ns = transitions[currentState]
		currentState = (ns ? ns : "end")
		println("  next state=[$currentState] ")
	}

} // end AppContext class

Summary

Shown was a simple example of using the JDK 1.6 embedded HTTP server using the Groovy language.

Updates

  • April 15, 2011: Added some beginnings of code to handle image resources.
  • August 4, 2011: Just saw an old post on same subject. “Groovy++ in action: DSL for embedding HttpServer”. Added it to references. That one creates a DSL to use the embedded HTTP server. Nice.
  • Dec 4, 2011: This post has an example of using Gretty via Groovy: Five Cool Things You Can Do With Groovy Scripts
  • Feb 11, 2012: The internal JDK Http server is being used here: “How ION uses Virgo“.

Required Software

• Oracle Java JDK 1.6.0.24
• Groovy 1.8-rc3
• BrowserLauncher2

Dev Software

• Eclipse: Helios Service Release 2
• Windows 7 Pro, 64bit
• Mercurial 1.8.1
• TortiseHG 2.0.2
• MercurialEclipse 1.0.0
• Groovy-Eclipse 2.1.3

Further Reading

API
com.sun.net.httpserver
http://download.oracle.com/javase/6/docs/jre/api/net/httpserver/spec/com/sun/net/httpserver/package-summary.html

Other Servers
Vert.x
Gretty
“Java development 2.0: Ultra-lightweight Java web services with Gretty”
Tomcat

Jetty

HTTP Implementations in other languages
Python
Lib/http/server.py
CherryPy

Misc
* http://www.redtoad.ca/ataylor/2012/02/simple-servlets-in-groovy/
* Groovy++ in action: DSL for embedding HttpServer
* Java non-blocking servers, and what I expect node.js to do if it is to become mature
* Sun’s secret web server
* Using com.sun.net.httpserver
* node.groovy?
* Ratpack
* AsynchronousChannel
* Mp3d project (which uses com.sun.httpserver)
* Groovy Goodness: Groovlets as Lightweight Servlets
* Making a simple web server in Python.
* Embedded HTTP server
* Comparison of web server software
* Groovlets
* Practically Groovy: MVC programming with Groovy templates
* HTTP server API in Sun’s Java SE 6
* Using Sun Java 6 HttpServer to write a functional HTTP test
* Package com.sun.net.httpserver
* Example for Java HTTP Server API and Ruby WEBrick HTTP Server
* Loop back connection leak
* EchoServer.java
* JDK modules source
* Java Documentation 6.0 JDK Modules
* ServerImpl
* D. Ferrin resource access solution
* Simple Java HttpServer / Handler
* post by hiro345
* com.sun.net.httpserver.HttpServer for comet/cometd
* Separating jQuery Functions into External Files (without selectors!)

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

missing ‘}’ in xml expression javascript

Good thing the web is a great idiot reduction device*. I just spent too much time trying to debug why an external js file would not load after I send it using the embedded server I’m using.

Well, I searched using Google and found something in StackOverflow (great site!).

The thing with StackOverflow is that even there, you have to really read carefully and fast, you won’t get a blinking marquee telling you what you should know.

The page was relevant, but the answer (in my case) was found in a little entry. I was using the <script> tag in my external script file, doh!.

BTW, how do I vote for one of those little entries being part of the answer?

*Unfortunately, I think it is more the opposite when it comes to non-technical information. We should dump the “Urban Myth” term and use something else, “Web Myth”?

Further reading

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

jsUnit based tests won’t run in other folders?

This is why software is such a sometimes frustrating undertaking. I once had a jsUnit based test working. It ran fine in FireFox. Today it did not. Funny thing is that the existing tests that come with jsUnit still work. Other browsers fail too. (maybe).

It had to be a typo, bad url, or something. The jsUnit docs say that the problem is that I am not correctly giving the path to the jsUnitCore.js file. I tried everything. But, now I try to get smart. First copy the tests that are working to another folder. I copy failingTest.html to /temp/jsunit, and I also copy jsUnitCore.js there too.
Still doesn’t work.

I edit jsUnitCore.js, and add an alert to show that it is being executed or loaded. To make sure I really did it, I diff:

C:tempjsunit>diff failingTest.html javajsunittestsfailingTest.html

 
4,5c4,6
&lt;     &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
&lt;     &lt;script type=&quot;text/javascript&quot; src=&quot;./jsUnitCore.js&quot;&gt;&lt;/script&gt;
---
&gt;     &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
&gt;     &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;../css/jsUnitStyle.css&quot;&gt;
&gt;     &lt;script type=&quot;text/javascript&quot; src=&quot;../app/jsUnitCore.js&quot;&gt;&lt;/script&gt;

C:tempjsunit>diff jsUnitCore.js javajsunitappjsUnitCore.js

13,14d12
&lt; alert(&quot;Maybe a career in sanitation?&quot;);
&lt;

Try the test and I see the message. So, I know that the library is being found and is running. That is weird. Must be the browser. I empty the cache. still nothing. Arrrrr.

Google? I find a reference to jsUnit forum about someone having a similar problem. No advice, but one person gives a url for the solution. Is it a good url, spam, or worse? Nope its legit, and real advice. It is the browser. Thank you Andrew! I should have checked the forum first.

Browsers, bah! I hope they don’t start showing up in embedded systems. That’s probably how WWIII will get started, some Javascript mistyping.

Updates
17JAN11: Spoke too soon. FireFox ver 4.0b9 is showing the problem again. I’ll try in my Ubuntu instance too.

Links
JSUnit 2.2 on Firefox 3.07 – FTW

jsUnit

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.