Slide 1

Slide 1 text

Migrating a JSF-based web application from Spring 3 to Java EE 7 and CDI Mario-Leander Reimer [email protected] QAware

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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?

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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.

Slide 23

Slide 23 text

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.

Slide 24

Slide 24 text

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.

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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.

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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.

Slide 32

Slide 32 text

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.

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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)

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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 …

Slide 40

Slide 40 text

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.

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

QUANTENSPRUNG DANK ANDERSDENKEN