Session and Entity Beans with Scala!

The most of J2EE applications developed are usually web + database applications. There’s usually a web framework like Java Server Faces used and jdbc, JPA, Hibernate, etc are used for the database interactions.
I’m on the quest to do all the above in Scala, and make life simpler because of Scala’s concise way of writing code and its various other advantages which have been elaborated on elsewhere.
So for my web application which was a Java EE 6, I chose:
JSF 2.0 for the MVC framework.
JPA for the database interactions.
Session Beans to interact with the Entity Beans.
Glassfish v3 prelude application server
Java derby Database(default)

All of the web pages were written in xhtml. The application I chose to rewrite was Dr. Cay Horstmann’s Simple Quiz web application from his blog here.

The design of the application is simple. It is a simple quiz based on common known facts of Java. So there’s a question and choices(using radio buttons) and at the end, there’s a page which displays the score.
For this, we use:
1. A managed bean.
2. A session bean.
3. 2 Entities.
4. index.xhtml and done.xhtml pages(one for the quiz, one for the score at the end)

To begin with, I simply rewrote all the Java code in Scala. Including the annotations used. However, the manner in which Scala annotations are written are different. For example, in JSF 2.0, the managed bean is annotated like this(thats right! No XML!):


@ManagedBean(name = "quiz")
@SessionScoped
public class QuizMB

In Scala:


@ManagedBean{val name = "test"}
@SessionScoped
class ScalaMB 

Again, in Java:

@OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL)    
private Collection<Choice> choices = new ArrayList<Choice>();

In Scala((the targetEntity is only necessary to work around a bug in 2.7 that will be fixed in 2.8 apparently):

@OneToMany{val cascade = Array(CascadeType.ALL),val targetEntity=classOf[Choice], val fetch = FetchType.EAGER } 
var choices: java.util.List[Choice] = new java.util.ArrayList[Choice]();

And my Session Bean looked like this:


@Stateless class QuizSB {

 @PersistenceContext private[this] var em: EntityManager = _

 def getQuestions():JList[Question]= {
 ................
 }

 def makeQuestions() {
 ...........
 }

def makeQuestion( _text:String, answer:String, otherChoices:String*) {
 ...........
 }
}

I then tried to access an instance of the SessionBean through the ManagedBean like this:

@ManagedBean{val name = "test"}
@SessionScoped
class ScalaMB {

@EJB private[this] var slsb : ScalaSB = _

def getCurrentQuestion():Question = {
 questions = slsb.getQuestions();
 questions.get(currentQuestionIndex);
}
...........
}

And my JPA beans were written as I have done before. A more detailed explanation of JPA for scala can be found here.

So this didnt work! No matter what I tried. Some of the things I tried:
1. Using setter injections instead of field injections for the session and entity beans.
2. Using JSF 1.2, incase the managed bean annotations were not being processed properly.
3. Looked at the bytecode to check the annotations were processed properly.
4. Looked at the glassfish code which handles the dependency injection.

I hung around on the #scala irc room on freenode asking questions. Dr. Horstmann asked around on java.net and after a while, I was very frustrated that a lot of experimentation was leading to little or no progress.
Dr. Horstmann then figured out from looking at this blog that the session bean implementing an interface and being annotated @Local would work! We then realized that we dont even need the interface, we just need to use a @LocalBean annotation, make sure the scala-library.jar was available properly and it would work!
So the final version of the session bean looked like this:


@Stateless 
@LocalBean 
class ScalaSB {

 @PersistenceContext private[this] var em: EntityManager = _

 def getQuestions():JList[Question]= {
 ................
 }

 def makeQuestions() {
 ...........
 }

 def makeQuestion( _text:String, answer:String, otherChoices:String*) {
 ...........
 }
}

To keep the process of deploying the war to glassfish simple and reliable, I wrote an ant script for it instead of relying on Eclipse to do the job for me.

So after 2 months of working on an already functional Java web app and getting it to work with Scala, whats next? 🙂
Well, whatever is next, will be easier since I’ve already figured out most of the kinks in the process. Or I hope I have…

Advertisements

5 thoughts on “Session and Entity Beans with Scala!

  1. Hi,

    So over here, are you using EJB in Java itself to code this application, Only difference is the implementation is in Scala. Am i right? And also in the previous program, if we are doing this operation on a remote machine.. How will you declare the deploy the remote machine annotation for the session bean?

  2. All logic is written using scala. Yes. And for a remote machine, we just change the annotation on the Session bean to @Remote.

  3. Hi
    Could you supply the full source code, it will be very helpfull for the learners., I have been trying to run a Scala web application with Derby and Hibernate. No success.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s