Life outside WO
Upcoming SlideShare
Loading in...5
×
 

Life outside WO

on

  • 749 views

 

Statistics

Views

Total Views
749
Views on SlideShare
749
Embed Views
0

Actions

Likes
0
Downloads
12
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Life outside WO Life outside WO Presentation Transcript

  • Life outside WOby Andrus Adamchik, ObjectStyle LLC
  • • 1998 - 2003 :WebObjects programmer• 1998 - present : Java programmer• 2001 - present : working on Cayenne• Apache member, open source developer• Owner of ObjectStyle LLCAbout me
  • Life outside WO
  • 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
  • What alternative stack wouldsatisfy a WO developer?
  • WO Stack
  • Generic DI-CentricStack
  • Our Stack
  • Why not JEE?
  • JEE provides us container,web app structure and coreHTTP APIs:Servlets (JSR-315)JAX-RS - Jersey (aka JSR-311, aka REST)
  • Stack Parts• Dependency Injection• HTML Framework• REST Framework• Persistence
  • Dependency Injection
  • 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
  • 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) { .. }}
  • 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) { .. }...}
  • 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) { .. }}
  • 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
  • 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) { .. }}
  • 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
  • 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
  • DI Framework Choices• Spring• Google Guice• Apache Tapestry• CDI• (Cayenne DI)
  • DI Framework Choices• All support annotations• All are very capable• Choice is driven by front-end technology (Tapestry for us)
  • 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
  • HTML Framework
  • HTML Framework - Choices• JSF• Tapestry (aka “T5” for “Tapestry v.5”)• Spring MVC• Wicket, Seam, Click, Grails, many others...
  • 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
  • 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)
  • 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.)
  • 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>
  • 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>
  • REST Framework
  • 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
  • REST Framework Has DifferentRequirements from HTML OnePossible to build on top of Tapestry/WO/etc.,but is it a good idea?
  • 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)
  • JAX-RS (JSR-311)My favorite JEE spec :)
  • 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
  • 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; }}
  • 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
  • Persistence Framework ... we’lldiscuss it later
  • Migration from WO
  • 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
  • No Direct Replacement for:• DirectToWeb (likely possible to implement on top of Tapestry)• DirectToJavaClient (however 3-tier ORM is available, provided byCayenne ROP)
  • WOCommunity Can:• Create WO-to-T5 template migration tools• Port Wonder to Cayenne/T5• Port ERRest to Jersey/Cayenne• ...
  • We’ve gone from Objective C to Javaonce, so we can do it again...
  • Q&AAndrus Adamchikandrus@objectstyle.comtwitter.com/andrus_a