Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

JavaFX and Scala in the Cloud

2,166 views

Published on

Talk about an end-to-end application leveraging JavaFX, Scala, Java DB, and cloud technologies. Given at the JAX conference in San Francisco.

Published in: Technology
  • I JUST completed the dressing table that my wife always wanted. To be honest it took 8 days instead of 3 but keep in mind that I'm not a great carpenter. i could honestly kiss you right now. 》》》 https://t.cn/A62Ye5eM
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

JavaFX and Scala in the Cloud

  1. 1. Stephen Chin | Oracle @steveonjava Andrew Phillips | jclouds @jcloudsJavaFX and Scala in the Cloud
  2. 2. +
  3. 3. HeavenPhoto by Alberto Fernandez Fernandez
  4. 4. When This Architecture Makes Sense• Data is mostly read-only – Transactional updates still require a server (but can be simpler/smaller)• Users view of data is small to medium – Initial DB download of < 10K records is reasonable – Not total DB size, but subset of data visible to user Conference App has 3K large records and compresses to only 330KB DB size
  5. 5. Cloud Data Advantages• Offline Operation – Once DB is cached, application works 100% offline• Responsive Client Performance – All DB queries are fast and local• High Availability & Scalability – 99.99% Availability – Easily scales up to 100s of requests per second But, with proper hashes scales up to millions of requests per second!
  6. 6. Cloud Data Advantages (continued)• Insanely cheap server costs! Number of Users Monthly Cost* 3,000 Free (S3 free tier) 10,000 $0.28 100,000 $3.84 1,000,000 $39.48* For 330KB of hosted data in Amazon S3
  7. 7. Cloud Data Advantages (continued)• Insanely cheap server costs! Number of Users Monthly Cost* 3,000 Free (S3 free tier) 10,000 $0.28 100,000 $3.84 1,000,000 $39.48* For 330KB of hosted data in Amazon S3
  8. 8. Cloud Data Advantages (continued)• Insanely cheap server costs! Number of Users Monthly Cost* 3,000 Free (S3 free tier) 10,000 $0.28 100,000 $3.84 1,000,000 $39.48* For 330KB of hosted data in Amazon S3
  9. 9. Cloud Data Advantages (continued)• Insanely cheap server costs! Number of Users Monthly Cost* 3,000 Free (S3 free tier) 10,000 $0.28 100,000 $3.84 1,000,000 $39.48* For 330KB of hosted data in Amazon S3
  10. 10. UI
  11. 11. JavaFX 2.0 PlatformImmersive Application ExperienceLeverage your Java skills with modernJavaFX APIs• Cross-platform Animation, Video, Charting• Integrate Java, JavaScript, and HTML5 in the same application• New graphics stack takes advantage of hardware acceleration for 2D and 3D applications• Use your favorite IDE: NetBeans, Eclipse, IntelliJ, etc.
  12. 12. What is Scala 2001 2006 • Scala Started • Scala v2.0 2003/2004 2011 • Scala v1.0 • Scala 2.9.2 (latest)• Started in 2001 by Martin Odersky• Compiles to Java bytecodes• Pure object-oriented language• Also a functional programming language
  13. 13. Why Scala?• Shares many language features with JavaFX Script that make GUI programming easier: – Static Type Checking – Catch your errors at compile time – Closures – Wrap behavior and pass it by reference – Declarative – Express the UI by describing what it should look like
  14. 14. Why Scala? (continued)• Scala also supports Type Safe DSLs! – Implicit Conversions – type safe class extension – Operator Overloading – with standard precedence rules – DelayedInit / @specialized – advanced language features
  15. 15. Java vs. Scala DSLpublic class JavaFXEEDemo extends Application { object ConferenceUI extends JFXApp { val model = ConferenceModel public static void main(String[] args) { stage = new Stage { launch(JavaFXEEDemo.class, args); width = 625 } height = 700 scene = new Scene(new StackPane()) { private SpeakerModel speakerModel = getInstance(); fill = "#fcfcfc" private TextField filter; children = Seq( private ChoiceBox<String> items; new VBox { children = Seq( @Override new ImageView { public void start(Stage primaryStage) { image = new Image(getClass().getResourceAsStream("JavaOneLogo.png")) primaryStage.setTitle("JavaOne Speaker List"); }, speakerModel.load(); new Rectangle { EventHandler<ActionEvent> filterAction = new EventHandler<ActionEvent>() { width = 625 public void handle(ActionEvent event) { height = 50 String field = items.selectionModelProperty().getValue().getSelectedItem(); fill = new LinearGradient( String text = filter.getText(); endX = 0, speakerModel.filter(field, text); stops = Stops(WHITE, "#d0cbc8") } ) }; } primaryStage.setScene(SceneBuilder.create() ) .width(625) }, .height(700) new VBox { .fill(Color.web("#fcfcfc")) padding = Insets(100, 20, 20, 20) .root(StackPaneBuilder.create().children( spacing = 30 // Background image and gradient children = Seq( VBoxBuilder.create().children( new HBox { ImageViewBuilder.create() val filter = new TextField(); 83 Lines 88 Lines .image(new Image(getClass().getResourceAsStream("JavaOneLogo.png"))).build(), val items = new ChoiceBox[ruco.TextField[Speaker]]() { RectangleBuilder.create().width(625).height(50).fill(LinearGradientBuilder.create().endX(0).stops( items = ObservableBuffer(Speaker.firstName, Speaker.lastName, Speaker.jobTitle, Speaker.company) StopBuilder.create().color(Color.WHITE).offset(0).build(), converter = StringConverter.toStringConverter({s:ruco.TextField[Speaker] => s.name}) StopBuilder.create().color(Color.web("#d0cbc8")).offset(1).build() } ).build()).build() alignment = Pos.BASELINE_LEFT ).build(), spacing = 15 // Foreground controls children = Seq( VBoxBuilder.create() items, 2622 Characters 1452 Characters .padding(new Insets(100, 20, 20, 20)) filter, .spacing(30) new Button("Filter") { .children(HBoxBuilder.create() onAction = { e:ActionEvent => .alignment(Pos.BASELINE_LEFT) model.filter(items.selectionModel().getSelectedItem(), filter.text()) .spacing(15) } .children( }, items = new ChoiceBox<String>( new Button("Clear") { FXCollections.observableArrayList(FIRST_NAME, LAST_NAME, JOB_TITLE, COMPANY) onAction = { e:ActionEvent => ), filter.text = "" filter = TextFieldBuilder.create().prefColumnCount(20).onAction(filterAction).build(), model.clear() ButtonBuilder.create().text("Filter").onAction(filterAction).build(), } ButtonBuilder.create().text("Clear").onAction(new EventHandler<ActionEvent>() { }, public void handle(ActionEvent event) { new Button("Reload") { speakerModel.clearFilter(); onAction = { e:ActionEvent => } filter.text = "" }).build(), model.load() ButtonBuilder.create().text("Reload").onAction(new EventHandler<ActionEvent>() { } public void handle(ActionEvent event) { } speakerModel.load(); ) } items.selectionModel().selectFirst() }).build() }, ).build(), new TableView[Speaker](model.filteredSpeakers) { TableViewBuilder.<Speaker>create().items(speakerModel.getFilteredData()).prefHeight(1000).columns( columns = Seq( TableColumnBuilder.<Speaker, String>create() new TableColumn[Speaker, String] { .text(FIRST_NAME) text = "First Name" .cellValueFactory(new PropertyValueFactory<Speaker, String>(FIRST_NAME_FIELD)).build(), converter = {_.firstName()} TableColumnBuilder.<Speaker, String>create() }, .text(LAST_NAME) new TableColumn[Speaker, String] { .cellValueFactory(new PropertyValueFactory<Speaker, String>(LAST_NAME_FIELD)).build(), text = "Last Name" TableColumnBuilder.<Speaker, String>create() converter = {_.lastName()} .text(JOB_TITLE) }, .prefWidth(200) new TableColumn[Speaker, String] { .cellValueFactory(new PropertyValueFactory<Speaker, String>(JOB_TITLE_FIELD)).build(), text = "Job Title" TableColumnBuilder.<Speaker, String>create() converter = {_.jobTitle()} .text(COMPANY) prefWidth = 200 .prefWidth(212) }, .cellValueFactory(new PropertyValueFactory<Speaker, String>(COMPANY_FIELD)).build() new TableColumn[Speaker, String] { ).build() text = "Company" ).build() converter = {_.company()} ).build() prefWidth = 212 ).build() } ); ) items.getSelectionModel().selectFirst(); prefHeight = 1000 primaryStage.show(); } } )} } ) } onCloseRequest = {_:Any => Platform.exit} } }
  16. 16. ScalaFX Applicationobject ConferenceUI extends JFXApp { val model = ConferenceModel stage = new Stage { width = 625 height = 700 scene = new Scene(new StackPane()) { fill = "#fcfcfc" children = Seq( // create background // create foreground ) } }}
  17. 17. Loading Imagesnew ImageView { image = new Image( getClass().getResourceAsStream( "JavaOneLogo.png" ) )}
  18. 18. Creating Buttonsnew Button("Filter") { onAction = { e:ActionEvent => model.filter(items.selectionModel().getSelectedItem(), filter.text()) }}new Button("Clear") { onAction = { e:ActionEvent => filter.text = "" model.clear() }}
  19. 19. ScalaFX Table Constructionnew TableView[Speaker](model.filteredSpeakers) { columns = Seq( new TableColumn[Speaker, String] { text = "First Name" converter = {_.firstName()} }, new TableColumn[Speaker, String] { text = "Last Name" converter = {_.lastName()} } … ) prefHeight = 1000}
  20. 20. DATABASEBy RRZEicons (Own work) [CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons
  21. 21. Java DB / Apache Derby• Embedded Database• Small Footprint (2.7MB)• Standards Based (Java, JDBC, SQL)• Extremely Easy to Configure – With JDBC 4 / SE 6, just drop in the jar!
  22. 22. Circumflex ORM• Scala-based ORM (Object-Relational Mapping)• SQL-based Query Syntax• DSL for Domain Object Definition• Lazy and Eager Fetch Strategies
  23. 23. Embedded DB Configorm.connection.driver= org.apache.derby.jdbc.EmbeddedDriverorm.connection.url=jdbc:derby:conferenceDataorm.connection.username=user1orm.connection.password=user1orm.defaultSchema=APP
  24. 24. Speaker Domain Objectclass Speaker extends Record[String, Speaker] { val id = "id".VARCHAR(255).NOT_NULL val company = "company".VARCHAR(255) val firstName = "firstName".VARCHAR(255) val jobTitle = "jobTitle".VARCHAR(255) val lastName = "lastName".VARCHAR(255) def PRIMARY_KEY = id def relation = Speaker}object Speaker extends Speaker with Table[String,Speaker]
  25. 25. Query the Databasedef clear() { val speakers = Speaker.criteria.list() filteredSpeakers.setAll(speakers)}def filter(field: TextField[Speaker], filterString: String) { val speakers = Speaker.criteria.add( field LIKE "%" + filterString + "%").list() filteredSpeakers.setAll(speakers)}
  26. 26. CLOUD
  27. 27. An OSSM Persistence Store • On-demand • Self-service • Scalable • Measurable • ™ Dave Nielsen, CloudCamp@jclouds
  28. 28. open sourcesimple: feels like java (and clojure)unit testabletested across multiple cloudsvibrant community
  29. 29. Portable APIs BlobStore LoadBalancer What do you Compute want?Provider-Specific HooksEmbeddable github jclouds-examples
  30. 30. Anatomy of a BlobStore Project1.Create context2.Get BlobStore API3.Do stuff4.Close context@jclouds
  31. 31. jclouds modularityAPIs are softwarefocused Providers areoffering focusedAPI + location + defaults= Provider
  32. 32. Cloud Access in Scalaval context = ContextBuilder.newBuilder("aws-s3") .credentials("identity", "secret") .buildView(classOf[BlobStoreContext])def loadFromCloud(container:String, resource:String):InputStream = { val blobStore = context.getBlobStore val blob = blobStore.getBlob(container, resource) blob.getPayload.getInput}def close() { context.close()}
  33. 33. Why jclouds?• Data Portability o APIs are not as compatible as they might appear• Code Portability o Currently 33 cloud providers• Enterprise-grade o Move petabytes of data• Parallel operations without threading concerns o Outperforms many native SDKs o GAE compatible o Many tuning options@jclouds
  34. 34. Why jclouds?• OSGi compatible• Clojure binding• “Invented” many standard SDK features o e.g. sync/async APIs• Tested! o “official” TCK for a number of cloud providers o also supports offline/local testing@jclouds
  35. 35. Why jclouds?• Location metadata o Don’t get locked in to a provider’s deployment policy• Does the hard work so you don’t have to o Multi-part in native SDKs vs. .multipart() in jclouds• Strong & active community o ~65 contributors, commercial support@jclouds
  36. 36. Conference App Demo
  37. 37. Stephen Chin <stephen.chin@oracle.com> | Oracle @steveonjavaAndrew Phillips <andrew@jclouds.org> | jclouds @jclouds Thank You!

×