Hot Code Replacement
Oracle’s traditional JVM enables hot code replace to some extent since version 1.4, when it was still from Sun.
If you were connected in debug mode (debug) through a suitable tool such as Eclipse, then the changes in recompiled classes would be injected into the JVM while it was still running.
However, there are several limitations: it is not possible to add or remove methods and attributes, change signatures and things like that.
On the other hand it is quite possible to create new classes, change the content of methods, inject values into variables while the execution is paused, etc.
Web applications
But talking specifically about web applications, that’s not all that matters. Often the container is configured to reload when it recognizes some change in certain files, such as the web.xml
, for example. Some IDE plugins trigger this process automatically when you change the code to ensure the application update.
In addition, application servers like Tomcat cache static content, including Jsps, images, and CSS. Tomcat 6, for example, was configured to make literally a copy of your entire application in a temporary folder. That’s good for production, but for development it’s a nightmare.
For details on these Tomcat issues, see ,eu article Avoid restarting Tomcat 6 and make startup faster. Probably not much different than Tomcat 7.
Java vs. Dynamic Languages
In a way, by comparing the "deploy" of PHP files with Java, is to compare bananas with oranges.
In PHP, simple copy of files is sufficient because in most cases it does not store state and interprets the files at each request. But think about the cost of this in relation to system performance.
The great benefit of Java in scalability is precisely an architecture that persists objects in memory and reuses them efficiently. The state of the system remains the same with each request and so the overall performance is much higher.
On the issue of availability for the user, although in general it is necessary to do the redeploy application, this can be remedied by using clusters and partial update thereof until all nodes receive updates.
The architecture of your application matters
Some frameworks work better than others. Depending on the type of change you are making, it can help or disrupt testing changes.
A very common detail in large applications is loading files .properties
internationalization (i18n). The problem is that the Bundles are not recharged if changed, at least not by default. Only some frameworks like struts2 or Spring allow you to configure them to reload the files with the translated texts without restarting the application.
In fact, many frameworks have a mode of development. For example, Primefaces in "dev" mode displays many details about errors and the context of facelet at the time of the exception, including variables that were in the request and session scopes.
Take advantage of this to avoid fixing the problems in "trial and error" and go straight to the problem. It is important to understand the mechanisms of your framework to achieve the best productivity.
Productivity in practice
With the knowledge of details about the IDE, the application server and the framework used, you can fine-tune your development environment and achieve much higher productivity, although you still have to carry out the server reboot when you make structural changes to your classes.
While tools can help, and many people agree that Jrebel helps, the best way to improve productivity is by changing the approach of developers. From my own experience I say that sometimes we test several possible solutions as trying to solve a labyrinth by brute force. Instead of focusing on the refresh facility to test various possibilities, think first more carefully about how the problem should be solved. This will greatly decrease the number of times you need to "fix and test" the application.