Java applets were originally introduced to provide interactive features for web applications (Wikipedia). With javascript based libraries (jquery, yui), proprietary plugins (flash, silverlight or javaFX) and the oncoming HTML5 this intended purpose disappeared, but java applets remain useful for following reasons:
- Scala/Java is type safe: You can find errors early.
- You can use the same language like you used for your web application.
- The Implementation is browser independent.
Example: Distributed Computation of Perfect Numbers
Definition: Perfect Number (Wikipedia)
Testing numbers for perfection is a simple but process-time consuming task. It isn’t complicated to distribute the calculation on several computers. You can easily think of other domains where similar types of computations could be useful.
Application Overview
Instead of a javascript a java applet is used to factorize numbers. With the typical features of the lift framework, the application looks as follows:
Details: Server -> Client Communication
The snippet: You can deploy your java/scala applet with your web application.
You can invoke your applet method like a javascript function:
// OnLoad(JsRaw("findFactors('"+ c.toJson +"');"))
OnLoad(JsRaw(c.toJsCall))
Update your case class:
case class JobPackage(ticket: Int,
start: Long,
end: Long,
master: Long) {
import net.liftweb.json._
import net.liftweb.json.JsonDSL._
def toJson = {
val json = ("ticket" -> ticket) ~
("start" -> start) ~
("end"-> end) ~
("master" -> master)
compact(JsonAST.render(json))
}
def toJsCall = "$('#some-div').html($('#clientEngine').get(0).doCalc(" + ticket
+ ", " + start + ", "+ end +", " + master +"));"
Client -> Server Communication
Add your ajax call to your applet:
JSONObject serverPackage = new JSONObject();
...
private void sendResult() {
try {
String sps = serverPackage.toString();
getAppletContext().showDocument(
new URL("javascript:replyResult('replyResult', '" + sps + "')"));
} catch (MalformedURLException e) {
errorText = "Error: " + e.getMessage();
}
}
and dispatch the result:
def PMCall(s: String) = {
logger.info("PMCall " + s)
val cResJs = net.liftweb.json.JsonParser.parse(s)
val ticket = (cResJs \\ "ticket").extract[Int]
// With 2.8: facs.extract[List[Long]]
val facs = for{
JInt(fac) <- cResJs \\ "factors"
} yield fac.extract[Long]
PerfectNumberMaster ! PerfectNumberMaster.CalcDone(ticket , facs)
Empty
}
Download and run the example
The Sourcecode is available here.
Type: mvn jetty:run and open the url http://localhost:8080