Migrating a JSF-based web application from Spring 3 to Java EE 7 and CDI
Mario-Leander [email protected] QAware
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
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
ServiceTechnician
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 Databasesand Systems
A <<Subsystem>>
Repair Overview
A <<Subsystem>>
Masterdata
A <<Subsystem>>
JSF Web UI
A <<Subsystem>>
REST API
IndependentWorkshop
A <<Client>>
Browser Search andDisplay
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 DBDocument
Storage
A <<Ext. System>>
AIR Bus
I <<Ext. System>>
Backend Systems
Query
A <<Subsystem>>
Vehicles Execute
Load
400 GBSolr Index
A <<Subsystem>>
Maintenance
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 stableand 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
5 | JavaOne 2014 | Migrating a JSF-based web application from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer
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 usingconstructor injection
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 moreexpressiveness
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
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 withregular Java code
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 toinject configuration values
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 forcross cutting concerns
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
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 environmentspecific bean configurations
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
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
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 thanwe 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?
17 | JavaOne 2014 | Migrating a JSF-based web application from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer
18 | JavaOne 2014 | Migrating a JSF-based web application from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer
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
20 | JavaOne 2014 | Migrating a JSF-based web application from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer
Individual Maven modules asmain unit of migration
Replace Spring annotations andwirings with CDI equivalent
Replace XML context definitionswith beans.xml
Optional: adjust components tobenefit from CDI
Find and/or build substitutes forSpring specific features
Adjust unit and integration tests
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 migrationis 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
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 todistinguish various implementations
Tip: do not use @Named to qualify your components in CDI, usecustom @Qualifier annotations instead.
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 tocustom @Component annotations
Tip: check the @Target annotation of the CDI stereotype, and
include METHOD so it can be applied to @Produces methods.
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.
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 usedependency injection- Support for lifecycle
- Constructor injection- Nested factory bean
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
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
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 usingthe DeltaSpike Configuration Mechanism
Tip: have a look at Apache DeltaSpike before you start building
your own custom CDI extensions for missing features.
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 proxyrelevant beans
Pointcut for all publicmethods in classesannotated with @Service
Pointcut for all publicmethods in classesannotated with @Repository
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
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 touse 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.
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‘sbean 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.
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 withgiven ID as bean name
Enum type definitions
Create transition instancewith given properties
Bean lookup by name foraction instance to execute
34 | JavaOne 2014 | Migrating a JSF-based web application from Spring 3 to Java EE 7 and CDI | M.-Leander Reimer
Programmatic approach: combine Builderpattern with a producer method
Used for named actionbean lookup
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 extensionto read XML files and create FSM beans
Creates instances, uses theBuilder from first approach
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
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 ofSimplified 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 andlaborious (or just didn‘t work)
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 smoothlyMigrated 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 tediousHomogenize annotation usage: replaced Faces bean annotations withCDI equivalent (e.g. @ManagedBean @Named)
Removed Registry based lookup of service facade instances
Migrated and simplified unit tests, this also improved test quality
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 …
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 andrunning on Glassfish v4.
Migration efforts were orders of magnitude lower than initiallyestimated 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.
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, butCDI 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
QUANTENSPRUNG DANK ANDERSDENKEN