Why Scala? Java is fine
My personal opinion is, having done programs in many languages, that Scala is a huge step up from Java complexity-wise and many things are corner case fillers which probably could have been left out with a more lenient approach.
Nevertheless Scala has lots of merits as well.
The code reduction compared to Java on the average is 30-50% less thanks to better property handling and other things like closures.
The speed if touched right is about the same as Java (one of the complaints about groovy).
However, if you want to apply Scala you seriously have to touch it the way you would touch C++, make up your mind on what part of the language you really use and only touch others in rare cases.
But lets stop the criticism here. Scala has lots of merits especially for JSF:
- Absence of setters and getters
- Tight integration with Java
- Isolation of common constraints via Mixins instead of base classes
- Same or almost the same performance as java
- Closures for things like iteration
Part 1, Managed BeansThe possible easiest entry into combining Scala and JSF is to create a managed bean. Every managed bean in JSF is a pojo with a handful of setters and getters. (and more depending on your functionality)
It probably is the easiest artifact within the JSF stack you can get.
Let us have a look at a simple Java managed bean:
The same now would be coded in Scala
Note for the people who are familiar with Scala, we took two assumptions here, first we are using for familiarity
reasons the Java mutable LinkedList and secondly we use BeanProperties
(we could resolve that with our own el resolver as well)
This is tightlier written, but what about data encapsulation what about setters and getters?
Scala follows a different route for data encapsulation. You can set properties but usually the data is public until you have overrides which cause the data encapsulation without any further code interference.
Also one thing noticeable is, that the implements Serializable has been replaced by a @serializable annotation. The rest of the annotations is applied as is.
So what about this @BeanProperty?This is a special Scala annotation which tells the compiler to encapsulate the property and generate setters and getters for it.
I want to use CDI instead of ManagedBeansCDI has been the new kid on the block and given that bigger projects nowadays either use Spring or CDI it makes sense to cover the CDI integration here as well.
To sum the CDI and Scala situation regarding managed beans, it is as seamless as it is with pure managed beans.
Here is an example:
Of course you still can use @Inject and other CDI constructs as well.
@BeanProperties is this really needed?As you have seen @BeanProperties produces the connection between our properties and the EL by encapsulating the property and providing Java like setters and getters.
This is very inelegant, first of all, because to access those properties, you have to use the setters and getters on the Scala side as well, and the code is convoluted with annotations.
Wouldn't it be nice to simply have something like:
This works as expected, even the EL will pick up all properties, thanks to Scalas public per default convention. However we now face a problem, once we want to encapsulate for instance val1. If we now would make it private or protected the code definitely would be broken and the EL would not pick it up anymore. As long as you stay in Scala, you can use Scala properties, however the EL is implemented in Java and expects Java setters and getters.
So to make the EL scala aware we have to roll out a binding solution, but first, lets talk about Scala properties.
Scala properties are a different convention. From outside they are invisible by default but they still implement full isolation.
So, code like myobj.myprop = 1 still would be myobj.myprop = 1 after the isolation has been added.
So how do we do it?
- the def val1: Int = _val1 is basically our new getter replacing our old val1 for read access
- def val1_$eq (val1: Int) is basically a convention to open val1 for write access via the = operator.
The last remaining open problem is the Expression Language. The EL relies on setters and getters for accessing the properties.
Thankfully there is a way to override the ELs handling via a custom resolver tailored for Scala. Now this code would override the scope of this blog, but you can download the sources for this EL resolver as Maven project from https://github.com/werpu/scalaelresolver
(NOTE: You have to follow the included readme.txt for your own project integration)