Showing posts with label Java EE. Show all posts
Showing posts with label Java EE. Show all posts

Sunday, May 05, 2019

To Enterprise Java and Beyond! A personal perspective.

Ok so the title isn't quite what Buzz Lightyear said but cut me some slack, it's been a long day! Earlier I posted a blog about the results of the negotiations between Oracle and the Eclipse Foundation around IP transfer for Eclipse Jakarta EE and how they didn't go the way many of us had expected 18 months ago. The upshot of this is that the Java EE community is at a crossroads and I'm going to outline the options I see and give my own preference. Note, we are discussing these things within Red Hat now and have no firm conclusion so far, hence why this is on my personal blog. Therefore, don’t read this as a formal statement from Red Hat - it is not and these are just my own thoughts and opinions. If you know anything about Red Hat then you'll understand that even though I sit where I do in the organisation that doesn't mean I get a veto!

Before I jump in I want to make something clear from the outset. Anyone who knows me knows I've been involved with Java and Java EE (J2EE) from the beginning of their history. In my own small way I like to think I've helped shape them both, whether as a specification lead or a member of the JCP EC. I may not be a Java Champion but I'm a champion of Java - see what I did there ;) ? The reason I call this out is I'm pretty sure I understand the positive influence they've both had on the industry over the years, whether through explicit efforts like application servers and the raft of specifications needed to build them for a distributed environment, or implicit because many of those same specifications are embedded and often hidden in some of our most popular frameworks or stacks. I'm not writing this from the perspective of a vendor, or because I'm on some ego trip, or even anger at the way things turned out. A few of us have known that this day was coming and it's given me a chance to try to think about the future objectively.

One of the key things that Java EE has prided itself with over those years has been compatibility which has helped ensure application portability. With a few exceptions and application written against those standards ensured an application could be moved between different compliant vendor implementations. And something which is often overlooked is the backwards compatibly such that it was typically possible to easily migrate to the next revision of the specification and hence implementations. That compatibility helped a lot of developers build applications which have stood the test of time with little to no modifications. In short, they could develop their apps in the pretty safe knowledge that they'd keep working over the years until or unless there was a need to add new functionality or take into account some breaking change in the standards.

Alright so with all of that said, where do the most recent announcements take us? Well put simply, if the community want to modify a Jakarta EE specification that is under the javax namespace then:

  • The namespace needs to change from javax to something else.
  • The specification name needs to change, e.g., no more JMS (note, as my youngest son pointed out to me the other day JkMS may not be good as his generation assume JK is shorthand for joke!)
  • The TCK needs to change.
  • The RI needs to change. I know we don't have the concept of RIs in Jakarta but there are implementations in Glassfish which have need drive the specifications.

Now let's think of what that means for developers who use these specifications, either within Java EE implementations or elsewhere:

  • Their application code needs to change.
  • Their test suites need to change.
  • Potentially any 3rd party code reliant on the specification needs to change.
  • Potentially any code reliant on the original developer code needs to change.

If you’ve ever used one of the Java EE specifications or even other specifications from other standards bodies, then you’ll know that depending upon the original reason for wanting to modify the specification, all of the above changes and necessary coordination across developers and possibly different vendors might well be worthwhile. The modifications could be that killer feature needed to catapult dependant applications to the next level or close that crucial security flaw. Changing your applications to accommodate such modifications isn’t something you might want to do from the start, especially if they appear to be working fine anyway, but any concerns can often be quickly overridden through understanding the motivation.

Going back to those crossroads, one of the roads we could go down is what a few people are advocating: a Big Bang approach after Jakarta EE 8 is out to just get the whole issue around javax out of the way in one fell swoop. This would mean changing all of the specifications and take the hit with developers, communities and customers all in one go. I'm not convinced that's the right thing to do though I'm willing to listen to the community, but here's why I start from my position:

  • It clearly breaks backwards compatibly and from the perspective of an end user that's not necessarily a good thing for all the reasons I mentioned before. Yes it "finally removes all Oracle control" as some have suggested, but I suspect most users of Java EE don't care about that, especially as they ignore it for other areas of our ecosystem like OpenJDK. So this could be an uphill struggle to convince people it's a good thing. Bad enough for one specification let alone all of them. In fact it could have the unintended affect of driving people away from Jakarta EE because if they have to change code anyway then why not look at all options, such as other frameworks, stacks or even languages.
  • We need to stop thinking about developers of Application Servers or their components and think about our end users who are not necessarily as well versed in the politics we often take for granted. A "one time hit" for us could be death by a thousand cuts for our users, communities and customers.
  • Going back to my original statement earlier about why a specification may have to change and why users may be ok with that, it all hinges on the definition of what constitutes a critical update to the specifications. Just changing the namespace doesn't count in my book (annoyance with Oracle isn't necessarily something people elsewhere care about, as I said earlier). I've heard that we should adopt Java 11 (like Java EE 8, Jakarta EE 8 only requires Java 8) and maybe suggest that we have to change the specifications somehow anyway as a result, so the namespace change is therefore forced on us and users. Well that doesn't work either because most vendors already support Java 11 without any changes to the specifications.
  • OK what about JPMS I hear you say? That's a part of Java 11 so we could take to opportunity to embrace modules for the specifications and again address the whole namespace issue at the same time. Look, I'm not going to rehash the whole Jigsaw debate from the other year but I think the jury is still well and truly out at the moment as far as JPMS is concerned so suggesting that this will do anything but alienate a large swathe of users is strange at the very least. JPMS is not a good reason to break compatibility for end users of something so mature and so well adopters as Java EE.

I cannot see any good reason (good for end users) that makes a wholesale change to the specification namespace worthy. Now that doesn't mean the community won't decide to go down that road, but if they do then they need to understand the potential potholes that are lying in wait. I've mentioned some of them and they could be so big as to derail the entire journey. Changing all of the specifications will require a lot of effort from vendors and communities to get behind the code changes, bug fixes etc. No one should be under any illusions that the developers and vendors who brought Java EE to where it is today are necessarily going to be able to commit as much to Jakarta EE in the future - the wider community is going to have to step up and fill in the gaps in effort and potentially monetary investment too. These specifications and implementations don't write themselves! One other thing to take into account: whilst the larger vendors can probably afford to make this kind of investment of time and people to change their implementations, it's entirely possible some smaller vendors won't have that luxury and that could reduce diversity.

That's one of the routes from this crossroads outlined. What about another? Well the clear alternative to the wholesale change option is to do it gradually as and when meaningful modifications to the specifications are needed. That then raises the obvious question about what is the future direction for Jakarta EE? Let’s try to answer that before we venture down this other road.

Those of you who have followed this adventure from the time we stood on stage at JavaOne 2017 will know that we said we wanted it to be the home of cloud native Java. That made perfect sense as we believed we could evolve the existing specifications seamlessly and eventually merge or otherwise collaborate with MicroProfile, which sprang up over a year prior to the JavaOne 2017 announcement. However, in this new world I'm no longer sure that makes sense and here's why:

  • The use cases which drove the development of Java EE remain extremely relevant today as evidenced by size of the market. When you factor in those other frameworks and stacks which use components of Java EE (specifications and implementations), that size grows further. Those users typically want stability, compatibility and cautious evolution. But changes happen; Java EE today isn’t the same as J2EE in the beginning. That’s been fine over the last 15+ years as new specifications appeared in the javax namespace and modifications to existing specifications likewise. This is goodness. However, we have to recognise that Java EE hasn’t evolved rapidly over the years. The 18 month delay around Jakarta EE hasn’t exactly helped either. New specifications and updates to existing ones haven’t exactly been driving to a rapid release cadence release. Don't get me wrong though, that isn’t necessarily a bad thing: stability, maturity and reliability are good things after all and I believe many of today's long time users take that for granted and expect it.

  • Slowly evolving the stable standards and implementations as and when, helps to give users the chance to evolve at their own pace too and often only when significant changes happen. In fact it’s not rocket science to see how the old javax namespace implementations could reside alongside their updated Jakarta namespace siblings at the same time if we went this route.
Stability is the operative word then and therefore, I think we should re-evaluate our direction for Jakarta EE in light of the namespace debacle which clearly has the potential to throw that out of the window. It’s no disservice to the community and implementers to suggest that focussing on stability and existing use cases should become the priority for Jakarta EE. They represent the backbone of our industry. If something significant comes up later that requires a change to a specification then we evolve only that specification, as I mentioned above.

What about new specifications though? Where do they get added? Well for now let’s assume that this route at the crossroads (this option) doesn’t preclude adding of new specifications to Jakarta EE, which would clearly have to be under a non-javax namespace, but we’ll put that topic on hold for a moment whilst we look at the final option at the crossroads where we find ourselves.

I think we can all recognise that there are new use cases for new deployment environments such as the cloud or IoT which have shown that Java EE isn’t necessarily the right answer. The community and vendors saw this when we all kicked off Eclipse MicroProfile and over the 3+ years since that effort started we’ve seen a lot of activity, many more implementations than Java EE Application Servers, and a number of rapid releases annually.

Whilst MicroProfile uses some Java EE specifications, it doesn’t need them all at the moment and might never. Some implementations can use Java EE Application Servers as a result of this. However, much of what has happened in MicroProfile has resulted in more non-Java EE specifications than Java EE and more implementations that don’t rely on Application Servers at all. It is a vibrant community evolving enterprise Java to be cloud-native faster than Java EE has so far been able to do. And it has a familiar feel to it as many of the same vendors and communities have become involved. Though if you look at the list of supporters and participants in the community you'll see many new names there, both big and small.

As I mentioned, MicroProfile relies on a few Java EE specifications at the moment, e.g., JAX-RS and CDI. If that community needed to evolve them then it would naturally need to either change the namespace as we’ve already covered, or perhaps replace them wholesale with entirely different approaches, though that has its own pros and cons. However, because MicroProfile doesn’t rely on many Java EE specifications, and when and where it does the use cases MicroProfile has will likely be satisfied with the stable javax versions anyway, it’s probable that the impact of any namespace changes is already much more focussed, meaning users are that much less likely to want to consider jumping ship.

Since the point we announced Jakarta EE and began working on it we've been asking the question about whether and how MicroProfile might merge into Jakarta EE, perhaps providing the innovation branch of it. But if the community wants to evolve Jakarta EE to cloud-native, I believe it makes more sense given the recent announcements to jump straight there and anoint MicroProfile as the place where that work continues to happen, pulling over specifications from Jakarta EE only where needed, modifying them only when there's a good reason. We don’t want to split the community and cause yet more confusion or delays and whilst some may want to continue driving Jakarta EE forward to conflict with MicroProfile, that risks fracturing the efforts and not capitalising on the momentum happening there now. Therefore, if new specifications were to be considered to be added to Jakarta EE around cloud-native, my preference would be for them to be moved to MicroProfile instead. And of course that doesn't mean they can't be taken back in to Jakarta EE if and when new releases are deemed necessary.

OK so you've gotten here and you'd probably like a summary of the options as I see them so here goes:

  1. The Big Bang approach and change all of the javax namespace at Jakarta EE 9 to something else. Not my personal preference as it risks alienating a lot of end users, driving them elsewhere and possibly reducing implementation diversity.
  2. Focus on stability and compatibility for Jakarta EE and evolve specifications and namespace only as and when new and significant modifications to them are needed, such as new features, bug fixes etc. New specifications can be added here too but clearly not under the javax namespace. I'm more keen on this option but the communities need to agree on the use cases as there's a possible conflict with MicroProfile.
  3. Agree that MicroProfile is the place to evolve Jakarta EE specifications if they need to become more cloud-native. MicroProfile will likely look forward though and add more and more new specifications and only pull across specifications from Jakarta EE when really needed, as has been the model to date. My preference, in case it wasn't obvious.


Now maybe there are other options, such as significant reasons for why Jakarta EE should evolve in directions not covered by MicroProfile. And of course option 2 and 3 aren't necessarily mutually exclusive if we can find other meaningful use cases for evolving Jakarta EE in option 2. It’s also possible some people won’t agree with my assessments. For me those are all good and acceptable outcomes from reading this article. I’m a scientist and if new information comes to light which impacts a theory I’ve created then I’ll re-evaluate. But what I caution everyone against is making rash decisions in the heat of the moment, especially if they are fuelled with the “let’s stick it to Oracle and get this done!” That attitude won’t lead to the right outcome and we could then spend many years regretting it.

The next step should be discussing this in the communities and not just the Jakarta EE community. The MicroProfile community is just as tied into the future of Jakarta EE. How we move forward with both is important to both. Let’s do this together and make the right consensus driven decision. This is a tricky time and we shouldn't rush to a decision on partial facts or worse still, anger and frustration.

Monday, January 02, 2017

A Java EE Interlude

I want to take a quick break from the other series for a moment to do something I've been remiss about for a while: addressing a recent report by Gartner on the state of Java EE. Before doing so I decided the other day to read the article my friend and colleague John Clingan made a few weeks ago and I realised that John had done a great job already. In fact so good I couldn't see myself adding much to it, but I'll try below. Note, there are other responses to this report and I haven't had a chance to read them but they might be just as good.

To start with, it's worth noting that I've known Anne for a number of years and we've had one or two disagreements during that time but also some agreements. Her announcements about the death of SOA seven years or so ago falls somewhere in between, for example. It's also important to realise, if you don't already, that I do believe everything has a natural cycle ("the circle of life") and nothing lasts forever; whether it's dinosaurs giving way to mammals (with some help from a meteor and/or the Deccan Traps), or CORBA shifting aside for J2EE, evolution is a fact of life. Therefore, whilst I disagree with Anne about the short-to-medium term future of Java EE, longer term it will pass into history. However, before doing so it will evolve and continue to influence the next generation of technologies, just as the dinosaurs became the birds and aspects of CORBA evolved into J2EE. For more details on my thinking on this topic over the years I leave it as an exercise to the reader to check this blog or my JBoss blog.

John covers my next point very well but it's worth stressing: I've mentioned on many occasions that my background is heavily scientific and I continue to try to employ objective scientific method to everything I do. So when I see blanket statements like "fade in relevance" or "lighter-weight approaches", whether it's in a Gartner report, a paper I'm reviewing as a PC member, or even something one of my team is writing, I immediately push back if there's no supporting evidence. And I read this report several times searching for it but kept coming up empty handed. It was one subjective statement after another, with no real attempt to justify them. That's disappointing because with my scientific hat on I love to see facts backing up theories, especially if those theories contradict my own. That's how we learn.

One other thing I did get from the report, and I'm prepared to admit this may be my own subjective reading, was that it seemed like a vague attempt to look into the future for middleware frameworks and stacks without really understanding what has brought us to where we are today. I've written about this many times before but weak assertions by the report that "modern applications" are somehow so different from those we've developed for the last 50 years that existing approaches such as Java EE are not useful really doesn't make any sense if you bother to think about it objectively. Distributed applications, services and components need to communicate with each other, which means some form of messaging (hopefully reliable, scalable and something which performs); there's really no such thing as a stateless application, so you'll need to save data somewhere (again, reliable, scalable and performant); hey, maybe you also want some consistency between applications or copies of data, so transactions of one form or another might be of help. And the list goes on.

Of course application requirements change over time (e.g., I recall doing research back in the 1980's where scale was measured in the 10's of machines), but new applications and architectures don't suddenly spring into being and throw away all previous requirements; it's evolution too though. I've presented my thoughts on this over the past couple of years at various conferences. In some ways you can consider Java EE a convenient packaging mechanism for these core services, which are typically deployed in a co-located (single process) manner. Yet if you look beyond the Java EE "veneer" you can still see the influence of enterprise distributed systems that predate it and also the similarities with where some next generation efforts are heading.

I suppose another key point which John also made well was that the report fails miserably to differentiate between Java EE as a standard and the various implementations. I'm not going to cover the entire spectrum of problems I have with this particular failure, but of course lightweight is one of them. Well over 5 years ago I wrote about the things we'd done years previously to make AS7 run on a plug computer or Android phone and we've kept up that level of innovation up throughout the intervening time. There's nothing in the Java EE standard which says you have to build a bloated, heavyweight application server and we, as well as other implementations, have proven that time and time again. It's disappointing that none of this is reflected in the report. I suppose it's one of those terms the authors hope that if they say it enough, people will attribute their own subjective opinions and assumptions to it.

Another one of those throw-away statements the report is good at is that "[...] at this point, Java developers eschew Java EE". I admit not every Java developer wants to use Java EE; not every Java developer wanted to use J2EE either. But you know what? Many Java developers do like Java EE and do want to use it. You only have to go to conferences like JavaOne, Devoxx or other popular Java events to find them in abundance. Or come and talk to some of our customers or those of IBM, Payara, Tomitribe or other members of the MicroProfile effort.

I could go on and on with this but the entry has already grown larger than I expected. John did a great job with his response and you should go read that for an objective analysis. Probably the only positive thing I could attribute to the original Gartner report is that its very existence probably proves that time travel is possible! It's a theory which fits the facts: a report which criticises something based on data which is largely a decade old means it was probably written a decade ago.

Saturday, March 07, 2015

More thoughts on container-less development


It's time to get back to the concept of container-less development. I gave an outline of my thinking a while back, but let's remember that I'm not talking about containers such as docker or rocket, though they do have an impact on the kinds of containers I am concerned about: those typically associated with application servers and specifically Java application servers. Over the years the Java community has come to associate containers with monolithic J2EE or Java EE application servers, providing some useful capabilities but often in a way which isn't natural for the majority of Java developers who just "want to get stuff done."

Now of course those kinds of containers did exist. Probably the first such container was what came out of implementing the J2EE standard and that itself evolved from CORBA, which despite some bad press, wasn't as bad as some people make out (though that's perhaps a topic for a different entry.) CORBA was based around the concept of services, but back then natural unit of concurrency was the operating system process because threading wasn't a typical aspect of programming languages. Early threading implementations such as using setjmp/longjmp or Sun's LWP package for SunOS/Solaris, were very much in their infancy. When Java came along with its native support for threads, CORBA was still the popular approach for enterprise middleware, so it was fairly natural to try to take that architecture and transplant it into Java. What resulted was the initial concept of a container of interacting services minus the distribution aspect to improve performance. (It's worth noting that the success of Java/J2EE, the inclusion of Java as a supported language for CORBA, and the increase in thread support for other languages resulted in a reverse imitation with the CORBA Component Model Architecture.)

Now of course there's a lot more to a container these days than the services (capabilities) it offers. But in the good 'ol days this approach to kickstarting the J2EE revolution around CORBA resulted in some inefficient implementations. However, as they say, hindsight is always 20/20. What exacerbated things though is that despite gaining more and more experience over the years, most J2EE application servers didn't really go back to basics and tackle the problem with a clean slate. Another problem, which frameworks such as Spring tried to address, was that CORBA didn't really have a programming model, but again that's for another entry.

Unfortunately this history of early implementations hasn't necessarily always had a positive impact on current implementations. Change can be painful and slow. And many people have used these initial poor experiences with Java containers as a reason to stay away from containers entirely. That is unfortunate because there is a lot of good that containers mask and which we take for granted (knowingly or unknowingly.) They include things such as connection pooling, classloader management, thread management, security etc. Of course as developers we were able to manage much of these things before containers came on the scene and to this day. CORBA programmers did the exact same thing (anyone remember dependency hell with shared libraries in C/C++?) But for complex applications, those (in a single address space) that grow in functionality and typically built by a team or from components built by different programmers, handling things yourself can become almost a full time job in itself. These aspects of the container are useful for developers.

It's important to understand that some containers have changed for the better over the years. They've become more streamlined, fit for purpose and looking at the problem domain from a whole new perspective. The results are lightweight containers that do a few core things that all (majority) developers will always need really well and anything else is an add-on that is made available to the developer or application on an as-needed basis. The idea is that typically any of these additional capabilities are selected (dynamically or statically) with the understanding of the trade-offs they may represent, e.g., overhead versus functionality, so the selection to enable them is made as an informed choice rather than imposed by the container developers. Very much like the micro-kernels that we saw developing from the old monolithic operating systems back in the 1980's. So even if you're not
a Java EE fan or don't believe you need all of the services that often come out of the box such as transactions, messaging and security, the container's probably doing some goodness for you that you'd rather not want to handle manually.

Apart from the complexity and overhead that containers may provide (or are assumed to provide), there's the ability to dynamically update the running instance. For instance, adding a new service that wasn't available (or needed) at the time the container booted up. Or migrating a business object from one container to another which may require some dependent services to be migrated to the destination container. Or patching. Or simply adding a more up-to-date version of a service whilst retaining the old service for existing clients. Not all containers support this dynamism, but many do and it's a complexity that does not come without cost, even for the most efficient implementations.

Whether or not you agree with it, it should be apparent by now why there's a growing movement away from containers. Some people have experienced the overhead some containers impose for very little value. Some people haven't, but trust the opinions of their colleagues and friends. Still others have never been keen on containers in the first place. Whatever the reasons, the movement does exist. And then along come the new generation of (different) containers, such as docker and rocket which some in the container-less movement believe obviate the need for old-style containers entirely. The argument goes something like this (I'll use docker as an example simply because if I use the term container here it will become even more confusing!): docker produces immutable images and is very easy to use, so rather than worry about creating dynamically updateable containers within it, the old style "flat classpath"/container-less development strategies make more sense. In other words, work with the technology to get the best out of what it provides, rather than try to do more that really doesn't make sense and give you any real benefit.

This is a good argument and one that is not wrong. Docker images are certainly immutable and fairly easy to use. But that doesn't mean they obviate the need for Java containers. You've got to write your application somehow. That application may be complex, built by a team or built from components created by developers from different organisations over a period of years. And the immutability aspect of docker images is only true between instantiations of the image, i.e., the state of a running image can be changed, it's just that once it shuts down all changes are lost and any new instance starts from scratch with the original state. But docker instances may run for a long time. If they're part of a high-availability instance, with each image a replica of the others, then the replica group could be running indefinitely and the fact that changes occur to the state of one means that they are applied to the others (new replicas would have their state brought up to date as they join the group). Therefore, whilst immutability is a limitation it's no different than only having an in-memory database, for example, which has no persistent backing store: it can be architected around and could be a performance benefit.

If you believe that the mutability of a running docker instance is something that makes sense for your application or service, then long running instances are immediately part of your design philosophy. As a result, the dynamic update aspect of containers that we touched on earlier immediately becomes a useful thing to have. You may want to run multiple different instances of the "same" service. You may need to patch a running instance(s) whilst a pre-patched image is deployed into the application or replica group (eventually the pre-patched docker instances will replace the in-memory patches versions by natural attrition.)

And then we have microservices. I've said enough about them so won't go into specific details. However, with microservices we're seeing developers starting to consider SOA-like deployments for core capabilities (e.g., messaging) or business logic, outside the same address space of other capabilities which would normally be co-located within the Java container. This is very much like the original CORBA architecture and it has its merits - it is definitely a deployment architecture that continues to make sense decades after it was first put into production. But microservices don't remove the need for containers, even if they're using docker containers, which is becoming a popular implementation choice. As I said in my original article on this topic, in some ways the operating system becomes your container in this deployment approach. But within these docker instance, for example, containers are still useful.

Now of course I'm not suggesting that Java containers are the answer to all use cases. There are many examples of successful applications that don't use these containers and probably wouldn't have benefited much from them. Maybe some microservices implementations won't need them. But I do believe that others will. And of course the definition of the container depends upon where you look - just because it's not as obvious as the traditional Java container doesn't mean there's not a container somewhere, e.g., your operating system. However they're implemented, containers are useful and going container-less is really not an option.

Saturday, February 07, 2015

Container-less development

In the Java world been hearing a lot lately about container-less development. (Note, I'm not talking about containers such as docker.) Whether it's to help build microservices, to reduce complexity for Java EE developers, or some other reasons, moving away from containers seems to be the theme of the day. One of the core aims behind the movement away from containers appears to be simplifying the lives of application developers and that's definitely a good thing.

 In general anything we can do to improve the development experience is always a good thing. However, I worry that the idea of moving away from containers is not necessarily going to make the lives of developers easier in the long term. Let's spend a moment to look at some of the things we've heard as complaints for container-driven development. I'll paraphrase, but ... "They make it too complex to do easy things." Or "Containers are just too bloated and get in the way of agile development." Or "The notion of containers is an anti-pattern from the 20th century." Or even "Testing code in containers is just too hard."

Now before we try to address these concerns, let's look at something I said to Markus in a recent interview. "Any container, whether it's something like docker, the JVM or even a Java EE application server, shouldn't really get in your way as a developer but should also offer you the capabilities you need for building and running your applications in a way that is easy to use, understand and manage. If you think about it, your laptop is a container. The operating system is a container. We take these for granted because over the years we've gotten really really good at building them to be unobtrusive. Yet if you look under the covers at your typical operating system, it's doing a lot of hard work for you and offering you capabilities such as process forking and scheduling, that you don't know you need but you do need them."

It's easy to make blanket statements like "containers are bad for agile development" or "containers are not fit for modern web apps", but the reality is somewhat different. Of course there may be specific examples of containers where these statements are correct, but let's try and remain objective here! As I mentioned to Markus, we're using containers in our daily development lives and not even aware of them most of the time. A good container, whether an operating system or a Java EE application server, shouldn't get in your way but should be there when you need it. When you don't need it, it's sitting in the background consuming limited memory and processor time, perhaps still ensuring that certain bad things don't happen to your application while it's running and which you didn't even consider initially, e.g., how often do you consider that your operating system is providing red zone protection for the individual processes?

As I said, a good container shouldn't get in your way. However, that doesn't mean it isn't needed. Many applications start out a lot simpler than they end up. You may not consider security initially, for instance, but if your application/service is going to be used by more than you and especially if it's going to be available globally, then it's something you're going to need eventually and a good container should be able to either take care of that for you opaquely or offer a simple to use interface. In essence, a good (ideal?) container should be like your favourite operating system - doing things in the background that you need but don't want to really understand, and offering easy to use APIs for those services you do need.

For enterprise users (and I include Web developers in that category) those services would include security, data management (RDBMS, NoSQL), messaging (not everything will communicate using HTTP) and transactions (yes, some people may not like them but they're essential for many types of application to ensure consistency in a local and distributed case). I'm not going to suggest that there's any such thing as the ideal/perfect container in the Java world today. There are definitely some implementations that would want you to consider seriously looking at container-less solutions! However, there are several implementations that have made significant strides in improving the developer experience and pushing themselves into the background, becoming part of the substrate. And a number of developer tools have sprung up to help developers further, such as Forge and Arquillian.

If you consider what lead to the rise of containers, it wasn't because someone somewhere thought "Oh wouldn't it be good if I threw everything and the kitchen sink into a deployment environment". Believe it or not there was a time before containers. Back then we didn't have multi-threaded languages. Everything was interconnected individual services, communicating using bespoke protocols. Your application was probably one or more services and clients, again communicating to get things done. If all of these services ran on the same machine (entirely possible) then once again you could consider the operating system as your application deployment container.

These services were there for a reason though: applications needed them! The development of containers as we know them today was therefore a natural evolution given improvements in language capabilities and hardware performance (reduce the interprocess communication at the very least). Granted we may not have focussed enough on making the development of applications with containers a seamless and natural thing. But that doesn't obviate the need.

Consider the container-less approach. For some applications this may be the right approach, just as we've never said that container-based development (or Java EE) was right for all applications. But as the complexity of the application or individual service grows and there's a need for more functionality (e.g., caching or security) then application developers shouldn't have to worry about which caching implementation is the best for their environment, or which version works well with the other functional components they're relying upon. Eventually container-less frameworks will start to address these concerns and add the "missing" features, whether as interconnected individual (micro?) services in their own address spaces or co-located with the application code/business logic but (hopefully) in an opaque manner that doesn't get in the way of the developer. Once we start down that road we're heading towards something that looks very similar to a container.

Rather than throw away the inherent benefits of containers, I think we should be working to make them even easier to use. Maybe this requires changes in standards, where those containers are based upon them. Maybe it's giving feedback to the container developers on what's getting in the way. Maybe it's working with the container-less efforts to build next generation containers that fit into their development and deployment experience seamlessly. There are a number of ways this can go, but none of them are really container-less.