Result

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/&#8221;. 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:

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?.

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 or JQuery, browser clients can more easily duplicate the usability of dedicated thick client apps. HTML5 (see HTML5 Rocks) 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