Sharing Our Passion for Technology
& Continuous Learning
Musings of a SpringOne 2009 Attendee - Day 3
Session: Agile Architecture - Technologies and Patterns - Kirk Knoernschild
Some of the questions this session set out to attempt to answer were
- What is architecture?
- What defines architecture?
- What are architectural decisions?
- Is architecture a forward only decision?
Several definitions of Architecture were quoted from prior literature. Such as architecture being the the shared understanding of the system being built. Shared understanding between a group of people who need to communicate about it -- developers and architects, or technical and management etc.
Lean principles are you delay the decision till it is required and till after you have enough information to make an effective decision. Does this mean you should not make decisions based on incomplete information? I disagree on the "effective decision". How do you even know what is effective decision? Something that is effective today more than likely will not be effective tomorrow. The world we live in is a naturally changing world. You delay the decision till the last responsible minute. But when you have to make the decision you do it based on the best available information at that point.
The goals of architecture were then discussed. I thought this was a very insightful analysis. We were first shown how the impact of change and the cost of change influence architecture and design. High impact and high cost of change require architecture and design. If the change has high impact, but low cost then architecture may not be as important as long as you have measures to mitigate the change such as unit and functional tests. Or if the change has low impact but high cost, if you are prepared to absorb the cost, then architecture may not be as important either though this is more unlikely. The end goal of architecture is to reduce the impact and cost of change.
Are flexibility and complexity opposing goals? Higher flexibility introduces higher complexity. It goes back to choosing your battles. If the impact of change is not significant then it doesn't have to be flexible and thus not complex. So the question is which parts of the system needs to be flexible.
The release-reuse equivalence principle is that the unit of release is the unit of reuse. We see this in daily practice. And consequently reuse fits nicely into modularity. In other words, what is modular can be released as a unit and reused.
So then what correlations can be made between agility and modularity?
- Structural flexibility which defines modularity
- Temporality or the ability of the system to accommodate future change which defines agility
A jar file
- unit of reuse
- unit of composition
- unit of deployment
- unit of management
So why not make jar files first class citizens on the java platform? Why do we have to package a jar inside a WAR or a EAR? Why are we flattening these modular units.
Increasing a system's modularity leads to easier to maintain and extendable software. In a non-modular system, being afraid to make changes to the code base causes us to do things such a copy/paste, or write duplicate code which further degrades the codebase. Guilty as charged! Modularity helps in assessing the impact and cost of change. When we know what other modules depend on the module that needs to be changed, we have a more clearer understanding of the risks, impacts and cost of that change. I wonder if the roadblock to modularity is our platforms. What if the WAS and Glassfish and Weblogics of the world allowed us to deploy our applications as sets of OSGi bundles?
There was a comment about how WAS 7 has made giant strides towards being modular internally by adopting OSGi under the hood. Apparently it starts under 5 seconds for a non-ejb application. I had to recently run WAS 7 in development mode inside my RAD workspace. And I can vouch for the fact that startup time was certainly several magnitudes more than 5 secs. Maybe I'm missing something here.
So what are benefits realized in the runtime because of modularity?
- Dynamic deployment
- Multiple versions
- Enforce dependencies
A few thoughts around this:
- Public methods shouldn't necessarily be published methods. Currently this is enforced via Javadocs unless you are using OSGi
- Interfaces should be close to their usage and not close to the implementations. This makes sense for framework APIs. It probably applies to business applications as well. What's good for the goose is good for the gander.
- Separate the interface from the implementations not just at the package level but also as deployment artifacts. You see this in framework apis now (javaee-api.jar is separate from its implementation jar). But not so much in business applications. If we did, it would aid in providing more predictable API evolution. We would be able to fix a defect or enhance an internal function in the implementation and then release just the newer version of the implementation built against the same old version of the API. The consumers of this API would not see any surprises since the API itself hasn't changed. Instead when we package both the interface and implementation as a single artifact, it is more difficult to avoid surprising the consumers of the API.
- Exceptions should be close to where they are thrown. So they should be part of the API.
Overall I really liked this session because of how it tied all the buzz and technical mumbo-jumbo around modularity and OSGi into business speak, something you can pitch to management.
Session: That old Spring magic has me in its SpEL: DI Wizardy with the Spring Expression Language - Craig Walls
Spring Expression Language or SpEL is probably the most pervasive feature in Spring 3.0. From what I've seen so far it can be used in DI, in Spring Web Flow, in Spring Security, Spring Integration. So if you are looking at taking advantage of Spring 3.0 you should probably look at SpEL. A SpEL expression is provided within a #{ } similar to the JSF EL. The source code contains well documented examples of the different forms of SpEL expressions. Here is a sampling:
Instead of having to use environmentPlaceHolderConfigurer
you could do:
#{systemProperties['region']}
#{systemEnvironment.region}
You can refer to the following:
#{bean.property}
#{request.getParamenter(''action)}
#{request.getAttribute(action'')}
You can inject these directly into bean properties instead of having to do it in code. Very cool! This is just scratching the surface. Go now and checkout the source. There are some amazing things you can do with collections similar to what you can do with the Bean predicate except more succinctly. SpEL can be used as a configuration tool (both in applicationContext.xml as well as with Spring annotations) as well as a general purpose parser a la apache commons beanutils via the SpELAntlrExpressionParser</code..
SpEL is nice but there is no type safety or syntax checking. It seems to impart a functional flavor when used with collections. Craig had one test class with individual test methods that showcased each of the capabilities of SpEL. He would make a change in the test method and hit save and the test would be automatically run giving him immediate feedback on pass or fail. He was using Infinitest who are handing out free licenses for individual developers. It uses JUnit. I hope they also provide TestNG support.
Session: Working with Spring Web Flow - Keith Donald
I was convinced to attend this session after the Spring Faces session. Spring Web Flow is a stateful web conversation framework. The flow persistence strategy is pluggable. By default it uses Session but it doesn't necessarily have to be session. Useful in a multi-step progression type user interaction as well as in single page AJAXy interactions.
Keith showed how pages are book-markable and how the browser Back button works as it should. Web flow uses an encrypted key in the URL parameter for the key. Example e5s1 where the 5 indicates the execution of time of this execution and the 1 indicates the snapshot or step in the flow. You can modify the key in the URL and the URL is still addressable.
The execution has a lifecycle and upon completion it is garbage collected which means it is no longer active. It does automatic session cleanup after the flow ends. Spring Web Flow can replace t:saveState and all the extra coding that goes with it to maintain state particularly in multi-page flows.
There was a question about where we can introspect the flow execution repository for use cases such as bread crumbs navigation. Apparently you can but it is still very involved and this is being addressed in the next version. Keith demonstrated the hotel web application sample from Spring and the flow for the booking scenario. External flow definition modules are compiled and refreshed upon changing without app server restarts. Code completion is available in the editor (STS?)
Can use evaluate to execute some method and assign to a scoped varible. SpEL can be used in Web Flow. The model attribute on view-state is used to bind form parameters to bean properties. I didn't quite catch the validation part of it.
I definitely need to take a good look at Spring Web Flow and it's integration with JSF.
Session: Spring Integration 2.0 Preview - Mark Fisher
Spring integration provides an embedded message bus that lives within an applicationContext with all components being Spring managed objects. Many of the patterns from the Enterprise Integration Patterns books are implemented. A message wraps around a payload (XML/java Object) along with headers. A Message Channel is the communication link between producers and consumers and provides loose coupling.
This is another one of those core technologies that I think can underpin the architecture of a flexible enterprise application.
Case Study: SRM 2.0 - A next generation shared resource management system built on SpringSource dm Server - Matt Stine
This session was about how St. Jude Children's Research Hospital rebuilt their Shared Resource Management System as a modular application to be extensible to meet growing business needs. The business need was to track samples as they progressed through the different stages in a laboratory. There are several laboratories and each usually has it's own set of unique requirements.
The previous system consisted of:
- Core domain model
- Core services platform
- Web platform
- Laboratory specific extensions
- DB Schema - extendable by hanging tables of existing tables
- Domain model
- Services
Overall the schema had 200 tables that was becoming unmanageable. And they had to follow a monolithic deployment model. When it was decided that they need to rethink the application it was based around extensibility
- primarily by configuration
- feature modularity
An EAV data model was chosen for it's extensibility. The system was built around some core concepts such as a kernel and business activity source. Using OSGi as the underlying platform, they were able to introduce new technologies behind an OSGi service without running risks of breaking other parts of the application. From a development perspective OSGi lets them ship the interface out to a 3rd party team and have them implement it.
Used 3 to 4 days of consulting work from SpringSource the team was able to ramp up on OSGi, Spring dm server and STS starting in January '09. They then spent the first 3 to 4 months working out the kinks since the tools were still in their 1.0.0 version. In their experience, adopting OSGi led to a short time fall-of in productivity as they ramped up on the technology but they are now reaping the long term benefits of modularity. Their reporting solution was implemented against a real time data mart that is relational and using messaging via Spring Integration and a data-bus architecture.
It was pretty awesome to see that they had developed a modular enterprise application based on OSGi leveraging Spring Integration. After the presentation I got the chance to talk to the technical lead on this project from St. Jude. He told me how respecting the small set of simple tenets of good application design enforced by OSGi, depending on interfaces, and use of shared bundles was really the reason for their success. OSGi is not complex and there is no need to make it complex. Wise words.