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…

Ant for Scala!

June 20, 2009

Ant has come out with a “scalac” task which compiles scala code. Since I did not want to rely on Eclipse to compile my scala code and build jars, etc, I decided to write my own Ant script to automate the process.

To begin with, we need to set the required properties:

I used a build.properties file to set scala.home value.

<property name="scala-compiler.jar" value="${scala.home}/lib/scala-compiler.jar"/>
<property name="scala-library.jar" value="${scala.home}/lib/scala-library.jar"/>

Then we define the scala classpath and the scala compiler command:

<path id="scala.classpath">
<pathelement location="${scala-compiler.jar}"/>
<pathelement location="${scala-library.jar}"/>
</path>

<taskdef resource="scala/tools/ant/antlib.xml">
 <classpath refid="scala.classpath"/>
</taskdef>

This is the main scalac target, here since I have some xml dependencies for my code, I copy them over to the build directory.
Then I compile the scala classes using the scalac ant task. Incase we want to mix scala and java code in the same project, I also have a javac target. Eclipse currently wont allow people to mix java and scala code, so this is cool.

<target name="compile" depends="prepare">
 <copy todir="${build.dir}/WEB-INF/classes">
 <fileset dir="${src.dir}">
 <include name="**/*.xml"/>
 </fileset>
 </copy>
 <scalac srcdir="${src.dir}" destdir="${build.dir}/WEB-INF/classes" classpathref="build.classpath">
 <include name="**/*.scala"/>
 <include name="**/*.java"/>
 </scalac>
 <!-- When we mix Scala and Java... -->
 <javac srcdir="${src.dir}" destdir="${build.dir}/WEB-INF/classes" classpathref="build.classpath">
 <include name="**/*.java"/>
 </javac>
 </target>
 

I build a war and deploy this war in the Glassfish server, so I have a target to build the war.

<target name="package" depends="compile">
 <jar jarfile="${deploy.war}">
 <fileset dir="${web.dir}"/>
 <fileset dir="${build.dir}"/>
 </jar>
</target>

Figuring all this out from the distributed help online was time consuming and painful, so I’m glad I can share :-) .

In parallel to my exploration of Lift, JSF 2.0 and other web technologies in order to come up with my own Scala based web framework, I’m trying to see whats the best way to provide plug-in support for such a framework would be.
This means delving into the very unfamiliar territory of Eclise plugin development. So, after playing around with helloworld equivalents of plugin development, I decided to check out some of the plugins provided by the “Web Tools Project” and see if I can make some modifications of my own.
Plugin development is different from the regular programming I’m used to, there’s a plugin.xml file which kind of acts as the pivot around which the whole plugin revolves. To run the plugin, one specifies a target eclipse platform(this means there’s 2 eclipse ides running during testing) and runs the plugin as an eclipse application which launches the target platform.
Used this tutorial  and found it very useful during this process.

adventures with liftweb

March 16, 2009

On the journey to create a JSF like scala framework, I’m currently in the process of studying how LiftWeb works. Obviously, the first step is to build something tangible and see what it does. A few observations to begin with:
1. Scala’s Eclipse support is not enough to provide a “create new liftweb project” option in Eclipse.

Instead, its a 2 step process:

Create a project using maven on the command line with:
mvn org.apache.maven.plugins:maven-archetype-plugin:1.0-alpha-7:create  \
-DarchetypeGroupId=net.liftweb                             \
-DarchetypeArtifactId=lift-archetype-basic                 \
-DarchetypeVersion=0.8                            \
-DremoteRepositories=http://scala-tools.org/repo-releases  \
-DgroupId=PROJECTNAME -DartifactId=PROJECTNAME

This generates a project outline,and to make it suitable for Eclipse, from the project folder, run the command:

mvn eclipse:eclipse

To set this project up in Eclipse, you do:
“Import -> General -> Existing Projects into workspace -> Project”

And this sets up a liftweb project in your Eclipse workspace. I havent yet figured out how to deploy the project into Glassfish directly, right now, to generate a war, from the project directory: mvn install

This install command generates a war in the “target” folder which I then deploy in glassfish using the admin console.

Again, because I havent figured out how to deploy into glassfish from Eclipse, I’m not sure how hot deploy works with Lift,but this blog assures us its possible.

Will keep posting updates as I continue my exploration of Lift Web.

Scala Nature in Eclipse

February 19, 2009

Since I’ve been trying to have Scala help with simplifying Java code, I’ve been looking into the possibility of having java and scala classes in the same project(under netbeans and Eclipse). While Netbeans doesnt seem to have this functionality available yet,  someone pointed out the “scala nature” functionality in Eclipse.

Basically, if you have a Java project, you can do a right click -> Scala -> Add Scala Nature. Doing so puts the scala libraries on the classpath and converts the project to a Scala project. This is supposed to allow one to have both Java and scala code in the same project and have them refer to each other.
I’ve been trying this. Here’s what I have:
1.  Scala objects are not visible from java classes, only scala classes are, this is apparently a known problem. I dont see why it would a problem allowing the access of the object’s methods like one would access static methods in Java.
2. When I right click -> Scala -> add Scala Nature for a JavaEE project, it does not add the scala libraries to the project classpath. So this does not solve my problem of having Scala code in Java Web apps.
3. So adding Scala nature only works for regular Java Projects for now.

Its a start though, and if we can access Scala objects and have JavaEE web apps which scala code in them, it’ll bring us one step closer to JavaEE nirvana :-) .

I decided to start using JSF 2.0 after Dr. Horstmann’s positive review of its features over the last few posts in his blog. Since my current set up is Netbeans 6.5 + glassfish v3 prelude as the server, I decided to update the JSF implementation to 2.0 in glassfish.

Following Dr. Horstmann’s instructions here, I downloaded the latest nightly build jars from here and copied over the 2 jars into glassfish. However, the update tool did not reflect this copy and still showed that I had JSF 1.2.

Since this didnt work, I next decided to run the updater jar and this ended up giving me the same error which was reported here on java.net.

Finally, Dr. Horstmann told me he discovered that deleting the existing JSF 1.2 implementation from glassfish v3 prelude allows the user to then add JSF 2.0.9 as an add on through the update tool. Hallelujah! This finally worked.

I’m really surprised though that the updater jar they expect to work so consistently failed for me and a couple other people who reported the same problems. Also, life would’ve been so much easier if glassfish allowed the user to update to JSF 2.0.9 without having to go through all the circus of manually trying to update the existing set up.

Anyway, if wishes were horses……

Scala with JPA

February 3, 2009

In my quest to make Scala blend with JSF and JPA, I’ve been trying to get an app working where I interact with the database while using Scala entities. Obviously, as a first step, I got a simple JPA project working, where my User class looked like:


import java.io.Serializable;
import javax.persistence.*;

@Entity
@Table(name = "user")
@NamedQueries({@NamedQuery(name = "User.findAll", query = "SELECT u FROM User u"),
@NamedQuery(name = "User.findById", query = "SELECT u FROM User u WHERE u.id = :id"),
@NamedQuery(name = "User.findByFirstname", query = "SELECT u FROM User u WHERE u.firstname = :firstname"),
@NamedQuery(name = "User.findByLastname", query = "SELECT u FROM User u WHERE u.lastname = :lastname")})
public class User implements Serializable
{
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "ID")
    private Integer id;
    @Column(name = "FIRSTNAME")
    private String firstname;
    @Column(name = "LASTNAME")
    private String lastname;

    public User() {
    }

    public User(Integer id) {
        this.id = id;
    }

    public User(Integer id, String firstname, String lastname) {
        this.id = id;
        this.firstname= firstname;
        this.lastname = lastname;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }
}

So once I got this to work, my next step was to write the same thing in Scala, I wrote it like:


import scala.reflect._
import javax.persistence._

@Entity
class User(@Id @Column{val name="ID"} @BeanProperty val id:Integer,
           @Column{val name="firstname"} @BeanProperty val firstname: String,
           @Column{val name="lastname"} @BeanProperty val lastname:String)
{

}

To make this work from my Java code, I made sure I pointed to my scala User class instead of Java, this includes the persistence.xml file as well. When I tried to run this, I got the following error:

Exception [EclipseLink-0] (Eclipse Persistence Services – 1.0.1 (Build 20080905) ): org.eclipse.persistence.exceptions.IntegrityException Descriptor Exceptions:

Exception [EclipseLink-63] (Eclipse Persistence Services – 1.0.1 (Build 20080905 )): org.eclipse.persistence.exceptions.DescriptorException Exception Description:

The instance creation method [scalajpa.User.], with no parameters, does not exist, or is not accessible.

Internal Exception: java.lang.NoSuchMethodException: scalajpa.User.() Descriptor: RelationalDescriptor(scalajpa.User –> [DatabaseTable(USER)])

So I realised I needed a default constructor for my User method, so I changed my scala class to:


import scala.reflect._
import javax.persistence._

@Entity
class User
{
    @Id
    @Column{val name="ID"}
    @BeanProperty var id:Integer= _

    @Column{val name="firstname"}
    @BeanProperty var firstname: String = _

    @Column{val name="lastname"}
    @BeanProperty
    var lastname:String = _
}

This worked out perfect. Talk about missing the obvious :-) . I realised I had to make this change when I looked here.

While I really like the compactness I got out of it, I’m not too thrilled about having to create a new Scala project, where I need all the EclipseLink libraries on the classpath, then build the Scala project into a jar and put it on the classpath of the JPA application. The whole process would be much easier if I could just create a Scala class right inside my JPA application and have it accessible from other java classes. I tried this and unfortunately the java classes did not recognize the Scala class :( .

As a next step, I plan to get a JSF + JPA application working with whatever help they can get from Scala.

So, I’ve started playing with Scala and my professor Dr.Cay Horstmann suggested that we should see how scala can be used in improving web applications which use JSF and JPA.
So as a first step, I started out by picking the java quiz example from chapter 3 of Dr. Horstmann’s very famous “Core JavaServer Faces” book. After getting it work with Java Beans. I decided to use scala to write the beans, because of the advantages scala provides by automatically generating getters and setters, etc.
So, I wrote a simple Scala program, built a jar out of it, and added that jar to the build path of the JSF app, and tried to call the scala code. It failed recognize the code and netbeans autocomplete didnt work(I picked netbeans because I wanted to work with glassfish v3 and I also feel netbeans has better JSF support than Eclipse).
I tried the same from Eclipse and while code autocompletion worked, the program failed to work because of class loader issues, until I realised that I needed the scala libraries on the java build path for Java to be able to call the scala code. Once I figured this out, I wrote the Scala classes I needed:


import scala.reflect._

class Problem(@BeanProperty val question: String, @BeanProperty val answer:String)
{
    def isCorrect(response:String):Boolean=
    {
        response.trim().equalsIgnoreCase(answer);
    }
}

class QuizBean
{
    var CurrentProblem:Int = 0;

    var tries:Int = 0;

    var score:Int = 0;

    var response:String = "";

    var correctAnswer:String = "";

    val p1 = new Problem("What trademarked slogan describes Java Development?Write once,.....", "run anywhere");
    val p2 = new Problem("What are the first 4 bytes of every class file(in hexadecimal)?", "CAFEBABE");
    val p3 = new Problem("What does this statement print? System.out.println(1+\"2\");", "12");

    val problems: Array[Problem] = Array(p1,p2,p3);

    def QuizBean()
    {
        startOver();
    }

    def startOver()
    {
        CurrentProblem = 0;
        score= 0;
        tries = 0;
        response = "";
    }

   def getQuestion():String =
   {
       val p : Problem = problems(CurrentProblem);
       p.getQuestion;
   }

   def getAnswer():String=
   {
       correctAnswer;
   }

   def getScore():Int=
   {
       score;
   }

   def getResponse():String =
   {
       response;
   }

  def setResponse(newvalue:String)
   {
       response = newvalue;
   }

   def answerAction():String =
   {
       tries = tries + 1;
       if(problems(CurrentProblem).isCorrect(response))
       {
           score = score + 1;
           nextProblem();
           if(CurrentProblem == problems.length)
               return "done";
           else
               return "success";
       }

       else if(tries == 1)
       {
           return "again";
       }
       else
       {
           nextProblem();
           if(CurrentProblem == problems.length) return "done";
           else return "failure";
       }
   }

   def startOverAction():String =
   {
      startOver();
      "startOver";
   }

   def nextProblem()
   {
       val p : Problem = problems(CurrentProblem);
       correctAnswer = p.getAnswer;
       CurrentProblem = CurrentProblem + 1;
       tries = 0;
       response = "";
   }
}

Once again, I built the scala code into a jar file, added the jar onto the JSF app build path, along with the scala libraries. I was still not confident that it would work,but the application worked with the simplest change. All I needed to do was to point to the scala class from the faces-config.xml file.
<managed-bean>
<managed-bean-name>quiz</managed-bean-name>
<managed-bean-class>scalacode.QuizBean</managed-bean-class>//This is the scala class.
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

After that, all I had to do was “run” the project and it worked like before :-) . Life is good again.

PS: please excuse the bad formatting, I havent figured out how to preserve code format here yet.

I just read this entry over at 37signals.com by David Heinemeier Hansson. Those who know me personally know that I’m really passionate about startups, I read about them, I want to work for one and that I’m fascinated by the way the startups work at a completely different level compared to the boring big companies.
In startup culture, its not uncommon to hear superhuman efforts, endless hours, thousands of lines of code in a few months, no social life which, when everything goes right, ends up with the company being bought for a few million or in some cases, going IPO.
The problem with that, at least for me is, if I’m going to pursue my ideas full time, I don’t have any other means of income, so this means I need to be able to work simultaneously on my ideas and the freelancing work that I do.
Reading something like this brings back a sense of calm to me, and I remind myself that this is not a 100 meter dash, its a marathon, and like David’s example about the Italian restaurant during startup school, I just want to be a small successful Italian restaurant for now, not a Sbarro, although hopefully I’ll end up like it.

I got my foosball table! I first played foosball table at the Google IO conference( I blogged about it here) and I wanted to get one for home! I searched on craigslist and a few other places but to my surprise, I found a really neat one on amazon.com!! It was really cheap but looked good and I immediately bought it. It showed up last friday and it was great! Everything about the table is good except the assembly instructions, which were really vague and hard to follow, so I had to spend a whole day putting it together, but all I’ve done this weekend is play foosball late into the night with my roommate :D

Above is a picture of my new foosball table!