Bio Juergen Hoeller is co-founder of the Spring Framework open source project and has been serving as the project lead and release manager for the core framework since 2003. Juergen is an experienced software architect and consultant with outstanding expertise in code organization, transaction management and enterprise messaging. @springjuergen
Software is Changing the World. QCon empowers software development by facilitating the spread of knowledge and innovation in the developer community. A practitioner-driven conference, QCon is designed for technical team leads, architects, engineering directors, and project managers who influence innovation in their teams.
1. Hi I’m Victor Grazi and I’m here with Juergen Hoeller at QCon 2014. Juergen is the cofounder of Spring and principal engineer of Pivotal, the current custodian of Spring. So Juergen, Spring is as important to most Java projects as Java itself, what is the secret of Spring’s success?
That is an interesting question actually. It’s often hard to say; after the fact we are always wiser, but looking back at those ten years, I would say it’s a combination of factors that really continued all the way through. Right from the beginning we set a couple of core principles up, where the application framework lives close to the application, it’s being deployed with the application, can be independently chosen, independently versioned along with the application’s deployment unit. Those principles still apply and are a key part of why Spring is so popular. It’s basically something that you can embed in any kind of application. It’s your choice, it’s the development teams responsibility, it’s decoupled from the actual deployment environment, which may be not in your hands, maybe in the hands of the operations team. So that independence from the target deployment infrastructure I think is a key point, even these days. And the rest is just history.
Fundamentally Spring turned out to arrive apparently at a very good time, at an interesting time, where there was a strong demand for a little bit of guidance, structuring, (and) programming model style, that Spring brought on to the scene here. In the past couple of years we’ve been so strongly focusing on evolving Spring in a kind of very balanced fashion where we are taking along existing Spring users in particular, not leaving them behind in any form, in a very clear upgrade path from generation to generation. I think that continuity along 10 years in the mean time is a key recipe for success in its own right. So it’s an interesting situation to be in now, where we have this 10 years history. We keep evolving the framework very actively, and our track record hopefully continues down those lines. There is no radical breakage plan so we are really moving along based on our original mission, which still applies even after all those years.
We developed our own process, in the mean time I suppose. It’s not very formally defined. We have a reasonably large team in the mean time across the Spring portfolio, but every single project has a very dedicated development team with strong project leads making their own decisions.
So basically we have independent projects that co-evolve. Of course there is some overall alignment and some strategy really backing up the entire portfolio. But fundamentally every project make its own decisions based on its stakeholders, based on its dependencies, based on the state that it is in. And we keep evolving, for example the Spring Framework itself, rather conservatively, (with a) strong focus on backward compatibility, (and) a very strong recognition of existing code out there integrating with Spring. There is so much out there, we really go to some extra lengths, trying not to break any such code. Whereas other projects in the Spring portfolio, more recent projects in particular, such as Spring Boot or even the Spring Data project or Spring XD; they evolve more, somewhat more radically; they release more often, they upgrade the minimum dependencies more aggressively than Spring Framework itself ever could. So this independence of the individual projects with a very strong project lead in place I think is what our model is about. And the strong project leads, we sometimes call it the “Benevolent Dictator Model”, it’s really necessarily to have a kind of ultimate authority for design decisions and for release-planning decisions in every project. So even if it’s very community driven and very team oriented, ultimately, in some cases, you need to arrive at a decision, we keep throwing out a lot of design here, into the world. Spring has so much surface area, there’s a lot of design decisions to make. You could almost argue (that) our day to day job is like a sequence of design decisions all day long, and sometimes we also code!
So that’s really why we have to have these strong project leads in place. If you don’t agree on certain design decisions, somebody has to make an ultimate decision on that. We used that recipe for about 10 years already. It’s originated in Spring framework. We set up all our Spring portfolio projects the same way and it keeps being a very successful model for us. Even if it’s different from say the Apache Software Foundation and others, we have no intention to change that model; it worked for us for the past 10 years and it will hopefully work for the next ten years as well.
Java 8 is a key topic of ours. But it’s not just a key topic of ours these days, it’s a key topic for this industry. We started investing last year, that’s actually back in early 2013 even, when the OpenJDK 8 milestones started to appear in a proper form. We had even a first Spring Framework 4.0 milestone build on OpenJDK 8 already, and we took it from there. So we’ve actually started adopting certain Java 8 features at a time when they were still arriving at the final shape. So we had a chance to influence, for example the parameter name discovery API in some details that were important to us.
That was the main reason why we started so early, to still have a chance of influencing some of the fine design in JDK 8. And from a usage perspective we had early adopters asking for Java 8 support, so it was partly driven by our own motivation to be there early to support Java 8 from early on. But there have been people even last year trying to build Spring applications on Java 8 with the use of OpenJDK 8 on milestone releases and we basically wanted to support them from early on.
The strategy from our perspective is simply that for new applications, new Spring-based applications being started now, there is no reason why you wouldn’t consider Java 8 from the beginning. It’s all in place now. We hopefully did our job. Many other infrastructure providers did their job as well. From the Eclipse foundation to ASM, all the pieces are basically in place, at least from the core Java perspective. And in June 2014, now, I would actually strongly recommend to familiarize yourself with Java 8 and just consider it for any new initiative started, for any major revision of existing systems as well, as long, of course, as you are able to introduce Java 8 into your production environments once you go into production, which may not be before next year anyway, or before 2016 maybe even. Many development projects have a long development phase. So that’s basically our perspective at the moment. We understand that there is a lot of JDK 6 and 7 usage out there, but we personally are strongly JDK 8 focused; we as a development team must be strongly Java 8 focused these days; we hope that our user community will also move on to Java 8 rather ambitiously.
There are actually quite a few of those. Of course Java 8 support is very dear to my heart; I’ve been leading that from day one. But there are a couple of other favorites. For example we had to reconsider the algorithm at the heart of the Spring dependency injection container, which is the type-matching algorithm. It’s a very central element in the picture where historically we only matched by primarily type plus qualifiers, which is basically what JSR 330 dependency injection model suggests. However we had quite a few people both within the team and in the user community starting to design more complex generic type structures; repository interfaces with a type variable for the actual entity type, but also custom structures significantly more complex than that even, where they were just saying “the primary type is not sufficiently expressive, I want a dependency that matches my full generic type-declaration at the injection point!” In order to address that properly we had to reinvent the type-matching algorithm. It was basically redesigned from scratch. It’s now fully generic type based and considers the entire generic type declaration. If a target type is assignable according to the Java compiler rules, so if you could assign it basically in a line of Java source code, then Spring also considers it assignable; then and only then.
It is, it is completely backwards compatible. That’s actually a good point. We had to fine tune it quite a bit. We had a milestone phase, a release candidate phase; we had to add a fallback for unchecked assignments, since in the Java compiler world you can do a proper generic assignment or an unchecked assignment. We basically mimic the same kind of arrangement that the Java compiler has. We have an unchecked assignment step in that algorithm and that basically covers all the cases, even in existing arrangements. It’s more like existing, larger Spring application context arrangements, they overuse qualifiers in some cases, which is now simply not necessary. But it doesn’t hurt either to have it in there.
But that’s actually why we are doing it. The end result means you have a very expressive type-arrangement in your code. There is no need to add additional metadata; if the type structures are sufficiently expressive, we’ll find the proper match for you.
So that’s certainly one of my favorites. And there are many such subtle refinements. Personally I also really like the composable annotation model. Introduced in Spring Framework 3, and that generation refined it all the way along, and in Spring Framework 4 we have a model for attributes; convention-based use of attributes on custom annotations. Spring annotations use this as meta-annotations and attributes, basically overriding standard Spring attributes. In all conciseness here, it’s a really expressive model. It allows you to design custom annotations, maybe for project wide use, maybe even for team wide, corporate wide use, where you may combine your own conventions into custom annotations in a very nice model. It also adds to the readability. You can choose your own names for those annotations, your own stereotypes, so it’s basically a tool for application architects or a development team to agree on a set of custom stereotypes that they would then use across a larger Spring-based codebase.
Conditional configuration isn’t actually brand new in the Spring world. It’s a model that we started introducing in a more first class form back in Spring Framework 3.1 with the profile model. Profiles are kind of a simple, static kind of condition. What we did in Spring Framework 4 is that we basically took a step back and revisited that arrangement.
Profiles (are) a very simple kind of condition, but in Spring Framework 4 we basically took it literally and introduced a general condition model. Profiles are now just a simple implementation within that general condition model, actually literally, so the profile model @Profile is now meta-annotated with @Conditional ProfileConditional.class, so it almost translates very literally.
The conditional model itself is now dynamic, which basically means there is a rich context provided to a condition implementation; a custom condition can react to any kind of context at the time when it’s being evaluated. It can check for the presence of other beans, the non presence of other bean definitions, the presence of certain environment settings, the presence of certain jars on the classpath or the non presence of certain jars on the classpath; so it’s a very flexible model, rich context provided. And Spring Boot basically is our primary vehicle to actually leverage that feature.
So in Spring Boot we really take that to quite some stage there where we build an arrangement, almost aggressively defaulting. In Spring Boot if you don’t provide a specific kind of setup, Spring Boot will auto-configure it for you and it’s all based on the Spring Framework 4 condition model. So you could almost say the heart of Spring Boot is a set of conditional configuration classes that’s based on the Spring 4 model. It’s of course also there for custom use, so any kind of larger Spring-based application may benefit from maybe a set of custom conditions expressing the configuration differences, the configuration challenges that that specific project has, but for anyone interested in the power of conditional configuration, definitely check out Spring Boot. Then you’ll see it basically in action from the first step onwards.
That’s the second main theme in Spring Framework 4. Actually very much worth mentioning is exactly the messaging domain and web sockets. We had a strong focus on message-oriented architectures for a number of years now, we have Spring Integration as a kind of sister project, modeling message-oriented architectures based on channels and based on routing. What we did in Spring Framework 4 is that we defined, like extracted almost, a general messaging module which is now part of the Spring Framework 4 arrangement, with common message types; message, message headers, a message mapping annotation for message endpoint design, so a couple of basically “commonalities” for message-oriented processing, and for message endpoint definitions in particular.
In the current state of affairs we are using that for web socket messaging, where our web sockets support is from the ground up. So you can do raw web sockets, you can do JSR 356 web sockets, Tomcat Jetty style web sockets; but where it really becomes interesting is one layer above, basically, messaging protocols on top of web sockets. So in Spring Framework 4 we basically did that whole stack, the messaging support is STOMP based, so we suggest the use of the STOMP messaging protocol on top of web sockets with a SockJS fallback. That’s a great way to design simple message based interaction between different parts of the system, and that’s where our new messaging module is being used and can be seen in action in the endpoints accepting messages there, we’re using our common message types. The recently released Spring Integration 4.0 uses the same messaging types, so the real power of this common messaging module really becomes apparent as we have more and more parts of the Spring portfolio supporting some kind of specific message endpoint, all using the common message endpoint design and the common messaging types.
In Spring Framework 4.1 to be released in July, we do the same for JMS. So we support a kind of bridge between JMS and our common message types so that the same endpoint design can also be used for standard traditional JMS endpoints. So it really comes together as we move into 2014 and as the wider Spring portfolio makes some really good use of what Spring Framework 4 introduced end of last year.
8. Of course NoSQL has been creeping up on us very quickly and it still seems fairly immature for any attempt at a general purpose API, and Java EE seems to stay away from doing that I guess partly for that reason, but Spring Data seems to be placing a stake in the ground in that space, can you talk about that?
I definitely agree with the general assessment, the NoSQL space is very diverse. It’s a very interesting space by all means; there is a lot of really interesting stuff going on, lots of innovation, lots of creative alternative thinking from what a transaction may possibly mean from the notion of consistency and so forth. So that’s great stuff. But basically each and every one of those data stores is an individual product, an individual model; it’s really hard to treat them in any kind of abstract form. So I wouldn’t want to see any kind of abstract API standard specification trying to identify the common ground which isn’t really much and we would probably arrive at something like the good old JCA common client interface, if that rings a bell with anyone.
But anyway, with Spring Data we have a different model. There are dedicated Spring Data sub-projects for every one of those data stores; from Redis to Mongo, Neo4J. There are dedicated sub-modules and every one of those treats its target data store as a first class option. So we basically do things the way that this data store wants us to do things. We are not trying to abstract it very much. The common model comes in through the repository model in Spring Data where common design characteristics (e.g.) how repositories are structured, how queries can be specified. But the way you actually express yourself in terms of queries, what the transaction means and so forth, is still data-store specific.
So Spring Data basically is our set of modules which really targets the NoSQL Space in the sense of treating those data stores as first class citizens in the Spring-based world; just as first class as a relational database is, as traditional messaging systems also are; and trying to kind of provide our community with the best of both worlds. First class support for those data stores, common design in terms of the Spring repository classes that you would implement there, and just the right degree of abstraction, which is not that much. So it’s a finely tuned balance and has nothing to do with trying to create a kind of standard model to talk to data stores. So Spring Data really is a nice illustration for the general design perspective that we take in Spring land, where we do try to identify common ground, common implementation styles, (but) at the same time we treat many of the middleware offerings out there as first class citizens. Just for a comparison, in the messaging space Spring AMQP (and) RabbitMQ is an alternative to JMS that had a first class status for a long while already. Basically the Spring Data projects do the same for the NoSQL Space.
Spring XD is an unusual project to have in our portfolio, even (though) it’s a reasonable new initiative and strongly targeting the Hadoop space. So it’s basically a solution-oriented arrangement for big data processing, for data ingestion, any kind of high volume processing. It’s really doing the very latest in the Hadoop space with Yarn, etc. It brings together a lot of the efforts that we’ve been doing before; a lot of the sub projects that we’ve been doing before. We’ve had a Spring for Apache Hadoop subproject for a while. Spring XD brings them into one model with a DSL arrangement where certain models can be implemented by some development teams in a corporation where others would use the DSL to express certain data processing arrangements. It’s an interesting kind of sweet spot between a more traditional application programming perspective and a DSL based higher level specification of data flows.
So Spring XD is at the moment in Milestone 7, it will go GA towards the end of July, so if anyone is interested in that space it’s definitely worth checking out with a very sweet spot in its specific design. We also release, as you may already have heard, Spring Framework 4.1 in July. That is no coincidence; Spring XD is Spring Framework 4.1-based and makes some interesting use of some of the more recent Spring Framework features as well.
It’s not the first time I’m hearing that question actually, but my Twitter account is obviously quite popular to be referenced and I’m actually reading it very actively just in case anyone is wondering. I’m not making any specific promises when the first Tweet will come, but chances are it’s not that far away.
Victor: Thank you very much Juergen Hoeller!