Developing Java EE 7 Applications with Scala (CON2644)
*Speakers: Peter Pilgrim*
Abstract: 750 words
Scala is an alternative JVM language with both object-oriented and functional programming paradigms. Scala development with the Java EE 7 platform is definitely possible and can be a pleasant experience. If you have uncertainty about how Scala can fit around the Java EE 7 platform, then this session aims to illustrate the huge benefit that Scala adoption can bring to the platform. Many other developers are taking advantage and the challenge of the JVM’s capability of being a vessel for multi-language programming. You no longer have to write every single project using Java, even if you like Lambdas experiences.
For the developer and engineering terms that feeling a little braver than usual, Scala is attractive as it is strongly typed and lets you set the gauge on how object oriented or how functional you want to be. You will learn how to reuse the annotations and creating Scala plain object safely and concisely.
This session will highlight and contrast the experience I had developing Scala solutions with Java EE, and there will be plenty of advice about using the functional programming features against the Java object oriented API.
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
BOF2644 Developing Java EE 7 Scala apps
1. Developing Java EE 7
Applications with
Scala (CON2664)
Demystifying the Object-Functional
Peter Pilgrim
Scala and Java EE
Independent contractor
@peter_pilgrim
2. Creative Commons 2.0
Attribution-NonCommercial-ShareAlike 2.0 UK:
England & Wales (CC BY-NC-SA 2.0 UK)
https://creativecommons.org/licenses/by-nc-sa/2.0/uk/
• Share — copy and redistribute the material in
any medium or format
• Adapt — remix, transform, and build upon the
material
• The licensor cannot revoke these freedoms as
long as you follow the license terms.
Xenonique
2
3. Xenonique
About Me
• Scala and Java EE developer independent
contractor
• Digital transformation / e-commerce
• Java Champion
• Working on the JVM since 1998
3
4. Xenonique
Java EE 7
Developer
Handbook
September
2013
Packt
Publishing
Digital
Java EE 7
Web APPS
December
2014
4
7. Xenonique
7
#1 Scala
Object-functional
Since 2003
Statically typed programming
Scalable Language
Inventor: Professor Martin Odersky, EPFL, Typesafe
8. Xenonique
8
#1 Scala
Pattern Matching
Case Classes
Traits, Mix-ins, Collections
Expressions, In-fix operators
Functions, Closures, Control Abstractions
Extension through Library functions
9. Xenonique
9
#1 Scala
Gradle, Gradle, Gradle v2.0
Groovy assembler, builder
Comprehensible, Configurable, Flexible
Works with Scala since Gradle v1.7
With Gradle, building WAR files is very straightforward
10. Xenonique
Scala Language
var age: Int = 37
val pi: Double = 3.141596527
val text: String = "human nature"
val r = if (age >= 18 ) "Adult" else "Child"
10
11. Xenonique
Scala Test #1
import collection.mutable.Stack
import org.scalatest._
import org.scalatest.junit.JUnitRunner
@RunWith(classOf[JUnitRunner])
class StackSpec extends
FlatSpec with Matchers {
/* ... */
}
11
12. Xenonique
Scala Test #2
class StackSpec extends FlatSpec with Matchers {
"A Stack" should
"pop values in last-in-first-out order" in
{
val stack = new Stack[Int]
stack.push(1)
stack.push(2)
stack.pop() should be (2)
stack.pop() should be (1)
}
/* ... */
}
12
13. Xenonique
Scala Test #3
class StackSpec extends FlatSpec with Matchers {
/* ... */
it should
"throw NoSuchElementException if an empty
stack is popped"
in {
val emptyStack = new Stack[Int]
a [NoSuchElementException]
should be thrownBy {
emptyStack.pop()
}
}
}
13
14. Java is a programming language.
Java is a virtual machine.
Java is a platform.
Xenonique
14
Java EE 7 released 2013
Built products on top of a standard platform
Transactions, Concurrency, Remote
Endpoints, Lifecycle, State, Persistence
20. CDI Model instance
class Account(
var balance: BigDecimal
)
// This is a complete class definition! ;-)
Xenonique
20
21. Xenonique
CDI Scala Gotchas
• Companion Objects cannot be used
• Case Classes (and obviously Case Objects)
– Failure due to creation of multiple static methods
in byte code
• Implicit class parameters
• Implicit method parameters
• Lazy public vals also fail
21
22. Building Java EE 7 War Files
• Gradle allows developers to build WAR files
very easy and also add customisation
• Explicitly include the Scala Library JAR as a
dependency
• With SBT, it is harder to create WAR files
– Battling between *.scala and *.sbt files
Xenonique
22
24. Xenonique
CDI Factory #1
trait Maker {
def createSample(): Fruit
}
@ApplicationScoped
class FruitFactory {
private class CocktailMaker extends Maker {
override def createSample():Fruit = new Strawberry
}
private class FruitSaladMaker extends Maker {
override def createSample():Fruit = new Banana
}
}
24
25. Xenonique
CDI Factory #2
@ApplicationScoped
class FruitFactory {
// ...
@Produces
def generateCocktail(): Maker =
new CocktailMaker()
@Produces
def generateFruitSalad(): Maker =
new FruitSaladMaker()
}
25
26. Xenonique
CDI Factory #3
trait Fruit {
val price: Double;
val name = this.getClass.getSimpleName
}
case class Apple() extends Fruit {
override val price = 0.75 }
case class Banana() extends Fruit {
override val price = 0.95 }
case class Strawberry() extends Fruit {
override val price = 2.99 }
26
27. #1 Collection Of Case
Xenonique
Classes
@ApplicationScoped
class FruitVendor {
def sell( fruit: Fruit with Product with
Serializable, quantity: Int): Double = {
fruit.price * quantity
}
}
27
28. #2 Collection Of Case
Xenonique
Classes
@Test
def shouldPriceFruitWithQuantity(): Unit = {
val fruits = List((Apple,2), (Orange,4),
(Banana,5))
for ( (fruit, quantity) <- fruits) {
val product =
fruitVendor.sell(fruit(), quantity)
assertEquals(
product, fruit().price * quantity, 0.01 )
}
}
28
29. #3 Collection Of Case Classes
Xenonique
Sugaring of Supertype
scala> val list = List( Apple -> 1,
Orange -> 4, Banana -> 7 )
list: List[(scala.runtime.AbstractFunction0[
Product with Serializable with Fruit]
with Serializable, Int)]
= List((Apple,1), (Orange,4), (Banana,7))
// [R]AbstractFunction0.apply() => R
// fruit() returns the Fruit mix-in type
29
30. Xenonique
30
#2 Arquillian:
Prefer integration tests over unit tests.
You can write Arquillian tests with Scala
You cannot yet mix ScalaTest specifications
31. Writing Arquillian Tests with
Xenonique
Scala #1
// HERE WOULD BE THE IDEAL WORLD
import org.jboss.arquillian.junit.Arquillian
import org.junit.runner.RunWith
import org.scalatest.junit. JUnitSuite}
import org.scalatest.{FlatSpecLike, Matcher}
@RunWith(classOf[Arquillian],
classOf[JUnitRunner]) /* ;-) */
class HelloArquillianSpec extends JUnitSuite
with FlatSpecLike with Matchers {
}
31
32. Writing Arquillian Tests with
Xenonique
Scala #2
// The Reality of the Situation in 2014
@RunWith(classOf[Arquillian])
class HelloArquillianSpec extends JUnitSuite
with Matchers {
// You can’t use BDD like specificationsL
}
32
34. Writing Arquillian Tests with
Xenonique
Scala #4
// Add a companion object
@RunWith(classOf[Arquillian])
class HelloArquillianSpec extends JUnitSuite
with Matchers {
@Inject var hello: Hello = _
@Test
def shouldPrintAPoliteGreeting():Unit = {
val msg = hello.hello("JavaOne 2014")
// ;-) At least, we can use matchers!
(msg) should be ("Hello JavaOne 2014")
}
}
34
35. Xenonique
35
#3
Servlets
A
Java
Servlet
is
a
web
component
managed
container.
Java
Servlets
are
based
on
the
Java
technology,
they
generate
dynamic
content,
and
hence
the
container
that
manages
them
is
capable
of
delivering
dynamic
content
to
the
web
client.
37. Xenonique
37
#4 JAX-RS
Easy to write in Scala
Jackson Annotations, Json4S
We demand Json support with seamless Scala support
Jackson, especially, FasterXML is extremely helpful
https://github.com/FasterXML/jackson-annotations/
For Parsing JSON from text strings, then examine Json4S
https://github.com/json4s/json4s
38. Convert Posis to Json
// How do we convert this POSI to JSON
// to seamlessly and easily? ;-/
class Traveller(
@BeanProperty var givenName: String,
@BeanProperty var familyName: String,
@BeanProperty var dateOfBirth: Date ,
@BeanProperty var docNo: String )
Xenonique
38
39. Jackson Json Jaxb Annotations
// Look at the Jackson JAX-B project for
// inspiration ;-D
class Traveller2(
@BeanProperty @JsonProperty("givenName")
var givenName: String,
@BeanProperty @JsonProperty("familyName")
var familyName: String,
@BeanProperty @JsonProperty("dateOfBirth")
var dateOfBirth: Date,
@BeanProperty @JsonProperty("documentNo")
var docNo: String )
Xenonique
39
40. Restful Scala JAX-RS Service
Xenonique
Endpoint
@Path("/traveller")
class TravellerServiceEndpoint {
@GET()
@Produces(Array(MediaType.APPLICATION_JSON))
def retrieve(): Response = {
val cal = Calendar.getInstance()
cal.set(1986, Calendar.MAY, 21)
val dob = cal.getTime
val traveller = new Traveller2("Sam", "Smith",
dob, "1234567890")
Response.ok(traveller).build()
}
}
40
41. Jackson Json Mapping With
Xenonique
Provider
@Singleton
@Provider
@Consumes(Array(MediaType.APPLICATION_JSON,
"application/*+json", "text/json"))
@Produces(Array(MediaType.APPLICATION_JSON,
"application/*+json", "text/json"))
class JacksonScalaContextResolver extends
JacksonJaxbJsonProvider(JacksonScalaContextResolver.getObjectMapper,
JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS)
object JacksonScalaContextResolver {
def getObjectMapper: ObjectMapper = {
val mapper = new ObjectMapper with ScalaObjectMapper
mapper.registerModule(new DefaultScalaModule)
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
mapper.setSerializationInclusion(Include.NON_NULL)
mapper
}
}
41
42. Case Classes Instances and
Xenonique
Jackson Annotations
@JsonIgnoreProperties(Array("databaseId",
"computedDeliveryDateTime"))
case class Traveller3(
@BeanProperty @JsonProperty("givenName")
var givenName: String,
@BeanProperty @JsonProperty("familyName")
var familyName: String,
@BeanProperty @JsonProperty("dateOfBirth")
var dateOfBirth: Date ,
@BeanProperty @JsonProperty("documentNo")
var docNo: Option[String],
@BeanProperty
var computedDeliveryDateTime: Date = new Date())
42
43. Consuming of Json to Scala
Case Class Instance #1
@POST()
@Consumes(Array(MediaType.APPLICATION_JSON))
def store( traveller: Traveller3): Response = {
if ( traveller.getDocNo().isEmpty ) {
Response.status(
Response.Status.BAD_REQUEST)
.entity(ErrorMessage("E199",
Xenonique
"Missing document No"))
.build()
}
else {
Response.ok().build()
}
}
43
44. Xenonique
Case Class #2
case class ErrorMessage(
@JsonProperty("id") var id: String,
@JsonProperty("error") var text: String)
// Renders
// { "id": "E199",
// "error": "Missing document No"
// }
44
45. Xenonique
45
#5 JSF
Easy to write in Scala
Conversational, FlowScoped
RequestScoped, SessionScoped
All types of validation are supported including
BeanValidation just like Java
46. Conversational Scoped
Xenonique
Managed Bean
@Named("wizard")
@ConversationScoped
class RegisterDrivingLicense extends
Serializable {
@Inject
var conversation: Conversation = _;
@BeanProperty var title: String = _
@BeanProperty var firstName: String = _
@BeanProperty var lastName: String = _
/* ... */ }
46
48. Conversational States
def beginConversation(): Unit =
{
if (conversation.isTransient()) {
conversation.begin()
}
}
def endConversation(): Unit =
{
if (!conversation.isTransient()) {
conversation.end()
}
}
Xenonique
48
49. Finish Conversational Scopes
def submitDeclarationPage(): String = {
endConversation()
if ( !declaration ) {
// The declaration was not signed
cancelApplication()
}
else {
// Here the form is complete
"end?faces-redirect=true"
}
}
Xenonique
49
50. Xenonique
50
#6 JMS
JMS is straight forward to code with Scala
MDB is essentially an asynchronous EJB
Tricky part is publishing with JMS 2.0!
51. JMS with CDI Qualifiers #1
class JMSResourceProducer {
@Resource(name = "jms/OrderConnectionFactory")
val orderConnFactory: QueueConnectionFactory = _
@Produces @Order
@Resource(name = "jms/OrderQueue")
val orderQueue: Queue = _
@Produces @Order
def createOrderConnection(): QueueConnection =
orderConnectionFactory.createQueueConnection()
/* ... */
}
Xenonique
51
54. Xenonique
54
#Conclusion(1)
Source code is available now!
https://github.com/peterpilgrim/digital-scala-javaone-
2014
55. #Conclusion(2)
Scala and Java EE 7 integrate well from
an Object-Oriented point of view
Java EE 8 and Lambda API promise a functional
approach. Java EE 7 annotations work in Scala.
The ability of Jackson annotations and a singleton provider to
seamlessly handle Scala’s case classes is a wonderful addition.
Arquillian almost works completely with ScalaTest.
Xenonique
55
56. Xenonique
56
#Conclusion(3)
WAR files require the runtime Scala
Library
Decent server configuration using Chef and Puppet
can obviate the bundling of the runtime
Scala allows developers to avoid Java boilerplate
Library writers should prefer to explicitly declare the
return types of functions and methods
58. #101 Bonus Information on Scala
A Powerful weapon that requires great responsibility
Great developers can create apps
AM #1: “Interactions and individuals over processes and tools”
Xenonique
58
59. How to avoid null pointers in
Xenonique
Scala Programming?
val greeting1: Option[String] =
Some("AOTB14")
val greeting2: Option[String] = None
59
60. Xenonique
Pattern Matching
def checker(p : Option[String]): String = {
p match {
case Some(v) => v
case _ => "Unexpected"
}
}
checker(greeting1) // "Hello AOTB14"
checker(greeting2) // "Unspecified"
60
61. Scala’s generic immutable list
Xenonique
collection type
val list: List[Int] = List(1,2,3,4)
list.foreach { x => println(x) }
// 1,2,3,4
61
62. Scala’s option behaves like
Xenonique
collection type #2
greeting1.foreach { x =>
println(s"Work: ${x}" ) }
// Work: Hello AOTB14
greeting2.foreach { x =>
println(s"Work: ${x}" ) }
// *** nothing happens ***
62
63. Read, Evaluate, Print, Loop
• Scala, Clojure, Groovy, Kotlin, Ceylon, Fantom
All have a interpretative mode
• Java JDK does not (yet) have an official REPL
(However try out javarepl.com online)
• Fingers crossed Project Kulla in JDK 9
http://blog.gmane.org/gmane.comp.java.openjdk.general
Xenonique
63
64. List of Creative Commons (2.0)
photography attributions
https://flic.kr/p/ayqvZp
https://www.flickr.com/photos/throughpaintedeyes/
Ryan Seyeau Follow
1000 Faces of Canada # 0084 - Zombie Walk - Explore!
Shot during the annual Zombie Walk in Ottawa.
https://flic.kr/p/Pp93n
https://www.flickr.com/photos/spacesuitcatalyst/
William A. Clark Follow
Measurement
Measure twice, cut once.
https://flic.kr/p/81dXuT
https://www.flickr.com/photos/froboy/
Avi Schwab Follow
Equipment used for measuring planes of crystals
https://flic.kr/p/2QHt7Q
https://www.flickr.com/photos/rosefirerising/
rosefirerising Follow
Pierre Curie, Piezo-Electroscope
Xenonique
64
66. List of Creative Commons (2.0)
photography attributions
https://www.flickr.com/photos/15216811@N06/
https://flic.kr/p/baULpM
N i c o l a Follow
Tree - IMG_1242
https://flic.kr/p/dwCQ7t
https://www.flickr.com/photos/90585146@N08/
marsmetn tallahassee Follow
IDA .. Integro-Differential Analyzer (Sept., 1952) ...item 2.. Richard Dreyfuss: Technology Has 'Killed Time' -- "In geopolitics, the removal of time is fatal." -- "And
you will give up, the protection of Republican Democracy." (July 19 2010) ...
https://flic.kr/p/6ZDbiZ
https://www.flickr.com/photos/ingmar/
Ingmar Zahorsky Follow
Traffic Jam
Accidents are common on the narrow streets going through the mountains of Nepal. When such an accident occurs, traffic is often halted for up to 3-4 hours.
https://flic.kr/p/opvVsg
https://www.flickr.com/photos/gregbeatty/
Greg Beatty Follow
Three Pillars
Nikon D800 16-35MM F4.0
https://flic.kr/p/FAskC
https://www.flickr.com/photos/mari1008/
mari_1008 Follow
traffic jam -B
Date: April,2th
Address: Jiangshu Rd,Shanghai,China.
Around 8:30 AM today, A little accident on YuYuan Rd and JiangSu Rd caused traffic jam.
Xenonique
66
67. List of Creative Commons (2.0)
photography attributions
https://flic.kr/p/bpss6D
https://www.flickr.com/photos/76029035@N02/
Victor1558 Follow
Creative_Photoshop_HD_Wallpapers_laba.ws
https://flic.kr/p/mLxu3m
https://www.flickr.com/photos/astrangelyisolatedplace/
astrangelyisolatedplace Follow
Office test #1. Setup fully functional. A rare 1200 no longer in production. Test run
soundtracked by the only #vinyl in the office; The Sesame Street Soundtrack - a
surprise present by @idinesh #technics #turntable #1200 #ocdv1
via Instagram ift.tt/1hpeUEU
https://flic.kr/p/gLPhEk
https://www.flickr.com/photos/stevecorey/
Steve Corey Follow
Treasure Hunt, a short story (5 images)
Xenonique
67
68. List of Creative Commons (2.0)
photography attributions
https://flic.kr/p/4JcerK
https://www.flickr.com/photos/16949884@N00/
Bömmel Follow
Ice Crystal
Ice is nice
https://flic.kr/p/dSsXiZ
https://www.flickr.com/photos/jeremyhall/
Jeremy Hall Follow
Called to Serve (suit and tie)
https://flic.kr/p/3enERy
https://www.flickr.com/photos/paolocampioni/
Paolo Campioni Follow
scala
Scendo (stair case spiral)
Xenonique
68
69. List of Creative Commons (2.0)
photography attributions
https://flic.kr/p/m62gmK
https://www.flickr.com/photos/lata/
-p Follow
Abstraction I.
From my platycerium. (Guide: Voronoi diagram)
https://flic.kr/p/6WSFR4
https://www.flickr.com/photos/62337512@N00/
anthony kelly Follow
big ben
big ben and underground sign
https://flic.kr/p/w7qef
https://www.flickr.com/photos/cobalt/
cobalt123 Follow
All We are Saying... (Thought for a New Year)
Peace Pasta from Annie's, with peas, of course.
Give Peace A Chance
Xenonique
69