Java EE 6 and Scala

Last weekend while pondering the question “Is Scala ready for the enterprise?” I decided to write a simple Java EE 6 app entirely in Scala, without using any Java. I had three main reasons for doing this: one was just to see how easy/difficult it would be to write everything in Scala (it was easy). Another was to document the process for others journeying down the same road (the entire project is on github). Finally, I wanted to identify advantages of using Scala instead of Java that are specific to Java EE apps (I found several).

Background

The specific app I created was an adaptation of the Books example from Chapter 10 of Beginning Java™ EE 6 Platform with GlassFish™ 3. It’s a simple web app that displays a list of books in a database and lets you add new books. Although it’s a pretty trivial app, it does touch on several important Java EE 6 technologies: JPA 2.0, EJB 3.1 and JSF 2.0.

Next I rewrote the Java parts in Scala (and put it on github). Initially I did a one-to-one mapping of the Java classes to their Scala counterparts. Once that was complete I did a bit of refactoring to Book.scala and BookEjb.scala, so the versions you’ll see on github now look a bit different. During this process I did use some hints from a few other relatedblogposts.

The Java version has 58 lines of completely useless getters & setters. You need at least 9 lines per field and more for additional annotations. IDEs like Eclipse can generate these getters/setters for you, but they still take up space and must be maintained over time.

The Scala version needs only two lines per field: one for the @BeanProperty annotation to generate getters/setters in the compiled class and one to declare the field itself. This is seven lines less than the Java version per field.

Fields are declared as vars so they are public by default, mutable and every var that is a non-private member of some object implicitly defines a getter and a setter method with it. So “var x” defines a getter just named “x” and a setter named “x_=”. This lets you get the field using object.x and set it using object.x = y.

If JPA supported Scala-style accessors & mutators, we’d be done, but it requires the use of get/set methods. This is why we use @BeanProperty on each field. This instructs the Scala compiler to generate Java-style get/set methods in the compiled class file so it looks just like a Java entity to JPA.

You may also be wondering why each field is assigned a value of _ in its declaration. This is just the default value in Scala, just like omitting an initializer in Java: 0 for numeric types, false for booleans, and null for reference types.

The annotations also look a bit different; in Java they’re @Column(nullable = false) but in Scala are @Column{val nullable = false}. This is just how you do it in Scala.

I also pulled the id and description fields out into their own traits. This makes the entity class shorter and makes common fields reusable and more consistent across entities. I could have pulled all fields out into their own traits, but in practice there’s probably a limit to how much you’d want to do this, some fields will be specific to a single entity class and not reusable.

In the Scala version I created the CrudEjb trait that provides full CRUD support for any JPA entity, so the concrete EJB can be defined simply as BookEjb extends CrudEjb[Book]. In several places we need the Class object of the entity, which is difficult to obtain due to Java’s erasure of generic types at runtime. Scala’s Manifests are a great solution to this problem.

The Scala version requires the @LocalBean annotation while the Java version does not (not sure why). Also the EntityManager is defined as a var without the Java-style getters and setters. The container is able to inject the EntityManager using the Scala-style mutator (bean.manager = x) but it does log an error about it not having a set method.

The Scala version is basically just the Java version converted to Scala, no major changes, just looks a bit cleaner due to Scala’s concise syntax. As with the EJB, we get an error logged about not having a set method for injecting BookEjb, but the container does actually inject an instance properly.

Conclusion

Even though this was a simple example, I think it shows a few advantages of using Scala instead of Java in Java EE apps. You can forget about useless getters/setters in JPA entity classes, use traits to reuse common JPA entity field definitions and mixin common behavior in EJBs (example: BookEjb could also mixin Logging trait and other traits). And advanced Scala features like Manifests help you write better code faster.

This example only scratched the surface of what Scala can do, and didn’t even use things like closures, case classes, pattern matching or Scala’s functional programming capabilities (using Scala collections of JPA entities would help a lot).

I don’t think it’s quite there yet. And in the Scala Bazar many things exist in a rough, little maintained state like a draft for Unit support (Java is currently getting this on a core level with JSR-275)

In a few years I guess it’ll be ready, until then only considered research or POC quality, not production yet.

@Werner – while I agree not every enterprise should immediately switch from Java to Scala, there are some compelling reasons to start using it now. Scala compiles to Java bytecode so it can run on the same JVM as your existing Java classes and interact with them pretty seamlessly. And as I’ve shown here, Scala can be used end-to-end in a Java EE app.

Now, we need some better tooling and it will lift off! I did something similar and was impressed, too… there were some problems when mixing java classes and scala classes at the same time, referencing each other (chicken-egg). But I think, this is not a problem, but avoids bad code ; )

Nice to see an example of the use Scala in JEE. To be fair, your Java and Scala code do not also do the same thing. For exampe, in the JSF managed bean you use a lazy evaluation in getBookList and in Scala you do not (I think the lazy keyword should be helpful here).

hi, I’v tried to play a little bit with this and I found, that I can’t use EJB as I want, because I get NullPointerException. Do you know why?http://pastebin.com/uTACayqx
I always get the error at line 17 when I use the bean. (There’s also a need to tweak web.xml for services)
Thanks for answering!

For Named Beans in EJB 3.1 to work, they need implement the Serializable interface in Java, so while writing the same in Scala programming language, we “extend” it. The @LocalBean annotation is unique to the Scala implementation. Without this annotation, the session bean exposes a local business interface (ScalaObject in this case) as its client instead of UserController.

If you have Java and Scala referencing each other, you compile like this:

scalac *.java *.scala
javac *.java

The scala compiler knows enough Java to be able to understand what will be exported by Java code and use it to compile Scala code. Java can then use the generated class files.

@Werner eil

Scala Bazar is a failed experiment. There’s plenty stuff for Scala, but you won’t find it through that tool. Presently, the site implicit.ly and the scala tools maven repository are the best way to find stuff for Scala.

Hi Zach, Thanks for the good article! Very few articles on this topic on the Web even right now.
I tried running this example (am using lift basic archetype in eclipse; build through maven). I changed the code to use Derby DB (which comes default wtth basic archetype).

The index.jsp page redirects to “/listBooks.xhtml”. But when I run the app, I get an empty page. I then included Faces servlet mapping in web.xml as:

Faces Servlet
javax.faces.webapp.FacesServlet
1

Faces Servlet
*.faces

But, after doing this change, am getting runtime errors like “faces servlet not found” etc. Can you please help with this? How do Faces & Scala co-work? What happens when index.jsop redirects to /listBooks.xhtml. Does Lift have anything to do here?
Is there any update to your code after you posted in this page?