Life outside WO

702
-1

Published on

Published in: Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
702
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
13
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Life outside WO

  1. 1. Life outside WOby Andrus Adamchik, ObjectStyle LLC
  2. 2. • 1998 - 2003 :WebObjects programmer• 1998 - present : Java programmer• 2001 - present : working on Cayenne• Apache member, open source developer• Owner of ObjectStyle LLCAbout me
  3. 3. Life outside WO
  4. 4. Why Bother?• WO is no longer a product sold by Apple• There are lots of good technologies out there• True open source / freedom• Effort put in Wonder will have a much higher ROI
  5. 5. What alternative stack wouldsatisfy a WO developer?
  6. 6. WO Stack
  7. 7. Generic DI-CentricStack
  8. 8. Our Stack
  9. 9. Why not JEE?
  10. 10. JEE provides us container,web app structure and coreHTTP APIs:Servlets (JSR-315)JAX-RS - Jersey (aka JSR-311, aka REST)
  11. 11. Stack Parts• Dependency Injection• HTML Framework• REST Framework• Persistence
  12. 12. Dependency Injection
  13. 13. Dependency Injection• Frees dependency users from concerns over dependencyinitialization, scoping and lookup• Loose coupling (aka “program to interfaces” style)• Services as facades to complex third-party frameworks• Makes services testable
  14. 14. DI Alternatives - Static Methodspublic class MyPage {void setupRender() {// no DI, use a static utilityString appName = PropertyUtils.getProperty(“app.name”);...}}public class PropertyUtils {private static ObjectContext context;// who and when invokes this?public static void init(ObjectContext context) {PropertyUtils.context = context;}public static String getProperty(String key) {return System.getProperty(key) != null ? System.getProperty(key) : getFromDB(key);}private static String getFromDB(String key) { .. }}
  15. 15. DI Alternatives - Self-initializing Singletonspublic class MyPage {void setupRender() {// no DI, use a static singletonString appName = PropertyUtils.singleton().getProperty(“app.name”);...}}public class PropertyUtils {private static PropertyUtils singleton;public static PropertyUtils singleton() {// is this thread-safe? is Cayenne runtime ready by now?if(singleton == null) {ObjectContext context = CayenneUtils.getContext();singleton = new PropertyUtils()}return singleton;}private ObjectContext context;public PropertyUtils(ObjectContext context) {this.context = context;}public static String getProperty(String key) {return System.getProperty(key) != null ? System.getProperty(key) : getFromDB(key);}private static String getFromDB(String key) { .. }...}
  16. 16. Dependency Injectionpublic class MyPage {@Injectprivate PropertyService propertyService;void setupRender() {String appName = propertyService.getString(“app.name”);}}public class PropertyService {private ObjectContext context;public PropertyService(@Inject ObjectContext context) {this.context = context;}public String getProperty(String key) {return System.getProperty(key) != null ? System.getProperty(key) : getFromDB(key);}private static String getFromDB(String key) { .. }}
  17. 17. Dependency Injection• Frees dependency users from concerns over dependencyinitialization, scoping and lookup• Loose coupling (aka “program to interfaces” style)• Services as facades to complex third-party frameworks• Makes services testable
  18. 18. Dependency Injectionpublic class MyPage {@Injectprivate IPropertyService propertyService;void setupRender() {String appName = propertyService.getString(“app.name”);}}public interface IPropertyService {public String getProperty(String key);}public class DBPropertyService implements PropertyService {// copy our old PropertyService code here...}public class FilePropertyService implements PropertyService {public String getProperty(String key) {return System.getProperty(key) != null ? System.getProperty(key) : getFromFile(key);}private static String getFromFile(String key) { .. }}
  19. 19. Dependency Injection• Frees dependency users from concerns over dependencyinitialization, scoping and lookup• Loose coupling (aka “program to interfaces” style)• Services as facades to complex third-party frameworks• Makes services testable
  20. 20. Dependency Injection• Frees dependency users from concerns over dependencyinitialization, scoping and lookup• Loose coupling (aka “program to interfaces” style)• Services as facades to complex third-party frameworks• Makes services testable
  21. 21. DI Framework Choices• Spring• Google Guice• Apache Tapestry• CDI• (Cayenne DI)
  22. 22. DI Framework Choices• All support annotations• All are very capable• Choice is driven by front-end technology (Tapestry for us)
  23. 23. Tapestry DI• Services assembly in the code (no XML)• Out of the box injection into T5 pages and components• Easy integration with Jersey (same services can be injected intoREST resources)• Supports HttpServletRequest/Response injection• Supports multiple DI modules
  24. 24. HTML Framework
  25. 25. HTML Framework - Choices• JSF• Tapestry (aka “T5” for “Tapestry v.5”)• Spring MVC• Wicket, Seam, Click, Grails, many others...
  26. 26. Why Tapestry?• The most natural choice for a WO developer:• Page is made of infinitely nestable components• Components get their values via bindings from parent• Something like WOComponentContent used to be nearlyimpossible with competition
  27. 27. Beyond WO Similarities• No common superclass of pages and components• “Static” component hierarchy (WOSwitchComponent-likefunctionality works differently)• Injection into pages and components• No separation between pages and direct actions (pages canserve DA-like responses)
  28. 28. Beyond WO Similarities - 2• AJAX support / zones (some controversy here)• Template inheritance• Different and fairly complicated page rendering lifecycle• Probably more scaleable (better state management facilities)• Lots of other good stuff and extension points (mixins, blocks,etc., etc.)
  29. 29. Tapestry - a simple dynamic pageIndex.java:package com.objectstyle.demo.html.pages;import org.apache.tapestry5.annotations.Persist;public class Index { @Persist private int clickCounter; public String getText() { return "Hi! Clicked " + clickCounter + " time(s)"; } public void onActionFromClick() { clickCounter++; }}Index.tml:<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"><body><h1>${text}</h1><p><t:actionlink t:id="click">click me</t:actionlink></p></body></html>
  30. 30. Tapestry - a simple page with a custom componentPageWrapper.tml:<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"> <head><title>${title}</title></head> <body><t:body /></body></html>PageWrapper.java:package com.objectstyle.demo.html.components;import org.apache.tapestry5.annotations.Parameter;import org.apache.tapestry5.annotations.Property;public class PageWrapper { @Parameter @Property private String title;}Index.tml:<html t:type="pagewrapper" title="prop:text" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"><h1>${text}</h1><p><t:actionlink t:id="click">click me</t:actionlink></p></html>
  31. 31. REST Framework
  32. 32. REST Framework Has DifferentRequirements from HTML One• Easy mapping of HTTP request parts to Java code• HTTP method• URL (path, parameters)• Session state management is non-essential• Responses are data structures without presentation elements
  33. 33. REST Framework Has DifferentRequirements from HTML OnePossible to build on top of Tapestry/WO/etc.,but is it a good idea?
  34. 34. REST Framework - Choices• Fortunately (?) fewer choices than with HTML frameworks• Most based on JAX-RS spec (JSR-311):• Jersey, Resteasy, Apache CXF• No prominent higher-level frameworks yet (I am building aclosed source one at the moment)
  35. 35. JAX-RS (JSR-311)My favorite JEE spec :)
  36. 36. JAX-RS (JSR-311)• Exposes POJO classes as web “resources”• Annotation-based• Usually deployed as a servlet• (Like servlet spec) low-level enough to be close to HTTPprotocol• (Unlike servlet spec) very usable on its own to support manyREST development scenarios without higher abstractions
  37. 37. JAX-RS - a simple resourceHelloResource.java:@Path("rest")public class HelloResource { @GET @Produces(MediaType.APPLICATION_JSON) public Object sayHi() { return new Model("Hi!"); }}Model.java:class Model { private String say; Model(String say) { this.say = say; } public String getSay() { return say; }}
  38. 38. JAX-RS provider - Jersey• A reference implementation of JSR-311• Support for REST client• A unit test framework• Trivial to integrate resource injection with Tapestry DI• Happily coexists with T5 pages in the same app
  39. 39. Persistence Framework ... we’lldiscuss it later
  40. 40. Migration from WO
  41. 41. What does it take?• Keep the WO philosophy, but not the WO code• Write the code from scratch• Should be easy for new projects• No 1-click migration for existing projects• Start by using WO frontend with Cayenne (?)• CayenneModeler / ERCayenne will import most EOModels
  42. 42. No Direct Replacement for:• DirectToWeb (likely possible to implement on top of Tapestry)• DirectToJavaClient (however 3-tier ORM is available, provided byCayenne ROP)
  43. 43. WOCommunity Can:• Create WO-to-T5 template migration tools• Port Wonder to Cayenne/T5• Port ERRest to Jersey/Cayenne• ...
  44. 44. We’ve gone from Objective C to Javaonce, so we can do it again...
  45. 45. Q&AAndrus Adamchikandrus@objectstyle.comtwitter.com/andrus_a
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×