Java was introduced in 1995. It is suppose to be an object-oriented, cross-platform language that simplify the development of the World Wide Web era. As many of us joined the industry long after the born of Java, I think it will be useful to review the progress of Java over the years.
Promise of Java and popularity of Aplet
Before Java, programming languages are not cross-platform. All the applications (in that era context, desktop applications) are developed for a specific OS platform. The Window OS was in its early day and most of the enterprise applications were built for Unix. Cross-platform software was not a real concern until until World Wide Web getting more and more popular.
Developer want to provide richer experience to their website need to figure out some ways to provide more interaction to web page. The code/logic suppose to run on client machine rather than server, where developers got no idea which OS, platform is being used. The applet of Java provide a perfect solution to the problem. Let do not mention some other benefits of Java like garbage collection and fully object-oriented, cross-platform make development for client-side application become much easier and cheaper. This is the major limitation of popular languages at that time (C++, VB, Delphi), which make them cannot compete with Java on portable device or client.
Slowly, everything turn to Applet, static page is getting animated and content is dynamically generated. The protocol for Applet to communicate with server was RMI. The popular architecture is to have multiple applet, running on different browsers communication with a single server, which may include or connect to database.
However, as the browser wars scaled up and security became the major concern, applet seem to suffer heavily from the deviation of browser standards, sandbox and firewalls. If there are too many specific code to handle specific browsers, it is pointless to choose Java as the tool to develop client application. As applet is a fully functioned software that run on the client OS, it is quite easy for hacker to do harm to client computer. To prevent this threat, sandbox was introduced so that many Java API call will return SecurityException when being used in applet (for example accessing file system). Moreover, applet communication make use of RMI, which operate on other port rather than HTTP protocol which is often get blocked by client firewall
Another limit of applet is the singleton nature of RMI. RMI bound the service to a specific port, and use a single UnicastRemoteObject to serve all clients. To make the situation worse, Java Transaction API is not yet created until 1998. Without transaction isolation, the only way to make database action thread-safe is serialization of access, which is extremely punishing in term of performance.
The next era of Java observed the trend of shifting of processing from client back to server. As building the logic on client is harder and RMI is pretty limit of term of multi-thread, developer choose to build complicated logic on server side. The introduction of Servlet API make the task simpler. The format of content is simply dynamically generated HTML, served through HTTP protocol, which is firewall friendly. The Servlet is not thread safe but multi-threaded, and can be used to serve content for multiple requests.
As Java is getting more matured, many other APIs are created around this time to solve various concerns of building Java Enterprise Applications:
Java Server Pages
Enterprise Java Bean
Java Transaction API
All vendors attempted to lure customers with commercial APIs that help to build enterprise application. That pose a threat to the growing of Java ecosystem. To bring Java forward, industry leader discussed and introduced Java 2 Enterprise Edition (J2EE) in late 1999. The idea is to create a common standard, which will make enterprise application portable. J2EE was widely adopted with many vendor provide commercial application servers following the standard.
However, there are many mistakes in creating of J2EE, which were soon to be discovered. J2EE is too ambiguous, it left out many aspect in database handling such as connection pool, transaction isolation, locking mechanism. That left vendors with no other choice rather than build their own standards on top of J2EE. This make write one, run every where idea less and less practical.
Moreover, the choice of specifications to be parts of J2EE is questionable. EJB is criticized to be bloated. Deployment descriptor is long and cumbersome. The idea of providing home and remote interfaces make the specification repeated as developer got high chance to provide the same methods for both interface. The idea of letting the bean handling the persistence of itself make the class heavy, mixing business logic code with persistence logic. It is very unfortunate that before J2EE, there is already one Java technology named Java Blend that offer a clean implementation of ORM and operate on POJO object. However, EJB was chosen over Java Blend and developers need to write lots more code to do simple tasks.
Still, this is the period where Java is getting more and more popular. The introduction of .Net in late 2000 provided a solid alternative to J2EE to build enterprise application but Java was still dominating in Banking and Finance industry.
A new beginning
One of the things that Java outperform .NET is its vibrant community. It is famous for challenging the norm and provide alternative solutions than adopting it. Many awesome products are originated from Java community to fix/challenge the standard solution dictated by Sun. Let take a look at some of them:
Log4j is globally accepted as replacement over Java Logging API
Ant offer a solid automation tool for Java project
JodaTime offer cleaner and more intuitive API over Java Date Time API
Hibernate provide alternative approach of persistence which operate on POJO, pretty much similar to Java Blend.
Spring framework offer cleaner approach over EJB which operate on POJO
and many other products, ...
Getting tired with writing big chunks of code and cumbersome API, Java developers has shown creativity on designing cleaner and simple solution that most of the time easier to use and faster to run. The work contributed by the community is so impressive this time that it soon brought J2EE to obsoleted. Sun slowly adapt to the situation and let the community drive the development of Java. Many works and ideas are slowly absorbed to later version of Java EE.
In this era, Java observed to strong trend of simplify development and separating framework code with business logic. POJO, the class you wrote from the first day of Java was give a new name as Java Plain Old Object. Inheritance become the villain as it put framework related code to business logic. So how we attempt to guide framework to do all the hard work for us without inheriting some troublesome abstract class? It all done with XML and Java Reflection API.
Java reflection API has been introduced much earlier but it is not advisable to use due to performance issue. However the JVM performance has improve so much in those years that it finally become a viable option. Suddenly, the whole lots of possible solutions is open in front of designer eye. Dependency Injection become the norm of constructing bean. The persisted object also can be built using reflection. Also from Spring, it is recommended to only expose getter for what you do not want client to change value. That make the object immutable, which is safer and cleaner to pass around.
Another notable trend is the rise of AOP. There is nothing I like more than AOP when developing complicated system. AOP separate the concerns and let developer focus on business logic when framework owner focus on other concern like security, transaction or logging. The interceptor make upgrading or adding new feature to existing system cheaper and code is easier to read.
The exception handling is passed over to framework rather than handling in business logic code. In the early day of Java, we need to create and need to catch lots of exception. The code to handle exception cause disruption of logic when writing code. Moreover, without the simple improvement from Java 7, the API is repeated and troublesome to write. The reason behind this is the introduction of exception handler in framework. Instead of catching checked exception, developer can let the Runtime exception flow up all the way to exception handler, where it is being commonly processed.
Declarative programming has never been known in Java. If there is some works to be done, developer need to write code to make that happen. However, kudos to annotation, it is much easier to instruct framework to do work for you rather than do it yourselves. This idea is not new, it has been much wanted but annotation definitely a better choice than Java Doc to put your instruction.
Java is also adopting ideas from other languages. Convention over configuration is original suggested by RoR and adopted by Java. Comparing to my early day of configuring Spring 1.x, it is much lesser thing to configure with Spring 3.x. However, it is easier does not mean that you do not need to learn fundamental concept. I think it will benefit for developers to go through API and learn about things that they do not normally need to write to get a better understanding of system.
Other than above, there are some other minor trends that I can highlight here. Stateless Session over Stateful Session is introduced not to far ago. It make scaling and deploying application on cluster more natural. RestAPI is now implemented by JavaEE and almost all other framework. With Restful API, it is still convention over configuration. Developer depend on common-standard to write client rather than the early day Remote interface. The introduction of GWT and Android continue to push the border of Java forward and give more advantage to Java deveoper in job market. On the other side, JVM give other language an option of portability by compiling to byte-code. This also help to boost performance as JVM is very matured at this point of time.
By the time I wrote this article, it is pretty much all the same whether you choose which framework and server to build your application. Java community has gone through storming of idea and reach the common consensus of how should Java be developed. Still, the path above is widely open. The growing of social network set new requirement for the scalability and performance of applications. As usual Java is not lagging behind in pursuing new goals.
I think it is very soon for us to see noSql and big data become the norm of the new Java application. I also observe the trend of bringing AI and data analytic to daily activity. Google analytic become a must for most of products that I worked on over last few years. It is even more interesting that most of them have some kinds of AI integrated that help user on data mining and even decision making.
I also want to see GWT getting more popular. It is not simply because I belong to the static type language camp but also because GWT is improving quite fast. I have seen some of sophisticated website built on GWT that it is really difficult to know that from the look or feeling.
I also welcome the introduction of Lambda in Java 8. Writing anonymous class has been a pain for long. I hope we will get a way with it when Java 8 coming. Java suppose to provide better support on the era of multiple core CPU with Fork-Join framework but I do not find it API intuitive enough. That seem to be a problem to be fixed on the future. I still got irritated by the pseudo-generic introduced in Java 5. I think it is better to implement full generic or simply take it away.
Java API has been criticized of being too verbose. When I appreciate the clear and easy to read of Java code I hope Java adopt some more API from other lean languages like Rail to shorten the code on some part.
If all wishes come true, then long live Java.