SlideShare a Scribd company logo
Typical Java Problems
                                           in the Wild

                                                                      Eberhard Wolff
                                                                       SpringSource




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
SpringSource Solution

                           Unifying the Application Lifecycle:
                            from Developer to Datacenter

 High Productivity Tools                                                                                             Lean Powerful Runtimes
      Spring Enterprise                                                                                              SpringSource tc Server
      Groovy and Grails                                                Build	
   Run	
                               SpringSource dm Server
SpringSource Tool Suite                                                                                              SpringSource http Server


                                                                               Manage	
  

                                           Application Infrastructure Management
                                                  SpringSource Hyperic HQ
                                                              SpringSource Hyperic IQ
Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.                            2
About me

•  Regional Director German speaking region and
   Principal Consultant
•  Author of several articles and books
•  First German Spring book
•  Speaker at national and international conferences

•  Eberhard.Wolff@springsource.com




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   3
Why this talk?

•  I do a lot of reviews
•  There are some common problems you see over and
   over again

•  So: Here are 10
         –  …not necessarily the most common
         –  ...but certainly with severe effects




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   4
#1
public class Service {	
	
      private CustomerDao customerDao;	
      private PlatformTransactionManager transactionManager;	
	
      public void performSomeService() {	
         TransactionStatus transactionStatus = transactionManager	
          .getTransaction(new DefaultTransactionDefinition());	
         customerDao.doSomething();	
         customerDao.doSomethingElse();	
         transactionManager.commit(transactionStatus);	
      }	
	
}	
  




 Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   5
#1 Weak Transaction
Handling
public class Service {	
	
      private CustomerDao customerDao;	
      private PlatformTransactionManager transactionManager;	
	
      public void performSomeService() {	
         TransactionStatus transactionStatus = transactionManager	
          .getTransaction(new DefaultTransactionDefinition());	
         customerDao.doSomething();	
         customerDao.doSomethingElse();	
         transactionManager.commit(transactionStatus);	
      }	
	
    •  What happens to the transaction if the DAO
}	
  
       throws an exception?
    •  We might never learn...
    •  ...or learn the hard way
Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   6
Weak Transaction Handling:
Impact
•  Hard to detect, has effects only if exception is
   thrown
•  …but then it can lead to wired behavior and data loss
   etc.
•  That is why you are using transactions in the first
   place




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   7
Solution

•  Declarative transactions
public class Service {	
	
      private CustomerDao customerDao;	
	
      @Transactional	
      public void performSomeService() {	
         customerDao.doSomething();	
         customerDao.doSomethingElse();	
      }	
	
}	
  
   •  Exception is caught, transaction is rolled back (if
      it is a RuntimeException)
   •  Exception handling can be customized

Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   8
A different solution…
 public void performSomeService() {	
   TransactionTemplate template = new TransactionTemplate(	
    transactionManager);	
   template.execute(new TransactionCallback() {	
 	
     public Object doInTransaction(TransactionStatus status) {	
        customerDao.doSomething();	
        customerDao.doSomethingElse();	
        return null;	
     }	
 	
    });	
 }
•  Allows for multiple transactions in one method
•  More code – more control
•  Rather seldom really needed
 Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   9
#2 Exception Design

•  Get all the details from a system exception!
•  Each layer must only use its own exceptions!
•  Exceptions have to be checked – then they must be
   handled and the code is more secure.

•  Sounds reasonably, doesn't it?




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   10
public class OrderDao {	
   public void createOrder(Order order) throws SQLException {	
      // some ugly JDBC code	
      // that I am not going to show	
   }	
}	
                                                                    public class SomeService {	
                                                                       public void performService()	
Get all the details!                                                      throws ServiceException {	
Use checked                                                               try {	
exceptions!                                                                  orderDao.createOrder(new Order());	
                                                                          } catch (SQLException e) {	
                                                                             throw new ServiceException(e);	
Service must only                                                         }	
throw                                                                  }	
ServiceException!                                                   }	       public class SomeController {	
                                                                                              public void handleWebRequest() {	
                                                                                                 try {	
 What am I supposed to do                                                                           someService.performService();	
 now?                                                                                            } catch (Exception e) {	
 No real logging                                                                                    e.printStackTrace();	
                                                                                                 }	
 And I don t care about the                                                                   }	
 specific ServiceException                                                              }
 Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.            11
Impact

•  Lots of useless exception handling code
•  Lots of exception types without specific handling of
   that type
•  In the end all you get is a log entry and lots of code

•  And what should the developer do?
         –  All he knows "Something went wrong"
         –  Does not really care and can not really handle it




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   12
Why is this commonplace?

•  Very few languages have checked exceptions (Java -
   CLU and Modula-3 had similar concepts)
•  Checked exception force developers to handle an
   exception – very rigid
•  How common is it that you can really handle an
   exception?
•  Checked exceptions are perceived to be more secure
•  Checked exceptions are overused – also in Java APIs

•  In many cases there are even no exception concepts
   in projects


Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   13
Solution

•  Use more unchecked exceptions aka
   RuntimeExceptions
•  Remember: A lot of languages offer only unchecked
   exceptions

•  Avoid wrap-and-rethrow – it does not add value
•  Don't write too many exception classes – they often
   don't add value
•  A specific exception classes is only useful if that
   exception should be handled differently



Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   14
Solution

public class OrderDao {	
   public void createOrder(Order order) {	
      jdbcTemplate.update("INSERT INTO ORDER ...");	
   }	
}	


                                                            public class SomeService {	
Where is the                                                   public void performService() {	
exception                                                      }	
                                                                  orderDao.createOrder(new Order());	

handling?                                                   }	

                                                                                             public class SomeController {	
                                                                                               public void handleWebRequest() {	
                                                                                                  someService.performService();	
                                                                                               }	
                                                                                             }

 Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.         15
AOP in one Slide

@Aspect	
public class AnAspect {	
	
   // do something before the method hello	
   // is executed	
   @Before("execution(void hello())")	
   public void doSomething() {	
   }	
	
  // in a specific class	
   // that ends in Service in any package or subpackage	
   @Before("execution(* com.springsource.MyService.hello())")	
   public void doSomethingElse2() {	
   }	
	
   // do something before any method in a class	
   // that ends in Service in any package or subpackage	
   @Before("execution(* *..*Service.*(..))")	
   public void doSomethingElse2() {	
   }	                                                        16
Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
Aspect for Logging

@Aspect	
public class ExceptionLogging {	
	
   @AfterThrowing(value="execution(* *..Service*.*(..))",	
    throwing="ex")	
   public void logRuntimeException(RuntimeException ex) {	
      System.out.println(ex);	
   }	
	
}	


•  Logs every exception – 100% guaranteed!




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   17
Handle only cases you really
want to handle

     public class SomeService {	
        public void performService() {	
           try {	
              orderDao.createOrder(new Order());	
           } catch (OptimisticLockingFailureException ex) {	
              orderDao.createOrder(new Order());	
           }	
        }	
     }	

•  Everything else will be handled somewhere else
•  Can handle specific error conditions using catch with
   specific types


Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   18
Generic Exception Handling

public class MyHandlerExceptionResolver	
  implements HandlerExceptionResolver {	
	
   public ModelAndView resolveException(	
    HttpServletRequest request,	
    HttpServletResponse response, Object handler, Exception ex) {	
      return new ModelAndView("exceptionView", "exception", ex);	
   }	
	
}

•  In the web layer
•  Handle all the (Runtime)Exceptions not handled
   elsewhere



Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   19
#3 Exception Handling

    public void someMethod() {	
      try {	
    	
      } catch (Exception ex) {	                                                                    Exception is not logged
         ex.printStackTrace();	                                                                    just written to stdout
      }	
                                                                                                   operations might not notice
      try {	
    	
      } catch (Exception ex) {	
         // should never happen	                                                                   Exception is swallowed
      }	
    }




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.               20
Impact

•  Related to #2: If you have excessive checked
   exceptions this will occur more often
•  …as developers are forced to handle exceptions they
   can't really handle
•  In the end you just get a message on the console
   and the application continues.
•  All kinds of wired behavior
•  i.e. exception is swallowed
•  You will have a hard time finding problems in the
   code
•  Potentially a huge problem – so worth its own
   explanation
Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   21
Solution

•  At least log exceptions
•  Rethink: Is it really OK to continue in this situation?
   If not - don't handle the exception. Might be better
   to let a generic handler handle it.
•  Introduce generic handling at least for
   RuntimeException (AOP, web front end, etc)
•  Enforce the logging using Findbugs, PMD etc.
•  And: Improve the
                               public void someMethod() {	
   exception design (#2)         try {	
                                                                                                   	
                                                                                                         } catch (Exception ex) {	
                                                                                                            log.error(ex);	
                                                                                                         }	
                                                                                                   }
Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.                   22
#4

•  Table of
   packages and
   the relations
   between them
•  Everything in
   red is part of a
   cycle
•  This is actual
   code from an
   Open Source
   project



 Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   23
Dependency Graph

•  Overview




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   24
Dependency
Graph
•  Just a small part
•  Red line show
   circular references




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   25
What is Architecture?

•  Architecture is the decomposition of systems in parts

•  No large or complex parts
•  No cyclic dependencies




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   26
Normal Dependencies

•  B dependes on A, i.e. it uses
   classe, methods etc.
•  Changes in A impact B                                                                                             Component A
•  Changes in B do not impact A




                                                                                                                     Component B




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.                 27
Cyclic Dependency

•  B depends on A and A on B
•  Changes in A impact B
•  Changes in B impact A                                                                                             Component A
•  A and B can only be changed
   as one unit
•  …even though they should be
   two separate units
                                                                                                                     Component B




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.                 28
Bigger cyclic dependencies



                          Component A


                                                                                                                     Component B


                          Component C




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.                 29
#4: Architecture Mess

•  This is effectively
   just one big
   unstructured pile
   of mud
•  Maintenance will
   be hard
•  Concurrent
   development will
   be hard
•  Changes will have
   unforeseeable
   results

 Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   30
Solution

•  Very hard if you have this state
•  Therefore: Manage dependencies from the start
•  Otherwise you are looking at a major restructuring of
   your application
•  …which might not be worth it
•  Effort for restructuring pays off by lower effort for
   maintenance
•  …might take a long time to amortize

•  Throwing away + redevelopment means that you
   have to migrate to a new solution -> complex and
   risky
Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   31
#5
public class ServiceAdaptor {	
   public void performService(OrderDTO orderDTO) {	
      logger.trace("Entering performService");	
      try {	
         if (orderDTO == null) {	
            throw new NullPointerException("order must not be null");	
         }	
         if (youAreNotAllowedToDoThis()) {	
            throw new IllegalStateException(	
             "You are not allowed to call this!");	
         }	
         OrderEntity order = new OrderEntity();	
         order.setCustomer(orderDTO.getCustomer()); // ...	
         service.performService(order);	
         commandLog.add(new Command("performService",	
          service,order));	
      } finally {	
         logger.trace("Leaving performanceService");	
      }	
   }	
}	                                                                 32
 Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
#5: Adaptor Layer

•  Adds to a service:
         –  Security
         –  Tracing
         –  Check for null arguments
         –  Log for all commands (auditing, replay…)
         –  Conversion from DTO to internal representation
•  Lots of boilerplate for each service
•  Changes to tracing etc. hard: lots of methods to
   change




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   33
Solution: Tracing with AOP

•  …or use Spring's predefined TraceInterceptor,
   DebugInterceptor etc.
    @Aspect	
    public class TraceAspect {	
    	
      @Before("execution(* *..*Service.*(..))")	
      public void traceBegin(JoinPoint joinPoint) {	
        System.out.println("entering method "	
          + joinPoint.getSignature().getName());	
       }	
    	
       @After("execution(* *..*Service.*(..))")	
       public void traceEnd(JoinPoint joinPoint) {	
          System.out.println("leaving method "	
           + joinPoint.getSignature().getName());	
       }	
    }

Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   34
Solution:
Null Checks with AOP
@Aspect	
public class NullChecker {	
	
  @Before("execution(* *..*Service.*(..))")	
  public void checkForNull(JoinPoint joinPoint) {	
     for (Object arg : joinPoint.getArgs()) {	
        if (arg==null) {	
          throw new NullPointerException("Argument was null!");	
        } 	
     }	
  }	
	
}


•  Security can be handled with Spring Security or AOP
•  Command log also possible

Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   35
What is left…
public class ServiceAdaptor {	
	
  public void performService(OrderDTO orderDTO) {     	
     OrderEntity order = new OrderEntity();	
     order.setCustomer(orderDTO.getCustomer()); // ...	
     service.performService(order);	
  }	
	
}
  •  You should probably switch to Dozer
    •  http://dozer.sf.net
    •  Can externalize mapping rules
    •  i.e. the layer can be more or less eliminated
    •  Everything (mapping, security, tracing…) is now
       implemented in one place (DRY)
    •  Often services just delegate to DAOs –
        same issue
Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   36
#6: No DAO
public class SomeService {	
	
  @PersistenceContext	
  private EntityManager entityManager;	
	
  public void performSomeService() {	
     List<Order> list = entityManager.	
      createQuery("select o from Order").getResultList();	
     for (Order o : list) {	
        // ...	
        if (o.shouldBeProcessed()) {	
           o.process();	
        }	
     }	
  }	
}
•  We don't need to abstract away from JPA – it's a
   standard, right?
Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   37
#6: Even worse
public class SomeServiceJdbc {	
	
private OrderDao someDoa;	
	
  public void performSomeService() throws SQLException {	
     ResultSet rs = someDoa.getOrders();	
     while (rs.next()) {	
        //...	
     }	
  }	
	
}

•  Service depends on JDBC
•  …and throws SQLException
•  Persistence visible in the service layer and beyond

Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   38
Impact

•  Code is impossible to test without a database
•  …so no real unit tests possible

•  Service depends on persistence – cannot be ported

•  How do you add data dependent security?

•  No structure




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   39
Solution

•  Use a DAO (Data Access Object)
         –  Separate persistence layer
         –  Technical motivation


•  …or a Repository
         –  Interface to existing objects
         –  Non technical motivation: Domain Driven Design, Eric
            Evans


•  Basically the same thing



Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   40
Solution

public class SomeServiceDAO {	
	
  public void performSomeService() {	
     List<Order> list = orderDao.getAllOrders();	
     for (Order o : list) {	
       // ...	
       if (o.shouldBeProcessed()) {	
          o.process();	
       }	
      }	
  }	
}

•  Clear separation
•  Tests easy


Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   41
Solution: Test

public class ServiceTest {	
  @Test	
  public void testService() {	
     SomeService someService = new SomeService();	
     someService.setOrderDao(new OrderDao() {	
	
       public List<Order> getAllOrders() {	
          List<Order> result = new ArrayList<Order>();	
          return result;	
       }	
     });	
     someService.performSomeService();	
     Assert.assertEquals(expected, result);	
  }	
	
}



Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   42
#7

•  No Tests




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   43
#7 Or bad tests
•  No asserts       public class MyUnitTest {	
                      private Service service = new Service();	
•  System.out:      	
   results are        @Test	
   checked            public void testService() {	
   manually             Order order = new Order();	
                        service.performService(order);	
•  Tests commented      System.out.print(order.isProcessed());	
   out: They did not }	
   run any more     	
   and were not       // @Test	
                      // public void testOrderCreated() {	
   fixed              // Order order = new Order();	
•  No mocks, so no // service.createOrder(order);	
   real Unit Tests    // }	
                    	
•  No negative      }
   cases

 Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   44
Impact

•  Code is not properly tested
•  Probably low quality – testable code is usually better
   designed
•  Code is hard to change: How can you know the
   change broke nothing?
•  Design might be bad: Testable usually mean better
   quality




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   45
Solution

 •  Write proper Unit Tests!
public class MyProperUnitTest {	
   private Service service = new Service();	
	
   @Test	
   public void testService() {	
      Order order = new Order();	
      service.performService(order);	
      Assert.assertTrue(order.isProcessed());	
   }	
	
   @Test(expected=IllegalArgumentException.class)	
   public void testServiceException() {	
      Order order = new BuggyOrder();	
      service.performService(order);	
   }	
	
}	
 Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   46
Wow, that was easy!




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
The real problem…

•  The idea of Unit tests is over 10 years old
•  Not too many programmer actually do real unit tests
•  Even though it should greatly increased trust and
   confidence in your code
•  …and make you much more relaxed and therefore
   improve quality of life…

•  Original paper: Gamma, Beck: "Test Infected –
   Programmers Love Writing Tests"
•  Yeah, right.



Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   48
BTW




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   49
Solution

•  Educate
         –  Show                   how to write Unit Test
         –  Show                   how to build Mocks
         –  Show                   aggressive Testing
         –  Show                   Test First / Test Driven Development
•  Coach / Review
•  Integrate in automatic build
•  Later on: Add integration testing, functional testing,
   FIT, Fitnesse etc.
•  …or even start with these



Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   50
What does not really work

•  Measuring code coverage
         –  Can be sabotaged
         public class MyProperUnitTest {	
           private Service service = new Service();	
         	
           @Test	
           public void testService() {	
              Order order = new Order();	
              service.performService(order);	
           }	
         }

•  Let developers just write tests without education
         –  How should they know how to test properly?
         –  Test driven development is not obvious

Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   51
#8: Creating SQL statements


    public class OrderDAO {	
    	
      private SimpleJdbcTemplate simpleJdbcTemplate;	
    	
      public List<Order> findOrderByCustomer(String customer) {	
         return simpleJdbcTemplate.query(	
          "SELECT * FROM T_ORDER WHERE name='"	
          + customer + "'", new OrderRowMapper());	
      }	
    	
    }




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   52
Impact

•  Performance is bad:
         –  Statement is parsed every time
         –  Execution plan is re created etc.




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   53
Impact

•  Even worse: SQL injection
•  Pass in a' or 't'='t'
•  Better yet: a'; DROP TABLE T_ORDER; SELECT *
   FROM ANOTHER_TABLE

public class OrderDAO {	
	
  private SimpleJdbcTemplate simpleJdbcTemplate;	
	
  public List<Order> findOrderByCustomer(String customer) {	
     return simpleJdbcTemplate.query(	
      "SELECT * FROM T_ORDER WHERE name='"	
      + customer + "'", new OrderRowMapper());	
  }	
	
}
Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   54
Solution

    public class OrderDAO {	
    	
      private SimpleJdbcTemplate simpleJdbcTemplate;	
    	
      public List<Order> findOrderByCustomer(String customer) {	
         return simpleJdbcTemplate.query(	
          "SELECT * FROM T_ORDER WHERE name=?",	
          new OrderRowMapper(), customer);	
      }	
    	
    }
•  … and white list the allowed characters in name




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   55
#9

•     "What about Performance?"
•     "Well, we figured the response time should be 2s."
•     "How many request do you expect?"
•     "…"
•     "What kind of requests do you expect?"
•     "..."




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   56
#9

•     The software is happily in the final functional test
•     Then the performance test start
•     Performance is too bad to be accepted
•     You can hardly do anything:
         –  Changes might introduce functional errors
         –  Too late for bigger changes anyway
•  The results might be wrong if the performance test is
   on different hardware than production.
•  You can't test on production hardware: Too
   expensive.



Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   57
Impact

•  You have to get bigger hardware
         –  Prerequisite: The software is scalable


•  Worse: You can't go into production




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   58
Solution

•  Get information about the number of requests,
   expected types of requests, acceptable response
   times
•  Pro active performance management:
         –  Estimate the performance before implementation
         –  …by estimating the slow operations (access to other
            systems, to the database etc)
         –  Measure performance of these operation in production
•  Practice performance measurements and
   optimizations before performance test




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   59
#10
            public class SomeService {	
            	
            private Map cache = new HashMap();	
            private Customer customer;	
            	
              public Order performService(int i) { 	
                 if (cache.containsKey(i)) {	
                    return cache.get(i);	
                 }	
                 Order result;	
                 customer = null;	
                 cache.put(i, result);	
                 return result;	
              }	
            	
            }



Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   60
#10 Multiple threads, memory
leaks
public class SomeService {	
	                                                                                                                    The cache is filled –
  private Map<Integer,Order> cache =	                                                                                is it ever emptied?
   new HashMap<Integer, Order>();	
  private Customer customer;	                                                                                        HashMap is not
	
  public Order performService(int i) { 	
                                                                                                                     threadsafe
     if (cache.containsKey(i)) {	
        return (Ordercache.get(i);	
                                                                                                                     customer is an
     }	                                                                                                              instance variable –
     Order result;	                                                                                                  multi threading will
     customer = null;	
     ...	
                                                                                                                     be a problem
     cache.put(i, result);	
     return result;	
  }	
	
}

Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.                           61
Impact

•  System working in small tests
•  In particular Unit tests work

•     But production fails
•     …probably hard to analyze / fix
•     Almost only by code reviews
•     …or extensive debugging using thread dumps




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   62
Solution
                            public class SomeServiceSolution {	
•     Use WeakHashMap to    	
      avoid memory leaks private Map<Integer, Order> cache =	
                               new WeakHashMap<Integer, Order>();	
•     Synchronize           	
•     Prefer local variables public Order performService(int i) {	
                                 synchronized (cache) {	
•     Usually services can          if (cache.containsKey(i)) {
      store most things in             return cache.get(i);	
                                    }	
      local variables            }	
                                 Order result = null;	
                                 Customer customer = null;	
                                 synchronized (cache) {	
                                    cache.put(i, result);	
                                 }	
                                 return result;	
                              }	
                            }
Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   63
Solution

•  Also consider ConcurrentHashMap
•  or http://sourceforge.net/projects/high-scale-lib




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.   64
Sum Up

  •  #1 Weak Transaction                                                                             •  #8 Creating SQL
     Handling                                                                                           queries using String
  •  #2 Exception Design                                                                                concatenation
  •  #3 Exception Handling                                                                           •  #9 No performance
  •  #4 Architecture Mess                                                                               management
                                                                                                     •  #10 Multiple threads /
  •  #5 Adaptor Layer
                                                                                                        memory leaks
  •  #6 No DAO
  •  #7 No or bad tests




Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.               65

More Related Content

What's hot (19)

PDF
Adopting Java for the Serverless world at Serverless Meetup Singapore
Vadym Kazulkin
 
PDF
FaaS or not to FaaS. Visible and invisible benefits of the Serverless paradig...
Vadym Kazulkin
 
PDF
Writing less code with Serverless on AWS at FrOSCon 2021
Vadym Kazulkin
 
PPTX
#JavaOne What's in an object?
Charlie Gracie
 
PDF
Iguazú: A Long-Running Job Scheduler using Docker and Mesos
Colleen Lee
 
PDF
Serverless Java Challenges & Triumphs
David Delabassee
 
PDF
JVM Support for Multitenant Applications - Steve Poole (IBM)
jaxLondonConference
 
PPTX
Immutable Infrastructure: the new App Deployment
Axel Fontaine
 
PDF
Java in the Cloud : PaaS Platforms in Comparison
Eberhard Wolff
 
PDF
ReST Vs SOA(P) ... Yawn
ozten
 
PDF
JavaOne 2015: 12 Factor App
Joe Kutner
 
PDF
Whizlabs webinar - Deploying Portfolio Site with AWS Serverless
Dhaval Nagar
 
PDF
Writing less code with Serverless on AWS at AWS User Group Nairobi
Vadym Kazulkin
 
PDF
Beyond AEM Curl Commands
Cliffano Subagio
 
PDF
Spring Boot
Eberhard Wolff
 
PPT
AWS Simple Work Flow
Hometrack Australia
 
PDF
Java Serverless in Action - Voxxed Banff
David Delabassee
 
PDF
DevOps Toolbox: Infrastructure as code
sriram_rajan
 
PPTX
Expect the unexpected: Anticipate and prepare for failures in microservices b...
Bhakti Mehta
 
Adopting Java for the Serverless world at Serverless Meetup Singapore
Vadym Kazulkin
 
FaaS or not to FaaS. Visible and invisible benefits of the Serverless paradig...
Vadym Kazulkin
 
Writing less code with Serverless on AWS at FrOSCon 2021
Vadym Kazulkin
 
#JavaOne What's in an object?
Charlie Gracie
 
Iguazú: A Long-Running Job Scheduler using Docker and Mesos
Colleen Lee
 
Serverless Java Challenges & Triumphs
David Delabassee
 
JVM Support for Multitenant Applications - Steve Poole (IBM)
jaxLondonConference
 
Immutable Infrastructure: the new App Deployment
Axel Fontaine
 
Java in the Cloud : PaaS Platforms in Comparison
Eberhard Wolff
 
ReST Vs SOA(P) ... Yawn
ozten
 
JavaOne 2015: 12 Factor App
Joe Kutner
 
Whizlabs webinar - Deploying Portfolio Site with AWS Serverless
Dhaval Nagar
 
Writing less code with Serverless on AWS at AWS User Group Nairobi
Vadym Kazulkin
 
Beyond AEM Curl Commands
Cliffano Subagio
 
Spring Boot
Eberhard Wolff
 
AWS Simple Work Flow
Hometrack Australia
 
Java Serverless in Action - Voxxed Banff
David Delabassee
 
DevOps Toolbox: Infrastructure as code
sriram_rajan
 
Expect the unexpected: Anticipate and prepare for failures in microservices b...
Bhakti Mehta
 

Similar to 10 Typical Java Problems in the Wild (20)

PDF
10 Typical Problems in Enterprise Java Applications
Eberhard Wolff
 
PDF
10 Typical Enterprise Java Problems
Eberhard Wolff
 
PDF
MongoDB for Java Devs with Spring Data - MongoPhilly 2011
MongoDB
 
PDF
MongoDB for Java Developers with Spring Data
Chris Richardson
 
KEY
A Walking Tour of (almost) all of Springdom
Joshua Long
 
PDF
Simple Pure Java
Anton Keks
 
PPT
Spring and Cloud Foundry; a Marriage Made in Heaven
Joshua Long
 
PDF
Introducing spring
Ernesto Hernández Rodríguez
 
KEY
Spring in the Cloud - using Spring with Cloud Foundry
Joshua Long
 
PDF
Java EE 與 雲端運算的展望
javatwo2011
 
PDF
Lo nuevo en Spring 3.0
David Motta Baldarrago
 
PDF
Questioning the status quo
Ivano Pagano
 
PDF
Overview of Grails Object Relational Mapping (GORM)
Chris Richardson
 
PPT
Java overview the piramide of success
Artem Bilan
 
PDF
The spring 32 update final
Joshua Long
 
KEY
Beyond OSGi Software Architecture
Jeroen van Grondelle
 
PDF
CDI and Weld
Redpill Linpro
 
PPT
Spring - a framework written by developers
MarcioSoaresPereira1
 
KEY
Enterprise Java Web Application Frameworks Sample Stack Implementation
Mert Çalışkan
 
PDF
Spring Mvc
ifnu bima
 
10 Typical Problems in Enterprise Java Applications
Eberhard Wolff
 
10 Typical Enterprise Java Problems
Eberhard Wolff
 
MongoDB for Java Devs with Spring Data - MongoPhilly 2011
MongoDB
 
MongoDB for Java Developers with Spring Data
Chris Richardson
 
A Walking Tour of (almost) all of Springdom
Joshua Long
 
Simple Pure Java
Anton Keks
 
Spring and Cloud Foundry; a Marriage Made in Heaven
Joshua Long
 
Introducing spring
Ernesto Hernández Rodríguez
 
Spring in the Cloud - using Spring with Cloud Foundry
Joshua Long
 
Java EE 與 雲端運算的展望
javatwo2011
 
Lo nuevo en Spring 3.0
David Motta Baldarrago
 
Questioning the status quo
Ivano Pagano
 
Overview of Grails Object Relational Mapping (GORM)
Chris Richardson
 
Java overview the piramide of success
Artem Bilan
 
The spring 32 update final
Joshua Long
 
Beyond OSGi Software Architecture
Jeroen van Grondelle
 
CDI and Weld
Redpill Linpro
 
Spring - a framework written by developers
MarcioSoaresPereira1
 
Enterprise Java Web Application Frameworks Sample Stack Implementation
Mert Çalışkan
 
Spring Mvc
ifnu bima
 
Ad

More from Eberhard Wolff (20)

PDF
Architectures and Alternatives
Eberhard Wolff
 
PDF
Beyond Microservices
Eberhard Wolff
 
PDF
The Frontiers of Continuous Delivery
Eberhard Wolff
 
PDF
Four Times Microservices - REST, Kubernetes, UI Integration, Async
Eberhard Wolff
 
PDF
Microservices - not just with Java
Eberhard Wolff
 
PDF
Deployment - Done Right!
Eberhard Wolff
 
PDF
Data Architecture not Just for Microservices
Eberhard Wolff
 
PDF
How to Split Your System into Microservices
Eberhard Wolff
 
PDF
Microservices and Self-contained System to Scale Agile
Eberhard Wolff
 
PDF
How Small Can Java Microservices Be?
Eberhard Wolff
 
PDF
Data Architecturen Not Just for Microservices
Eberhard Wolff
 
PDF
Microservices: Redundancy=Maintainability
Eberhard Wolff
 
PDF
Self-contained Systems: A Different Approach to Microservices
Eberhard Wolff
 
PDF
Microservices Technology Stack
Eberhard Wolff
 
PDF
Software Architecture for Innovation
Eberhard Wolff
 
PDF
Five (easy?) Steps Towards Continuous Delivery
Eberhard Wolff
 
PDF
Nanoservices and Microservices with Java
Eberhard Wolff
 
PDF
Microservices: Architecture to Support Agile
Eberhard Wolff
 
PDF
Microservices: Architecture to scale Agile
Eberhard Wolff
 
PDF
Microservices, DevOps, Continuous Delivery – More Than Three Buzzwords
Eberhard Wolff
 
Architectures and Alternatives
Eberhard Wolff
 
Beyond Microservices
Eberhard Wolff
 
The Frontiers of Continuous Delivery
Eberhard Wolff
 
Four Times Microservices - REST, Kubernetes, UI Integration, Async
Eberhard Wolff
 
Microservices - not just with Java
Eberhard Wolff
 
Deployment - Done Right!
Eberhard Wolff
 
Data Architecture not Just for Microservices
Eberhard Wolff
 
How to Split Your System into Microservices
Eberhard Wolff
 
Microservices and Self-contained System to Scale Agile
Eberhard Wolff
 
How Small Can Java Microservices Be?
Eberhard Wolff
 
Data Architecturen Not Just for Microservices
Eberhard Wolff
 
Microservices: Redundancy=Maintainability
Eberhard Wolff
 
Self-contained Systems: A Different Approach to Microservices
Eberhard Wolff
 
Microservices Technology Stack
Eberhard Wolff
 
Software Architecture for Innovation
Eberhard Wolff
 
Five (easy?) Steps Towards Continuous Delivery
Eberhard Wolff
 
Nanoservices and Microservices with Java
Eberhard Wolff
 
Microservices: Architecture to Support Agile
Eberhard Wolff
 
Microservices: Architecture to scale Agile
Eberhard Wolff
 
Microservices, DevOps, Continuous Delivery – More Than Three Buzzwords
Eberhard Wolff
 
Ad

Recently uploaded (20)

PPTX
Building a Production-Ready Barts Health Secure Data Environment Tooling, Acc...
Barts Health
 
PDF
Shuen Mei Parth Sharma Boost Productivity, Innovation and Efficiency wit...
AWS Chicago
 
PDF
NewMind AI Journal - Weekly Chronicles - July'25 Week II
NewMind AI
 
PDF
Sustainable and comertially viable mining process.pdf
Avijit Kumar Roy
 
PDF
Upskill to Agentic Automation 2025 - Kickoff Meeting
DianaGray10
 
PPTX
Earn Agentblazer Status with Slack Community Patna.pptx
SanjeetMishra29
 
PDF
Novus-Safe Pro: Brochure-What is Novus Safe Pro?.pdf
Novus Hi-Tech
 
PDF
Upgrading to z_OS V2R4 Part 01 of 02.pdf
Flavio787771
 
PDF
HR agent at Mediq: Lessons learned on Agent Builder & Maestro by Tacstone Tec...
UiPathCommunity
 
PPT
Interview paper part 3, It is based on Interview Prep
SoumyadeepGhosh39
 
PDF
Wojciech Ciemski for Top Cyber News MAGAZINE. June 2025
Dr. Ludmila Morozova-Buss
 
PDF
HydITEx corporation Booklet 2025 English
Георгий Феодориди
 
PDF
Log-Based Anomaly Detection: Enhancing System Reliability with Machine Learning
Mohammed BEKKOUCHE
 
PDF
Meetup Kickoff & Welcome - Rohit Yadav, CSIUG Chairman
ShapeBlue
 
PDF
Arcee AI - building and working with small language models (06/25)
Julien SIMON
 
PDF
Impact of IEEE Computer Society in Advancing Emerging Technologies including ...
Hironori Washizaki
 
PPTX
UI5Con 2025 - Get to Know Your UI5 Tooling
Wouter Lemaire
 
PDF
Why Orbit Edge Tech is a Top Next JS Development Company in 2025
mahendraalaska08
 
PDF
2025-07-15 EMEA Volledig Inzicht Dutch Webinar
ThousandEyes
 
PPTX
✨Unleashing Collaboration: Salesforce Channels & Community Power in Patna!✨
SanjeetMishra29
 
Building a Production-Ready Barts Health Secure Data Environment Tooling, Acc...
Barts Health
 
Shuen Mei Parth Sharma Boost Productivity, Innovation and Efficiency wit...
AWS Chicago
 
NewMind AI Journal - Weekly Chronicles - July'25 Week II
NewMind AI
 
Sustainable and comertially viable mining process.pdf
Avijit Kumar Roy
 
Upskill to Agentic Automation 2025 - Kickoff Meeting
DianaGray10
 
Earn Agentblazer Status with Slack Community Patna.pptx
SanjeetMishra29
 
Novus-Safe Pro: Brochure-What is Novus Safe Pro?.pdf
Novus Hi-Tech
 
Upgrading to z_OS V2R4 Part 01 of 02.pdf
Flavio787771
 
HR agent at Mediq: Lessons learned on Agent Builder & Maestro by Tacstone Tec...
UiPathCommunity
 
Interview paper part 3, It is based on Interview Prep
SoumyadeepGhosh39
 
Wojciech Ciemski for Top Cyber News MAGAZINE. June 2025
Dr. Ludmila Morozova-Buss
 
HydITEx corporation Booklet 2025 English
Георгий Феодориди
 
Log-Based Anomaly Detection: Enhancing System Reliability with Machine Learning
Mohammed BEKKOUCHE
 
Meetup Kickoff & Welcome - Rohit Yadav, CSIUG Chairman
ShapeBlue
 
Arcee AI - building and working with small language models (06/25)
Julien SIMON
 
Impact of IEEE Computer Society in Advancing Emerging Technologies including ...
Hironori Washizaki
 
UI5Con 2025 - Get to Know Your UI5 Tooling
Wouter Lemaire
 
Why Orbit Edge Tech is a Top Next JS Development Company in 2025
mahendraalaska08
 
2025-07-15 EMEA Volledig Inzicht Dutch Webinar
ThousandEyes
 
✨Unleashing Collaboration: Salesforce Channels & Community Power in Patna!✨
SanjeetMishra29
 

10 Typical Java Problems in the Wild

  • 1. Typical Java Problems in the Wild Eberhard Wolff SpringSource Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
  • 2. SpringSource Solution Unifying the Application Lifecycle: from Developer to Datacenter High Productivity Tools Lean Powerful Runtimes Spring Enterprise SpringSource tc Server Groovy and Grails Build   Run   SpringSource dm Server SpringSource Tool Suite SpringSource http Server Manage   Application Infrastructure Management SpringSource Hyperic HQ SpringSource Hyperic IQ Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 2
  • 3. About me •  Regional Director German speaking region and Principal Consultant •  Author of several articles and books •  First German Spring book •  Speaker at national and international conferences •  [email protected] Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 3
  • 4. Why this talk? •  I do a lot of reviews •  There are some common problems you see over and over again •  So: Here are 10 –  …not necessarily the most common –  ...but certainly with severe effects Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 4
  • 5. #1 public class Service { private CustomerDao customerDao; private PlatformTransactionManager transactionManager; public void performSomeService() { TransactionStatus transactionStatus = transactionManager .getTransaction(new DefaultTransactionDefinition()); customerDao.doSomething(); customerDao.doSomethingElse(); transactionManager.commit(transactionStatus); } }   Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 5
  • 6. #1 Weak Transaction Handling public class Service { private CustomerDao customerDao; private PlatformTransactionManager transactionManager; public void performSomeService() { TransactionStatus transactionStatus = transactionManager .getTransaction(new DefaultTransactionDefinition()); customerDao.doSomething(); customerDao.doSomethingElse(); transactionManager.commit(transactionStatus); } •  What happens to the transaction if the DAO }   throws an exception? •  We might never learn... •  ...or learn the hard way Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 6
  • 7. Weak Transaction Handling: Impact •  Hard to detect, has effects only if exception is thrown •  …but then it can lead to wired behavior and data loss etc. •  That is why you are using transactions in the first place Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 7
  • 8. Solution •  Declarative transactions public class Service { private CustomerDao customerDao; @Transactional public void performSomeService() { customerDao.doSomething(); customerDao.doSomethingElse(); } }   •  Exception is caught, transaction is rolled back (if it is a RuntimeException) •  Exception handling can be customized Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 8
  • 9. A different solution… public void performSomeService() { TransactionTemplate template = new TransactionTemplate( transactionManager); template.execute(new TransactionCallback() { public Object doInTransaction(TransactionStatus status) { customerDao.doSomething(); customerDao.doSomethingElse(); return null; } }); } •  Allows for multiple transactions in one method •  More code – more control •  Rather seldom really needed Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 9
  • 10. #2 Exception Design •  Get all the details from a system exception! •  Each layer must only use its own exceptions! •  Exceptions have to be checked – then they must be handled and the code is more secure. •  Sounds reasonably, doesn't it? Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 10
  • 11. public class OrderDao { public void createOrder(Order order) throws SQLException { // some ugly JDBC code // that I am not going to show } } public class SomeService { public void performService() Get all the details! throws ServiceException { Use checked try { exceptions! orderDao.createOrder(new Order()); } catch (SQLException e) { throw new ServiceException(e); Service must only } throw } ServiceException! } public class SomeController { public void handleWebRequest() { try { What am I supposed to do someService.performService(); now? } catch (Exception e) { No real logging e.printStackTrace(); } And I don t care about the } specific ServiceException } Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 11
  • 12. Impact •  Lots of useless exception handling code •  Lots of exception types without specific handling of that type •  In the end all you get is a log entry and lots of code •  And what should the developer do? –  All he knows "Something went wrong" –  Does not really care and can not really handle it Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 12
  • 13. Why is this commonplace? •  Very few languages have checked exceptions (Java - CLU and Modula-3 had similar concepts) •  Checked exception force developers to handle an exception – very rigid •  How common is it that you can really handle an exception? •  Checked exceptions are perceived to be more secure •  Checked exceptions are overused – also in Java APIs •  In many cases there are even no exception concepts in projects Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 13
  • 14. Solution •  Use more unchecked exceptions aka RuntimeExceptions •  Remember: A lot of languages offer only unchecked exceptions •  Avoid wrap-and-rethrow – it does not add value •  Don't write too many exception classes – they often don't add value •  A specific exception classes is only useful if that exception should be handled differently Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 14
  • 15. Solution public class OrderDao { public void createOrder(Order order) { jdbcTemplate.update("INSERT INTO ORDER ..."); } } public class SomeService { Where is the public void performService() { exception } orderDao.createOrder(new Order()); handling? } public class SomeController { public void handleWebRequest() { someService.performService(); } } Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 15
  • 16. AOP in one Slide @Aspect public class AnAspect { // do something before the method hello // is executed @Before("execution(void hello())") public void doSomething() { } // in a specific class // that ends in Service in any package or subpackage @Before("execution(* com.springsource.MyService.hello())") public void doSomethingElse2() { } // do something before any method in a class // that ends in Service in any package or subpackage @Before("execution(* *..*Service.*(..))") public void doSomethingElse2() { } 16 Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
  • 17. Aspect for Logging @Aspect public class ExceptionLogging { @AfterThrowing(value="execution(* *..Service*.*(..))", throwing="ex") public void logRuntimeException(RuntimeException ex) { System.out.println(ex); } } •  Logs every exception – 100% guaranteed! Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 17
  • 18. Handle only cases you really want to handle public class SomeService { public void performService() { try { orderDao.createOrder(new Order()); } catch (OptimisticLockingFailureException ex) { orderDao.createOrder(new Order()); } } } •  Everything else will be handled somewhere else •  Can handle specific error conditions using catch with specific types Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 18
  • 19. Generic Exception Handling public class MyHandlerExceptionResolver implements HandlerExceptionResolver { public ModelAndView resolveException( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { return new ModelAndView("exceptionView", "exception", ex); } } •  In the web layer •  Handle all the (Runtime)Exceptions not handled elsewhere Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 19
  • 20. #3 Exception Handling public void someMethod() { try { } catch (Exception ex) { Exception is not logged ex.printStackTrace(); just written to stdout } operations might not notice try { } catch (Exception ex) { // should never happen Exception is swallowed } } Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 20
  • 21. Impact •  Related to #2: If you have excessive checked exceptions this will occur more often •  …as developers are forced to handle exceptions they can't really handle •  In the end you just get a message on the console and the application continues. •  All kinds of wired behavior •  i.e. exception is swallowed •  You will have a hard time finding problems in the code •  Potentially a huge problem – so worth its own explanation Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 21
  • 22. Solution •  At least log exceptions •  Rethink: Is it really OK to continue in this situation? If not - don't handle the exception. Might be better to let a generic handler handle it. •  Introduce generic handling at least for RuntimeException (AOP, web front end, etc) •  Enforce the logging using Findbugs, PMD etc. •  And: Improve the public void someMethod() { exception design (#2) try { } catch (Exception ex) { log.error(ex); } } Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 22
  • 23. #4 •  Table of packages and the relations between them •  Everything in red is part of a cycle •  This is actual code from an Open Source project Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 23
  • 24. Dependency Graph •  Overview Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 24
  • 25. Dependency Graph •  Just a small part •  Red line show circular references Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 25
  • 26. What is Architecture? •  Architecture is the decomposition of systems in parts •  No large or complex parts •  No cyclic dependencies Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 26
  • 27. Normal Dependencies •  B dependes on A, i.e. it uses classe, methods etc. •  Changes in A impact B Component A •  Changes in B do not impact A Component B Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 27
  • 28. Cyclic Dependency •  B depends on A and A on B •  Changes in A impact B •  Changes in B impact A Component A •  A and B can only be changed as one unit •  …even though they should be two separate units Component B Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 28
  • 29. Bigger cyclic dependencies Component A Component B Component C Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 29
  • 30. #4: Architecture Mess •  This is effectively just one big unstructured pile of mud •  Maintenance will be hard •  Concurrent development will be hard •  Changes will have unforeseeable results Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 30
  • 31. Solution •  Very hard if you have this state •  Therefore: Manage dependencies from the start •  Otherwise you are looking at a major restructuring of your application •  …which might not be worth it •  Effort for restructuring pays off by lower effort for maintenance •  …might take a long time to amortize •  Throwing away + redevelopment means that you have to migrate to a new solution -> complex and risky Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 31
  • 32. #5 public class ServiceAdaptor { public void performService(OrderDTO orderDTO) { logger.trace("Entering performService"); try { if (orderDTO == null) { throw new NullPointerException("order must not be null"); } if (youAreNotAllowedToDoThis()) { throw new IllegalStateException( "You are not allowed to call this!"); } OrderEntity order = new OrderEntity(); order.setCustomer(orderDTO.getCustomer()); // ... service.performService(order); commandLog.add(new Command("performService", service,order)); } finally { logger.trace("Leaving performanceService"); } } } 32 Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
  • 33. #5: Adaptor Layer •  Adds to a service: –  Security –  Tracing –  Check for null arguments –  Log for all commands (auditing, replay…) –  Conversion from DTO to internal representation •  Lots of boilerplate for each service •  Changes to tracing etc. hard: lots of methods to change Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 33
  • 34. Solution: Tracing with AOP •  …or use Spring's predefined TraceInterceptor, DebugInterceptor etc. @Aspect public class TraceAspect { @Before("execution(* *..*Service.*(..))") public void traceBegin(JoinPoint joinPoint) { System.out.println("entering method " + joinPoint.getSignature().getName()); } @After("execution(* *..*Service.*(..))") public void traceEnd(JoinPoint joinPoint) { System.out.println("leaving method " + joinPoint.getSignature().getName()); } } Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 34
  • 35. Solution: Null Checks with AOP @Aspect public class NullChecker { @Before("execution(* *..*Service.*(..))") public void checkForNull(JoinPoint joinPoint) { for (Object arg : joinPoint.getArgs()) { if (arg==null) { throw new NullPointerException("Argument was null!"); } } } } •  Security can be handled with Spring Security or AOP •  Command log also possible Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 35
  • 36. What is left… public class ServiceAdaptor { public void performService(OrderDTO orderDTO) { OrderEntity order = new OrderEntity(); order.setCustomer(orderDTO.getCustomer()); // ... service.performService(order); } } •  You should probably switch to Dozer •  http://dozer.sf.net •  Can externalize mapping rules •  i.e. the layer can be more or less eliminated •  Everything (mapping, security, tracing…) is now implemented in one place (DRY) •  Often services just delegate to DAOs – same issue Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 36
  • 37. #6: No DAO public class SomeService { @PersistenceContext private EntityManager entityManager; public void performSomeService() { List<Order> list = entityManager. createQuery("select o from Order").getResultList(); for (Order o : list) { // ... if (o.shouldBeProcessed()) { o.process(); } } } } •  We don't need to abstract away from JPA – it's a standard, right? Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 37
  • 38. #6: Even worse public class SomeServiceJdbc { private OrderDao someDoa; public void performSomeService() throws SQLException { ResultSet rs = someDoa.getOrders(); while (rs.next()) { //... } } } •  Service depends on JDBC •  …and throws SQLException •  Persistence visible in the service layer and beyond Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 38
  • 39. Impact •  Code is impossible to test without a database •  …so no real unit tests possible •  Service depends on persistence – cannot be ported •  How do you add data dependent security? •  No structure Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 39
  • 40. Solution •  Use a DAO (Data Access Object) –  Separate persistence layer –  Technical motivation •  …or a Repository –  Interface to existing objects –  Non technical motivation: Domain Driven Design, Eric Evans •  Basically the same thing Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 40
  • 41. Solution public class SomeServiceDAO { public void performSomeService() { List<Order> list = orderDao.getAllOrders(); for (Order o : list) { // ... if (o.shouldBeProcessed()) { o.process(); } } } } •  Clear separation •  Tests easy Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 41
  • 42. Solution: Test public class ServiceTest { @Test public void testService() { SomeService someService = new SomeService(); someService.setOrderDao(new OrderDao() { public List<Order> getAllOrders() { List<Order> result = new ArrayList<Order>(); return result; } }); someService.performSomeService(); Assert.assertEquals(expected, result); } } Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 42
  • 43. #7 •  No Tests Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 43
  • 44. #7 Or bad tests •  No asserts public class MyUnitTest { private Service service = new Service(); •  System.out: results are @Test checked public void testService() { manually Order order = new Order(); service.performService(order); •  Tests commented System.out.print(order.isProcessed()); out: They did not } run any more and were not // @Test // public void testOrderCreated() { fixed // Order order = new Order(); •  No mocks, so no // service.createOrder(order); real Unit Tests // } •  No negative } cases Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 44
  • 45. Impact •  Code is not properly tested •  Probably low quality – testable code is usually better designed •  Code is hard to change: How can you know the change broke nothing? •  Design might be bad: Testable usually mean better quality Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 45
  • 46. Solution •  Write proper Unit Tests! public class MyProperUnitTest { private Service service = new Service(); @Test public void testService() { Order order = new Order(); service.performService(order); Assert.assertTrue(order.isProcessed()); } @Test(expected=IllegalArgumentException.class) public void testServiceException() { Order order = new BuggyOrder(); service.performService(order); } } Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 46
  • 47. Wow, that was easy! Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited.
  • 48. The real problem… •  The idea of Unit tests is over 10 years old •  Not too many programmer actually do real unit tests •  Even though it should greatly increased trust and confidence in your code •  …and make you much more relaxed and therefore improve quality of life… •  Original paper: Gamma, Beck: "Test Infected – Programmers Love Writing Tests" •  Yeah, right. Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 48
  • 49. BTW Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 49
  • 50. Solution •  Educate –  Show how to write Unit Test –  Show how to build Mocks –  Show aggressive Testing –  Show Test First / Test Driven Development •  Coach / Review •  Integrate in automatic build •  Later on: Add integration testing, functional testing, FIT, Fitnesse etc. •  …or even start with these Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 50
  • 51. What does not really work •  Measuring code coverage –  Can be sabotaged public class MyProperUnitTest { private Service service = new Service(); @Test public void testService() { Order order = new Order(); service.performService(order); } } •  Let developers just write tests without education –  How should they know how to test properly? –  Test driven development is not obvious Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 51
  • 52. #8: Creating SQL statements public class OrderDAO { private SimpleJdbcTemplate simpleJdbcTemplate; public List<Order> findOrderByCustomer(String customer) { return simpleJdbcTemplate.query( "SELECT * FROM T_ORDER WHERE name='" + customer + "'", new OrderRowMapper()); } } Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 52
  • 53. Impact •  Performance is bad: –  Statement is parsed every time –  Execution plan is re created etc. Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 53
  • 54. Impact •  Even worse: SQL injection •  Pass in a' or 't'='t' •  Better yet: a'; DROP TABLE T_ORDER; SELECT * FROM ANOTHER_TABLE public class OrderDAO { private SimpleJdbcTemplate simpleJdbcTemplate; public List<Order> findOrderByCustomer(String customer) { return simpleJdbcTemplate.query( "SELECT * FROM T_ORDER WHERE name='" + customer + "'", new OrderRowMapper()); } } Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 54
  • 55. Solution public class OrderDAO { private SimpleJdbcTemplate simpleJdbcTemplate; public List<Order> findOrderByCustomer(String customer) { return simpleJdbcTemplate.query( "SELECT * FROM T_ORDER WHERE name=?", new OrderRowMapper(), customer); } } •  … and white list the allowed characters in name Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 55
  • 56. #9 •  "What about Performance?" •  "Well, we figured the response time should be 2s." •  "How many request do you expect?" •  "…" •  "What kind of requests do you expect?" •  "..." Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 56
  • 57. #9 •  The software is happily in the final functional test •  Then the performance test start •  Performance is too bad to be accepted •  You can hardly do anything: –  Changes might introduce functional errors –  Too late for bigger changes anyway •  The results might be wrong if the performance test is on different hardware than production. •  You can't test on production hardware: Too expensive. Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 57
  • 58. Impact •  You have to get bigger hardware –  Prerequisite: The software is scalable •  Worse: You can't go into production Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 58
  • 59. Solution •  Get information about the number of requests, expected types of requests, acceptable response times •  Pro active performance management: –  Estimate the performance before implementation –  …by estimating the slow operations (access to other systems, to the database etc) –  Measure performance of these operation in production •  Practice performance measurements and optimizations before performance test Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 59
  • 60. #10 public class SomeService { private Map cache = new HashMap(); private Customer customer; public Order performService(int i) { if (cache.containsKey(i)) { return cache.get(i); } Order result; customer = null; cache.put(i, result); return result; } } Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 60
  • 61. #10 Multiple threads, memory leaks public class SomeService { The cache is filled – private Map<Integer,Order> cache = is it ever emptied? new HashMap<Integer, Order>(); private Customer customer; HashMap is not public Order performService(int i) { threadsafe if (cache.containsKey(i)) { return (Ordercache.get(i); customer is an } instance variable – Order result; multi threading will customer = null; ... be a problem cache.put(i, result); return result; } } Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 61
  • 62. Impact •  System working in small tests •  In particular Unit tests work •  But production fails •  …probably hard to analyze / fix •  Almost only by code reviews •  …or extensive debugging using thread dumps Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 62
  • 63. Solution public class SomeServiceSolution { •  Use WeakHashMap to avoid memory leaks private Map<Integer, Order> cache = new WeakHashMap<Integer, Order>(); •  Synchronize •  Prefer local variables public Order performService(int i) { synchronized (cache) { •  Usually services can if (cache.containsKey(i)) { store most things in return cache.get(i); } local variables } Order result = null; Customer customer = null; synchronized (cache) { cache.put(i, result); } return result; } } Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 63
  • 64. Solution •  Also consider ConcurrentHashMap •  or http://sourceforge.net/projects/high-scale-lib Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 64
  • 65. Sum Up •  #1 Weak Transaction •  #8 Creating SQL Handling queries using String •  #2 Exception Design concatenation •  #3 Exception Handling •  #9 No performance •  #4 Architecture Mess management •  #10 Multiple threads / •  #5 Adaptor Layer memory leaks •  #6 No DAO •  #7 No or bad tests Copyright 2009 SpringSource. Copying, publishing or distributing without express written permission is prohibited. 65