Reputation: 2931
We're currently using PHP and continuous deployment is plain simple. We've got a bare git repo on the server, Jenkins pushes to it and a git post receive hook does a checkout and moves a new symlink to the new version over the old symlink.
How could we do the same thing with a Java web project?
Should I investigate OSGI for this?
Upvotes: 2
Views: 296
Reputation: 2359
In general, you need to invest more effort into automating the process in Java than in PHP, given that Java requires at least compilation and that the infrastructure is different than PHP.
Based on your question it seems that you want to re-implement an existing PHP web application completely in Java, i.e. also the front end will be implemented in Java. Instead of re-implement the complete application in Java, you should discuss using Java for backend services only which might be stateless and don't require the use of a session. The frontend could be PHP and/or HTML only with a JavaScript framework (such as Angular, Ember, whatever), which calls the backend services directly.
If you want to develop a JavaEE style web application you need a container and package your application in a format deployable by the container. You can pick a servlet container such as Tomcat or Jetty and package your application as WAR file which is then deployed into the container. Assuming you follow that path, you need to decide whether you want to deploy the container as part of your application every time you deploy your application or require the container to be installed on the servers already.
Another option is to embed a servlet engine into your application or pick a different technology such as Vert.x which comes with yet another deployment model. There are pros and cons for either approach. I - personally - prefer packaging my application as a complete, ready to execute runnable, i.e. make the container part of the deployment.
I would recommend a CI server such as Hudson or Jenkins. It can poll a Git repository for changes and compile the Java code base once a new version was pushed. It's also possible to implement a Git hook which triggers a process in the CI server upon push.
The benefit of a CI service is that it comes with additional support for code analysis, testing and reporting on builds, which allows you to implement a decision making process into the deployment process. For example, if a build fails, has test errors or a code scan unveils potential security issues, the deployment will be aborted.
Assuming you use a CI service it's possible to deploy any "good" Git revisions at any time. Thus, the CI service could also be used for rollbacks.
You also need to think about deploying database updates. It could be done from within your application during boot/initialization. But that might become critical on rollback. Some changes aren't backwards/forward compatible. But this needs to be solved regardless of the technology, i.e. in Java as well as PHP.
I'm not sure OSGi is the solution/answer to this question. If downtime is critical for you, you need a HA solution anyway. No downtime deployments in OSGi or any other Java container are tough to implement. Given that a HA environment is necessary anyway, the effort is often not worth it (this is my personal opinion). Thus, I recommend not going down that path but leveraging the HA/load balancing infrastructure for this. Take down a node, deploy it, test it, bring it back into service - or if you run in a scriptable IaaS environment - get a new machine, deploy it, test it, bring it into service. Of course, all of this needs automation.
This also depends heavily on your infrastructure/architecture. But you probably want a session store separated from the containers (such as Memcache, Redis, other database). The session just contains data. Thus the code/application logic needs to deal with staleg/incompatible data in the sessions.
Any good container starts within a few seconds these days. It's the application which screws it up regularly. IoC containers (such as Spring or Guice) tend to initialize things eagerly at startup. That's not a bad thing but adds to the startup time till your application is ready. A lazy approach might be more helpful here especially if not all functionality is required on all nodes. Thus, it is possible to implement fast deployments even in Java. But it requires careful implementation.
Upvotes: 4