Deathmatch: Ruby on Rails vs' J2EE - PowerPoint PPT Presentation

1 / 39
About This Presentation
Title:

Deathmatch: Ruby on Rails vs' J2EE

Description:

... of Loose Coupling with Spring. Adopting Spring is easier when architecture is ... Spring Lessons Learned. Start with bean wiring (Inversion of Control) ... – PowerPoint PPT presentation

Number of Views:52
Avg rating:3.0/5.0
Slides: 40
Provided by: garsomb
Category:

less

Transcript and Presenter's Notes

Title: Deathmatch: Ruby on Rails vs' J2EE


1
Deathmatch Ruby on Rails vs. J2EE
  • Franz Garsombke

2
Spring and Hibernate Extreme Makeover -
Architecture Edition
  • Franz Garsombke

3
Overview
  • Re-factored application
  • Spring concepts
  • Loose coupling
  • Spring EJB architecture
  • Spring POJO architecture
  • Lessons learned
  • Hibernate concepts
  • Hibernate DAO layer
  • Spring Hibernate The dynamic duo
  • Lessons learned
  • Project lessons learned
  • End results
  • QA

4
Personal Info - Qualifications
  • Counterstrike screen name HoneycombB.I.G.
  • Ran a BBS on Commodore 64
  • Subscription to Java Developers Journal
  • Frequent visitor to www.theserverside.com

5
Find a new careerNow!
Java Web Developer Needed
  • Java Web Developer Needed
  • Reply to job-64857317_at_craigslist.orgDate
    2005-03-22, 1042AM MSTJava developer needed to
    assist with database-driven web applications.
    Must be in Boulder area and provide references.
  • Dependibility and strong work ethic required.
    Experience required
  • Java
  • HTML
  • Java Server Pages Servlets
  • JDBC
  • MySQL database design
  • SQL (including complex table joining)
  • Excellent code documentation
  • CSS Experience preferred
  • Apache Tomcat
  • XML
  • LOG4J
  • JavaScript
  • Job location is BoulderCompensation 15 per
    hour, depending on experience This is a
    part-time job.Principals only. Recruiters,
    please don't contact this job poster.Please, no
    phone calls about this job!Please do not contact
    job poster about other services, products or
    commercial interests.Reposting this message
    elsewhere is NOT OK.

6
Re-factoring with Spring and Hibernate
  • Project Statistics
  • 1600 Java files
  • 50 entity Beans no relational mappings
  • 20 Session Beans Entry Points, Nested
    Transactions, WebServices
  • All tests written with Cactus. 0 out-of-container
    tests
  • Build and deployment would take about 15 minutes
  • Flagship Application Major Voice over IP
    application
  • Application Requirements
  • Scalable
  • Reliable primarily an issue of code quality for
    this analysis
  • Flexible resilient to support product changes
  • Code Transpareny
  • During development developer progress code
    quality
  • Easy to integrate and test
  • Enabling of high developer productivity
  • End-state Solution
  • Simplified, layered code

7
VOIP App Problems and Challenges
8
Spring Framework
  • Spring is a layered Java/J2EE application
    framework
  • Swiss army knife
  • AOP cross cutting concerns
  • MVC Framework
  • JMS
  • DAO Abstraction Layer
  • Integration with Hibernate, iBATIS, etc.
  • Inversion of control (bean wiring)
  • Much more
  • Our re-factor project used
  • AOP auditing our entire web service layer
  • Bean wiring injection
  • EJB proxying transparent use of EJBs
  • Hibernate integration no brainer

9
Importance of Loose Coupling with Spring
  • Adopting Spring is easier when architecture is
    loosely coupled
  • Consistent transaction boundaries/entry points
  • Spring adds more value with testing. Control
    injection
  • No boundaries makes things a lot harder

10
High Level of Coupling
Products
Application Framework
External Providers
Data Access
  • Very tight coupling across the entire application
  • Interaction complexity is extremely high.
  • Unit testing is hard to do, if not impossible.
    Impossible out of the container.
  • One code change could potentially affect multiple
    areas of the code.
  • The application is very brittle, and development
    takes much longer than in a layered architecture.
  • More than a few developers and they will start
    stepping on each other.

11
Very Loose Coupling layers talk only to those
directly above and below them
Spring Interceptors (AOP)/Interface
Biz Services
Interface
Products
Application Framework
Spring Interceptors (AOP)/Interface
Interface
External Providers
Workflow
Spring Interceptors (AOP)/Interface
Data Access
  • Structuring a system into layers has a number of
    important benefits
  • Understand a single layer as a coherent whole
    without knowing about the other layers
  • Substitute layers with alternative implementation
    of the same basic services
  • Significantly reduce complexity of code
    interactions
  • Simplify unit testing test each layer
    separately
  • Much more rapid development

12
Looking at a Layer Façade Pattern
After Refactor
Before Refactor
VOIP App
Spring Audit Interceptors
VOIP App
External Provider Layer
Service1
Service2
Service3
Service4
Service4
Service3
Service2
Service1
Refactor Enabled
VOIP App
Mock
Mock
Mock
Mock
Mock External Provider Layer
13
Loose Coupling w/ Business Interface Pattern
  • Having code in EJBs makes unit testing extremely
    difficult since everything has to be run in an
    application server.
  • Moved all business logic out of Stateless and
    Message Driven EJBs into plain old java objects
    (POJO). EJB is solely used for transaction and
    thread management. This makes testing the
    business logic much easier since we can write all
    of our tests out of the container.

14
ltbean id"orderService" lazy-init"true"
class"org.spring...SimpleRemoteStatelessSessionPr
oxyFactoryBean"gt ltproperty name"jndiName"gt
ltvaluegtOrderServicelt/valuegt lt/propertygt
ltproperty name"businessInterface"gt
ltvaluegtcom.voip.OrderServiceBizIFlt/valuegt
lt/propertygt lt/beangt
15
Business Service Arch. Pattern with EJB
DAO 1 (POJO)
Hibernate Interceptor (Spring) Audit Interceptor
EJB CMT
Biz Service (POJO)
DAO 2 (POJO)
Biz Service 2 (POJO)
Hibernate Session
JTA Transaction (Hibernate has built-in JTA
auto-detect)
DAO 2 (POJO)
Injection
Biz Service 2 (POJO)
Biz Service (POJO)
DAO 1 (POJO)
16
Business Service Arch. Pattern with Req. New Tx
EJB
17
Business Service Arch. Pattern without EJB
18
Interceptors Configuration
  • ltbean id"hibernateInterceptor"
    class"org.springframework.orm.hibernate.Hibernate
    Interceptor"gt
  • ltproperty name"sessionFactory"gt
  • ltref bean"sessionFactory"/gt
  • lt/propertygt
  • lt/beangt
  • ltbean id"auditInterceptor" class"com.voip.AuditI
    nterceptor"gt
  • ltproperty name"daoAudit"gt
  • ltref bean"daoAudit"/gt
  • lt/propertygt
  • lt/beangt

19
Biz Services Configuration
Interceptors
  • ltbean id"_serviceAutoProxyCreator1"
    class"org.spring.aop.framework.autoproxy.BeanName
    AutoProxyCreator"gt
  • ltproperty name"interceptorNames"gt
  • ltlistgt
  • ltidref bean"hibernateInterceptor"/gt
  • ltidref bean"auditInterceptor"/gt
  • lt/listgt
  • lt/propertygt
  • ltproperty name"beanNames"gt
  • ltlistgt
  • ltidref local"OrderServiceBizIF"/gt
  • lt/listgt
  • lt/propertygt
  • lt/beangt
  • ltbean id"OrderServiceBizIF" class"com.voip.Order
    ServiceBiz"gt
  • ltproperty name"daoOrder"gtltref
    bean"daoOrder"/gtlt/propertygt
  • ltproperty nameservice2"gtltref
    beanservice2"/gtlt/propertygt
  • lt/beangt

Beans
Service Class
Injection
20
Typical Biz Service Class
  • public class OrderServiceBiz implements
    OrderServiceBizIF
  • private DAOOrderIF daoOrder // injected
  • /
  • _at_xdocletpublic-method
  • /
  • public OrderDTO placeOrder(String name) throws
    MyAppException
  • OrderDTO order new OrderDTO()
  • order.setCreateDate(new Date())
  • order.setName(name)
  • // do biz logic here
  • getDaoOrder().storeOrder(order)
  • public DAOOrderIF getDaoOrder()
  • return daoOrder

21
Spring Lessons Learned
  • Start with bean wiring (Inversion of Control)
  • Beans that are Spring wired are very easy to
    apply AOP
  • The more injection, the more you can mock
  • Spring can be used for test data retrieval
  • One of Springs goal is to make existing
    technologies easier. Spring is not Hibernate,
    Hibernate is not Spring.
  • Ability to change behavior without changing code
    is an important point and benefit of Spring (i.e.
    datasource configuration, transaction manager,
    our entire web service layer)
  • Re-factor into layers first, then add Spring and
    Hibernate
  • Layering also creates boundaries
  • Tradeoff between run-time flexibility and
    run-time configuration validation
  • Changing one property in the database allows us
    to change entire layers

22
Hibernate
  • Hibernate is a powerful, ultra-high performance
    object/relational persistence and query service
    for Java

23
Data Access Object Layer
  • Implementation details of DAO layer left up to
    developer (i.e you can use JDBC, Hibernate,
    iBATIS, JDO, Entity Beans, etc.)
  • Entity beans are hard to test and are not very
    scalable since they are application server
    managed objects.
  • Every Entity Bean was removed and replaced with a
    Spring/Hibernate true object relational layer, or
    Data Access Object Layer (DAO). This layer is
    fully testable out of the container.
  • This layer was implemented with interfaces in
    front which allows for the layer to be stubbed or
    mocked for application testing
  • A DAO layer enables you to adopt new persistence
    mechanisms

24
Hibernate DAO Layer
  • Many things are generated
  • Middlegen Hibernate Mapping Files
  • Hbm2java Data Transfer Objects (DTOs)
  • XDoclet - Interfaces
  • Spring makes Hibernate session management
    transparent with Hibernate Interceptors and the
    HibernateDAOSupport class
  • DAO Layer only took about a week to create.
    Largely depends on underlying data model and
    referential integrity
  • Hibernate allows for Hibernate Query Language or
    pure SQL
  • This DAO layer provides all the benefits that
    Hibernate brings to the table (caching, lazy
    loading, etc.).

25
DAO UML Diagram
26
Typical DAO Class
  • DAO represents an aggregate or functional area
  • public class DAOAudit extends HibernateDaoSupport
    implements DAOAuditIF
  • /
  • _at_xdocletpublic-method
  • /
  • public AuditEventDTO loadAuditEvent(Long id)
  • return (AuditEventDTO) getHibernateTemplate().load
    (AuditEventDTO.class, id)

27
Typical DAO Class (cont.)
  • /
  • _at_xdocletpublic-method
  • /
  • public Object findUniqueByDynamicQuery(final
    Object dto, final Class dtoType)
  • HibernateCallback callback new
    HibernateCallback()
  • public Object doInHibernate(Session
    session) throws HibernateException
  • Example exampleDto Example.create(dto).i
    gnoreCase().enableLike(MatchMode.ANYWHERE)
  • return session.createCriteria(dtoType).add
    (exampleDto).uniqueResult()
  • return getHibernateTemplate().execute(callback
    )

28
Typical DAO Class (cont.)
  • /
  • _at_xdocletpublic-method
  • /
  • public Collection findSpringOrdersByName(String
    name)
  • return getHibernateTemplate().find(
  • "from AuditEventDTO event where event.name
    ?", name,Hibernate.STRING)

29
Hibernate/Spring ConfigSession Factory
  • ltbean id"sessionFactory class"org.spring.orm.hi
    bernate.LocalSessionFactoryBeangt
  • ltproperty name"dataSource"gtltref
    bean"dataSource"/gtlt/propertygt
  • ltproperty name"mappingResources"gt
  • ltlistgt
  • ltvaluegtcom/voip/OrderDTO.hbm.xmllt/valuegt
  • More DTOs
  • lt/listgt
  • lt/propertygt
  • ltproperty name"hibernateProperties"gt
  • ltpropsgt
  • ltprop key"hibernate.dialect"gtnet.sf.hiberna
    te.dialect.Oracle9Dialectlt/propgt
  • ltprop key"hibernate.trans.manager_lookup_cl
    ass"gttransaction.lookup.classlt/propgt
  • lt/propsgt
  • lt/propertygt
  • lt/beangt
  • ltbean id"nonTxSessionFactory class"org.spring.o
    rm.hibernate.LocalSessionFactoryBean"gt
  • ltproperty name"dataSource"gtltref
    bean"nonTxDataSource"/gtlt/propertygt
  • ltproperty name"mappingResources"gt

Hibernate Mapping Files
Auto JTA Detection
30
Hibernate/Spring Configuration DAO
  • lt!--
    --gt
  • lt!-- Hibernate DAO --gt
  • lt!--
    --gt
  • ltbean id"daoOrder" class"com.voip.DAOOrder"gt
  • ltproperty name"sessionFactory"gtltref
    local"sessionFactory"/gtlt/propertygt
  • lt/beangt
  • ltbean id"daoAudit" class"com.voip.DAOAudit"gt
  • ltproperty name"sessionFactory"gtltref
    local"nonTxSessionFactory"/gtlt/propertygt
  • lt/beangt
  • Spring Property Files
  • Production
  • transaction.lookup.classnet.sf.hibernate.trans.We
    blogicTransactionManagerLookup
  • Test

Inject with Tx Session Factory
Inject with NonTx Session Factory
31
Hibernate/Spring Configuration Datasource
  • lt!--
    --gt
  • lt!-- Data Sources (Production) --gt Spring
    Production Bean Factory
  • lt!--
    --gt
  • ltbean id"dataSource" class"org.spring.jndi.JndiO
    bjectFactoryBean"gt
  • ltproperty name"jndiName"gtltvaluegtspring_datasourc
    elt/valuegtlt/propertygt
  • lt/beangt
  • ltbean id"nonTxDataSource" class"org.spring.jndi.
    JndiObjectFactoryBean"gt
  • ltproperty name"jndiName"gtltvaluegtnontx_datasource
    lt/valuegtlt/propertygt
  • lt/beangt
  • lt!--
    --gt
  • lt!-- Data Sources (Testing) --gt Test Bean Factory
  • lt!--
    --gt
  • ltbean id"dataSource" class"springframework...Sin
    gleConnectionDataSource"gt
  • ltproperty name"url"gtltvaluegtjdbc.urllt/valuegtlt/p
    ropertygt
  • ltproperty name"username"gtltvaluegtjdbc.userna
    melt/valuegtlt/propertygt
  • ltproperty name"password"gtltvaluegtjdbc.passwo
    rdlt/valuegtlt/propertygt
  • lt/beangt

32
DAO Lessons Learned
  • Lazy loading a must have (session per
    transaction)
  • Collections
  • Class Level
  • Left outer joins slow
  • Checked Exceptions
  • Remember the first level cache
  • If re-factoring, create DAO layer first and get
    code coverage to 100
  • Automatic dirty-checking is a must have
    (session per transaction)
  • Write generic finder methods instead of one
    finder method for each possible combination
  • Bi-directional relationship problems
  • Consistent patterns are very important for a DAO
    layer exception handling, transaction mgmt,
    finder methods, etc
  • Hiberate 3.0.1 SessionFactory.getCurrentSession()
    method. It allows application developers to
    delegate tracking of current sessions to
    Hibernate itself. Currently, the
    getCurrentSession() method is only available if
    you are using Hibernate within a JTA environment.

33
Replicating the container transactional unit
testing
34
Replicating the container transactional unit
testing
  • ltbean id"transactionManager" class"org.springfra
    mework.orm.hibernate.HibernateTransactionManager"gt
  • ltproperty name"sessionFactory"gt
  • ltref bean"sessionFactory"/gt
  • lt/propertygt
  • lt/beangt

35
Replicating the container transactional unit
testing
  • protected void setUp() throws Exception
  • setTransactionManager((PlatformTransactionManage
    r) getClassFactory().getObjectById("transactionMan
    ager"))
  • // Start a transaction
  • transactionManager.getTransaction(new
    DefaultTransactionDefinition())
  • protected void tearDown() throws Exception
  • try
  • onTearDownInTransaction()
  • finally
  • getTransactionManager().rollback(getTransact
    ionStatus())

36
Summary of Patterns/Design Principles
  • DAO
  • separates a data resource's client interface from
    its data access mechanisms. Adapts a specific
    data resource's access API to a generic client
    interface
  • Interface
  • Keep a class that uses data and services provided
    by instances of other classes independent of
    those classes by having it access those instances
    through an interface
  • AOP
  • Aspect-oriented programming (AOP) is a new
    programming technique that allows programmers to
    modularize crosscutting concerns (behavior that
    cuts across the typical divisions of
    responsibility, such as logging)
  • IOC
  • Inversion of Control (IOC) is a means to inject
    components into other components thus allowing
    for very loose coupling

37
Project Lessons Learned
  • Steel Thread/Prototype/Reference Architecture
  • Do your homework (0 infrastructure bugs).
    Replacing the engines in-flight on an airplane
    analogy
  • Iterations
  • Scapegoat central
  • Need someone with crosscutting knowledge
  • Correct or dispel bad press quickly
  • Set realistic expectations there will be bugs
  • Not a silver bullet must use all the parts
  • Be pragmatic dont use because its cool
  • Existing unit tests make life a lot easier

38
Re-factor Results
  • Entire code base can be tested out of container
    except for EJB ? EJB calls
  • Code is much more maintainable
  • Re-factoring is much easier with baseline of unit
    tests in place
  • Inversion of control helps immensely in mocking
    out external service layer calls
  • Testing becomes much easier meaning more likely
    to happen
  • Teams able to scale with less code contention

39
Questions?
fgarsombke_at_yahoo.com
http//dozer.sourceforge.net
Shameless Plug
Dozer is a powerful, yet simple Java Bean to Java
Bean mapper that recursively copies data from one
object to another. Typically, these Java Beans
will be of different complex types.
Dozer supports simple property mapping, complex
type mapping, bi-directional mapping,
implicit-explicit mapping, as well as recursive
mapping. This includes mapping collection
attributes that also need mapping at the element
level.
Write a Comment
User Comments (0)
About PowerShow.com