Date post: | 15-Jan-2015 |
Category: |
Education |
Upload: | peter-pilgrim |
View: | 1,064 times |
Download: | 2 times |
Scala and Java EE 7 Development Experiences
Peter A. Pilgrim Independent Contractor, Java Champion
Biography ■ Completed Java Sybase
course in 1998 ■ Founded JAVAWUG
2004-2010 ■ Independent Contractor ■ Blue-chip business:
Digitas Lbi, Barclays Retail, Transform
September 2013
Java EE 7 Developer Handbook
• Overview of Scala • Java EE 7 architecture and design • Using Gradle as a build tool • How to create beans in Scala with dependency injection • JAX-RS endpoints • Servlet Endpoints • JMS Messaging • Scala adoption advice and hints for sustainable team
development
“The right architecture to the right application. Not all of us work for Facebook or Twitter. If you look at their "web site" the navigation is quite simple… For them, statelessness and NoSQL is mandatory. But when you work on a "web application” then you deal with complex flow management. Their problem is elsewhere : fewer users but complex long time running transactional flows. Stateful architecture are mandatory.
Antonio Gonclaves Why Java EE Lost and Spring Won
http://java.dzone.com/articles/why-java-ee-lost-and-spring
Scalable Language
12/05/2014 XeNoNiQUe.co.uk (c) 2011 7
Still has a very bright future Purely Object-Oriented Statically-typed
Functional
JVM Language
Typing Derived from “Pascal” Tree of Computer Language
<variableName> [: [ <Type> ]
personName: String taxRate: Float
density: Double found: False
persion: Person
May 12, 2014 Xenonique ©2013 8
Variables and Values Assignment less programming Prefer val over var var x = 10.0; x = 10 + x val y = 10.0 val z: Float = x var t: Int = 42; t = t * 2
9
Scala Class class Person ( val firstName: String val lastName: String, val height: Float, val age: Int ) { // Write your definition here
} May 12, 2014 Xenonique ©2013 10
Instances of Scala Classes
val p1 = new Person( "Billy", "Mitchell", 5.10F, 42 ) val p2 = new Person( "Kat", "Moon", 5.8F, 39 ) May 12, 2014 Xenonique ©2013 11
Companion Objects object Person { private records = List[Person]() def apply(fn: String, ln: String, h: Float, a: Int): Person = { val p = new Person(fn, ln, h, a ); records = p :: records.reverse // O(1) return p } def recordCount() = records.size } May 12, 2014 Xenonique ©2013 12
Case Classes
class Transmission( driveTrain: String )
May 12, 2014 Xenonique ©2013 13
Scala Functions
val isEven: (Int => Boolean) = (k: Int) => k % 2 == 0
• Functions are values, values are object • Ergo, functions are objects in Scala
May 12, 2014 Xenonique ©2013 14
Scala Code def uniqueSorted[Symbol]( p: List[Symbol] ): List[Symbol] = { val myOrdering = Ordering.fromLessThan[Symbol]( _.toString < _.toString ) var acc = SortedSet.empty(myOrdering) def compress0( q: List[Symbol] ): Unit = { q match { case Nil => Nil case x :: xs => { acc += x ; compress0(xs) } } } compress0( p ) acc.toList }
May 12, 2014 Xenonique ©2013 15
Functions are First Class
• In Scala, functions are first class citizens • Functions can return functions
May 12, 2014 Xenonique ©2013 16
SBT
• SBT is the de-facto build tool • Works with Maven • Incremental Compilation +1 • DSL written in Scala +1 • Plugins Available +1 • Complex to Understand -1 May 12, 2014 Xenonique ©2013 17
Gradle
• Gradle is written in Groovy • Gradle is a DSL too +1 • Easier to Grok +1 • Since v1.4 Gradle support incremental
compilation through Zinc • Not the de-facto standard -1
May 12, 2014 Xenonique ©2013 18
ENTERPRISE DEVELOPMENT
Modern Practice
Java EE 7 Framework Updates
Interface Boundary Endpoints
JAX RS 2.0
JMS 2.0
Bean Validation 1.1
Management and Storage
EJB 3.2
CDI 1.1
JPA 2.1
Web and HTML Service Endpoints
Servlet 3.1
WebSocket 1.0
JSF 2.2
JSON 1.0
CDI and Scala trait Processor {
def process( payload: DataValue ) : Unit /* ... */
} @ApplicationScoped class DatastarProcessor extends Processor { @Inject var dataStore: DataStore = _ override def process( payload: DataValue): Unit = { // Do something here } }
What about Java SE 8?
public interface PaymentIssuer { public void allocate( int id );
}
What about Java SE 8? @ApplicationScoped public class CreditCardTicketTracker() { @Inject PaymentIssuer issuer; public void doWork( List<Ticket> ticketBatch ) { }
}
What about Java SE 8? public void doWork( List<Ticket> ticketBatch ) { DateTime dt = new DateTime().minusDays(2); ticketBatch.stream() .filter( t -> t.isAvailable() && t -> t.paymentType == PaymentType.CreditCard && t.concertDate.before( dt ) ) .map( t -> p.getAllocationId() ) .forEach( allocationId -> issuer.allocate(allocationId)); }
Write Annotations as Java // In the Java source tree (src/main/java) import javax.inject.Qualifier; import javax.interceptor.InterceptorBinding; import java.lang.annotation.*; import static java.lang.annotation.ElementType.*; @Qualifier @InterceptorBinding @Target({METHOD, TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface PermanentStorage { } public @interface CachedStorage { } public @interface TransientStorage { }
Stock CDI Advice
• CDI does works very well with Scala POJOs • CDI cannot instantiate companion objects! • CDI beans must have a default constructor • CDI does not understand case classes (but
see later …)
CDI Setter Injection
• Take advantage of Scala’s @BeanProperty annotation
@BeanProperty var liveStatus:String = “Default” @Inject def setLiveStatus(a:String):Unit=???
CDI Scopes // Prefer CDI scopes if you use JSF in Java EE import javax.enterprise.context.RequestScoped import javax.enterprise.context.SessionScoped import javax.enterprise.context.ApplicationScoped // Instead of import javax.faces.bean.RequestScoped import javax.faces.bean.SessionScoped import javax.faces.bean.ApplicationScoped
Last Advice on CDI Proxies
• Scala POJOs need a lifecycle scope • Always create default no args constructor • Cannot be final or have final members – (Interaction between Java and Scala)
JSF Managed Beans import javax.enterprise.context.RequestScoped import javax.inject.Named @Named @RequestScoped class BasicFlow { def serveResponse() = "endState.xml" }
JSF XHTML Facelet View <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html ...> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:f="http://xmlns.jcp.org/jsf/core”> <h:head> ... </h:head> <h:body> ... </h:body> </html>
JSF XHTML Facelet View <h:body> ... <h:form> <h:commandButton action="#{basicFlow.serveResponse}” value="Invoke Action" /> </h:form> </h:body>
Demo CDI and Scala
Produces JMS Connections in Scala class JMSResourceProducer { @Resource(name = "jms/OrderConnectionFactory") private orderConnectionFactory: QueueConnectionFactory = _ @Produces @Order @Resource(name = "jms/OrderQueue") private orderQueue: Queue = _ @Produces @Order def createOrderConnection(): QueueConnection = orderConnectionFactory.createQueueConnection() @Produces @Order def createOrderSession(@Order conn:QueueConnection): QueueSession = conn.createQueueSession(true, Session.AUTO_ACKNOWLEDGE) }
Scala and JAX-RS
• JAX-RS 2 annotations work with Scala POJOS out of the box
• Annotate on public methods • @GET, @POST, @PUT, @DELETE • @Produces, @Consumes
Use Qualifiers in Scala // In the Scala source tree (src/main/scala) @ApplicationScoped @PermanentStorage class DatastarProcessor extends Processor { @Inject var dataStore: DataStore = _ override def process( payload: DataValue): Unit = { /* ... */ } }
JAX-RS @Path("/alldata") class AllDataServiceEndpoint { @Inject var fastService: FastService = _ @Inject var predictorService: PredictorService = _ @Context var request: HttpServletRequest = _ @Path("/item") @GET @Produces(Array(APPLICATION_JSON)) def listServices = ??? }
JAX-RS def listServices = { val listServices = (fastService.configuredAllServices ++
predictorService.configuredAllServices) map { makeElement( _ ) } Response.ok(listServices, MediaType.APPLICATION_JSON).build } }
Jackson, Scala & JSON Support
• JAX-RS works well with Scala POJOs • JAX-RS and Java EE 7 provides JSON
providers only for Java POJOs • Use Jackson JSON Providers for seamless
support of case classes
Jackson Scala JAX-RS @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)
Jackson Scala JAX-RS 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 } }
Open Source Integration Testing Peter Muir, David Blewin and Aslak Knutsen and from Red Hat JBoss.
Demo Alternative
Demo Servlets, CDI & EJB
Java EE 7 Demo
EXECUTIVE SUMMARY
Digital by Default with Java
“If you're frustrated that you're not getting picked, one plan is to up your game, to hustle harder, ... But in the era of picking yourself, it seems to me that you're better off finding a path that doesn't require you get picked in order to succeed.”
Seth Godin, Getting Picked (‘need to’ versus ‘want to’)
Run It Yourself
• https://github.com/peterpilgrim/javacro • Download the source code, build and run • Feedback, welcomed!
Thank You!
The book:
http://www.packtpub.com/java-ee-7-developer-handbook/book
Blog:
http://xenonique.co.uk/blog/ Twitter:
@peter_pilgrim
Creative Commons Attributions http://www.flickr.com/photos/holstphoto/3371060720/ Photo of "Chip Pattern" by Ryan Holst, March, 2009 http://www.flickr.com/photos/scarygami/5489773527/lightbox/ Photo of "Pattern" by Scarygami http://www.flickr.com/photos/christianhaugen/3486381680/sizes/l/in/photostream/ Photo of "Patterns in the Sand" by Christian Haugen http://www.flickr.com/photos/krunkwerke/3840127296/ Photo of a series of punch cards which are strung together, to control the pattern woven by the Jacquard loom. John R. Southern
Creative Commons Attributions http://www.flickr.com/photos/josefstuefer/43867840/ Proof of Pattern messh "untitled" in tan by Josef Stuefer http://www.flickr.com/photos/josefstuefer/43972554/ Proof of Pattern mesh "untitled" in blue by Josef Stuefer http://www.flickr.com/photos/scott1723/6290151038/ Alter photo of "Tug of War 3" by Scott Anderson