Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Migrating a JSF-Based Web Application from Spring 3 to Java EE 7 and CDI

Migrating a JSF-Based Web Application from Spring 3 to Java EE 7 and CDI

This talk is a detailed case study about the migration of a JSF-based web application from Spring 3 to Java EE 7 and CDI. It is presented at the JavaOne 2014 conference.

At first sight this didn’t seem to be too difficult. Both technologies are based on similar concepts and provide similar mechanisms for dependency injection (DI). So migrating pure annotation based bean wiring from Spring to CDI was obvious and straight forward.

But the deeper we looked into the source code the more Spring specific code we found with no direct and easy mapping in neither of JEE7, EJB3 or CDI available. Some of the problems and challenges we were confronted with were:
- How to migrate XML based bean wirings?
- How to migrate FactoryBeans?
- How to migrate AspectJ based AOP proxies?
- How to implement Spring profiles for environment based wiring?
- How to implement custom bean scopes?
- How to implement custom Spring XML schema notations and wiring?
- How to migrate code that is built against Spring APIs?
- How to migrate unit test based on Spring Test?

To answer these questions the talk will present the patterns and strategies used to map, transform and migrate the different concepts from Spring 3 to JEE7with CDI. The talk will discuss the changes and implications of the migration on the system’s architecture.

M.-Leander Reimer

October 02, 2014
Tweet

More Decks by M.-Leander Reimer

Other Decks in Programming

Transcript

  1. 2 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer This talk will … Give a brief overview of the system’s architecture Try to explain the rationale behind the migration Outline differences and similarities between both technologies Show patterns and strategies used during the migration to translate the different concepts Discuss implications on the system’s architecture Highlight problems, challenges and lessons learned
  2. 3 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer A <<Application Cluster>> AIR Loader Mechanic A <<System>> AIR Central A <<Subsystem>> Maintenance A <<System>> AIR Repository I <<Subsystem>> Apache Solr A <<Client>> AIR Client I <<Subsystem>> .NET WPF A <<Subsystem>> Solr Extensions A <<Subsystem>> Defects A <<Subsystem>> Flat Rates A <<Subsystem>> Service Bulletins Service Technician A <<Ext. System>> 3rd Party Application A <<Subsystem>> AIR Fork DLL A <<Subsystem>> AIR Call DLL Launch I <<Subsystem>> Spring Framework I <<Subsystem>> JEE 5 A <<System>> AIR Control I <<Subsystem>> Jenkins A <<Subsystem>> Documents A <<Subsystem>> Vehicles A <<Subsystem>> Measures Backend Databases and Systems A <<Subsystem>> Repair Overview A <<Subsystem>> Masterdata A <<Subsystem>> JSF Web UI A <<Subsystem>> REST API Independent Workshop A <<Client>> Browser Search and Display A <<Ext. System>> 3rd Party iOS App A <<Subsystem>> AIR iOS Lib A <<Subsystem>> Defects A <<Subsystem>> Flat Rates A <<Subsystem>> Service Bulletins I <<Subsystem>> Spring Framework A <<Subsystem>> Documents A <<Subsystem>> Parts A <<Subsystem>> WS Clients A <<Subsystem>> File Storage A <<Subsystem>> Solr Access A <<Subsystem>> Protocoll A <<Subsystem>> Watchlist A <<Subsystem>> Masterdata A <<Subsystem>> Retrofits AIR DB Document Storage A <<Ext. System>> AIR Bus I <<Ext. System>> Backend Systems Query A <<Subsystem>> Vehicles Execute Load 400 GB Solr Index A <<Subsystem>> Maintenance
  3. 4 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Why would you want to migrate a stable and running system? The short answer: IT governance. The long answer: JEE now provides the same functionality and is a standard Easy and cost efficient migration to future JEE versions Lower costs for web infrastructure and application operations Easy application maintenance by *-shore companies No additional vendor support required, no additional costs
  4. 5 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer
  5. 6 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Annotation based wiring of components using constructor injection
  6. 7 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Usage of custom Spring annotations for more expressiveness
  7. 8 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer XML based wiring of components for Spring specific beans and more complex components
  8. 9 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer FactoryBeans to build bean instances with regular Java code
  9. 10 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Usage of property placeholder support to inject configuration values
  10. 11 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Implementation of AspectJ based proxies for cross cutting concerns
  11. 12 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Programmatic bean lookup using the Registry pattern and the ApplicationContext
  12. 13 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Usage of Spring bean profiles for environment specific bean configurations
  13. 14 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Spring XML namespaces for syntactic sugar
  14. 15 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Unit and module tests heavily use and rely on the Spring Testing framework
  15. 16 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer We were faced with more questions than we had answers for How to migrate basic annotation based bean wiring? How to migrate XML based bean wiring and factory beans? How to migrate Spring property placeholder support? How to migrate AspectJ based AOP proxies? How to migrate programmatic bean lookups? How to migrate Spring bean profiles? How to migrate custom Spring XML namespaces? How to migrate code that is built against Spring APIs? How to migrate unit test based on Spring Test?
  16. 17 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer
  17. 18 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer
  18. 19 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer All new Java EE 7 Maven Coordinates
  19. 20 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Individual Maven modules as main unit of migration Replace Spring annotations and wirings with CDI equivalent Replace XML context definitions with beans.xml Optional: adjust components to benefit from CDI Find and/or build substitutes for Spring specific features Adjust unit and integration tests
  20. 21 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Basic Spring to CDI annotation migration is straightforward, with subtle differences Caution: Spring and CDI have a different default scope! CDI uses client proxies per default (except for @Dependent), in Spring you have to do this explicitly. This might influence your wiring style. Be careful with final. Spring Annotation CDI Annotation @Component(„myBean“)  @Named(„myBean“) @Scope(„singleton“)  @ApplicationScoped @Scope(„prototype“)  @Dependent @Scope(„request“)  @RequestScoped @Scope(„session“)  @SessionScoped @Autowired  @Inject Default Default
  21. 22 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Both technologies support @Qualifier to distinguish various implementations Tip: do not use @Named to qualify your components in CDI, use custom @Qualifier annotations instead.
  22. 23 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer @Stereotype is the CDI equivalent to custom @Component annotations Tip: check the @Target annotation of the CDI stereotype, and include METHOD so it can be applied to @Produces methods.
  23. 24 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Migrate *-components.xml to beans.xml Tip: use CDI 1.1 bean-discovery-mode=„annotated“ as the equivalent to Spring‘s component scan.
  24. 25 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer XML based bean wiring as well as factory beans are migrated to Producer methods - Factory beans can also use dependency injection - Support for lifecycle - Constructor injection - Nested factory bean
  25. 26 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer XML based bean wiring as well as factory beans are migrated to Producer methods
  26. 27 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer There is no direct equivalent to Spring‘s @Value(„${some.property}“) annotation
  27. 28 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Property injection support for CDI using the DeltaSpike Configuration Mechanism Tip: have a look at Apache DeltaSpike before you start building your own custom CDI extensions for missing features.
  28. 29 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Migrating Spring AOP using @Interceptor and @InterceptorBinding annotations Activate aspects and auto proxy relevant beans Pointcut for all public methods in classes annotated with @Service Pointcut for all public methods in classes annotated with @Repository
  29. 30 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Migrating Spring AOP using @Interceptor and @InterceptorBinding annotations
  30. 31 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer The CDI way for programmatic bean lookup improved our code enormously BeanManager is the ~ equivalent to ApplicationContext Migrated ApplicationContextAware static registry class to use the BeanManager instead Advice: don‘t use BeanManager directly. It‘s too low level. Don‘t use a static registry either. Gruesome testability! Tip: if static access to contextual references is really required, use the DeltaSpike BeanProvider implementation.
  31. 32 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Are Alternatives the equivalent to Spring‘s bean definition profiles? Almost. Problem: Alternatives need to be activated in the bean.xml Not suitable for environment specific, dynamic activation. Use a CDI extension to veto annotated type if profile is not active. Alternative: Use the DeltaSpike ProjectStage mechanism.
  32. 33 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer The migration of our custom Spring XML namespaces seemed to be a challenge Create instance of type FiniteStateMachine with given ID as bean name Enum type definitions Create transition instance with given properties Bean lookup by name for action instance to execute
  33. 34 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Programmatic approach: combine Builder pattern with a producer method Used for named action bean lookup
  34. 35 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Improved approach: use a CDI extension to read XML files and create FSM beans Creates instances, uses the Builder from first approach
  35. 36 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Direct usage of simplified JMS 2.0 API instead of Spring‘s JmsTemplate Sending Receiving
  36. 37 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Replacing Spring‘s Testing Framework was painful and a lot of work SpringJUnit4ClassRunner  MockitoJUnitRunner This work really paid of Simplified unit tests with better isolation decreased execution time Different approaches and test runners for CDI tests available: Jglue CDI-Unit: @RunWith(CdiRunner.class) DeltaSpike Test-Control: @RunWith(CdiTestRunner.class) Arquillian: @RunWith(Arquillian.class) Testing a CDI enabled JAR in isolation is complex and laborious (or just didn‘t work)
  37. 38 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer And there was a lot more code to migrate Migrated Spring task execution and scheduling funtionality to @Async methods or JEE7 ManagedExecutorService The JPA persistence code migration went smoothly Migrated persistence.xml from JPA 1.0 to 2.1 Simple JPA unit tests using DBUnit for test data setup The JSF web layer migration was quite tedious Homogenize annotation usage: replaced Faces bean annotations with CDI equivalent (e.g. @ManagedBean  @Named) Removed Registry based lookup of service facade instances Migrated and simplified unit tests, this also improved test quality
  38. 39 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer 28 days and 300K LOC later …
  39. 40 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer 28 days and 300K LOC later … … we had the AIR Central web application fully migrated and running on Glassfish v4. Migration efforts were orders of magnitude lower than initially estimated and anticipated! The standalone AIR Loader applications were next to migrate: using CDI from Java SE, even more complex Spring XML namespace, comprehensive usage of Spring JDBC.
  40. 41 | JavaOne 2014 | Migrating a JSF-based web application

    from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer Lessons Learned and Resumé JEE7 and CDI have definitely caught up on Spring There was no Spring feature that could not be migrated Some convenience is still missing, but CDI provides lightweight and easy to use extension mechanisms, there is growing support from the Open Source community. Question and rethink established patterns and best practices More careful when using and binding to a specific framework