Fun with Scala, JEE 6, JBossAS 7 and Async EJB

In this post i will show a simple Asynchronous service using enterprise Java Beans. Instead of using Java i will use Scala (to increase the fun :-) ). We gonna deploy the code in JBoss Aplication Server 7 (BTW this new version is ultra fast compared to JBOSSAS 6 and previous versions) this version is compliant with JEE6 and we will use one of the new features called Async support for EJB.

I will use maven 3 as a build and dependency management system. This code also works on JBossAS 8 akka Wildfly. If you are impatient  you can get the full code on my github. JEE6 don`t demand you to create an web.xml so we gonna create an servlet and an ejb using annotations only(that`s pretty cool).




WheaterServlet

package com.github.diegopacheco.jee6.scala.servlets
import com.github.diegopacheco.jee6.scala.services.WeatherService
import javax.servlet.annotation.WebServlet
import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.inject.Inject
@WebServlet(name = "WeatherServlet", value = Array("/WeatherServlet"), asyncSupported = true, loadOnStartup = 1)
class WeatherServlet extends HttpServlet {
@Inject
var weatherServiceEjbAsync:WeatherService = _
override def doGet(req: HttpServletRequest, resp: HttpServletResponse): Unit = {
weatherServiceEjbAsync.retrieve( req.startAsync() )
}
}
Note that i used the Annotations @WebServlet and @Inject. The first annotation is used in order to define a servlet in JEE6. You need set asyncsupported to true in order to have async support for EJB as well. Actually the async started at the servlet level and them an AsyncContext is propagated to the EJB context.

The second annotation is an CDI annotation, i used it because i want to inject an EJB instance on the servlet. As you can see i just delegate to work to an ejb on the doGet method of this servlet. Now lets take a look on the EJB code.

WeatherService

package com.github.diegopacheco.jee6.scala.services
import javax.ejb.Stateless
import javax.ejb.Asynchronous
import javax.servlet.AsyncContext
import java.io.PrintWriter
import java.text.SimpleDateFormat
import java.util.Date
@Stateless
class WeatherService {
@Asynchronous
def retrieve(ac:AsyncContext): Unit = {
Thread.sleep(5000)
val writer = ac.getResponse().getWriter()
writer.println(new SimpleDateFormat("HH:mm:ss").format(new Date()) + " Faz Muito Friu em POA Tche!")
writer.close()
ac.complete()
}
}
This is a Stateless EJB, note i'm using the @Asynchronous annotation in order to get the Async support for EJB, you also need receive the Servlet AsyncContext object by parameter. By deisgn i'm making this EJB wait 5 seconds before return the result this is just to simulate somethign that takes some time and don`t give an immediate response. Once i finished i need call the method complete on the AsyncContext.

Okay, almost there, now we just need create a simple HTML file with JavaScript in order to call our async servlet/ejb, so lets see.

<html>
<head>
<title>servlet-async</title>
</head>
<body>
<div>
This simple demo client continuously sends requests to <i>/WeatherServlet</i><br />
to invoke a resource intensive task which asynchronously generates a response.
</div>
<br />
Last response received at:
<div id="response">
<i>(no response yet)</i>
</div>
<script type="text/javascript">
function requestData() {
var request;
try {
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
} else {
request = new ActiveXObject("Microsoft.XMLHTTP");
}
} catch (e) {
alert("Your browser does not support XMLHttpRequest!");
}
request.open("GET", "WeatherServlet", true);
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200) {
document.getElementById("response").innerHTML = request.responseText;
requestData();
} else {
console.log("Unexpected response received from server:"+request.status)
}
}
}
request.send(null);
}
requestData();
</script>
</body>
</html>
view raw index.html hosted with ❤ by GitHub
Now i just need build the solution, you can do that doing: $ mvn scala:compile -DdisplayCmd=true install

Deploy your WAR file at JBossAS 7 or 8 and them just hit: http://localhost:8080/jbossas7-jee6-playground-1.0-SNAPSHOT/ and have fun :-)

Popular posts from this blog

Having fun with Zig Language

C Unit Testing with Check

Cool Retro Terminal