My current project involves building a commercial Java Web application. For years I’ve built Web applications (using Java and a number of other platforms) to deploy on our own servers. Building something that’s suitable for distribution is a horse of a different color. I thought I’d write up my experiences for other people who are taking on similar tasks.
- Distribution format – Usually Java applications are distributed as WAR or EAR files, but many people also package their Java Web applications with a servlet container to run them to make things easier.
- Open source licenses – My application uses a number of open source libraries, and I had to go through and make sure that all of the libraries were distributable without much fuss.
- Configuration – What’s the best way to set up database connections and other configuration parameters?
- Deployment platform – In theory, Java Web applications should work with any servlet container, but the devil is always in the details. Many Java applications seem to be distributed with a servlet container as well. What’s the best approach?
Look for separate posts dealing with each of those issues.
I’m sure other considerations will arise as well, but those are the first few that have cropped up as I’ve started working on this.
Embarking on this process makes it clear why PHP has become the dominant platform for writing distributable Web applications. Regardless of its strengths and weaknesses as a development platform, its deployment story is hard to beat.
There are no real questions when it comes to distribution format. You archive the files and put them up for download. The end user downloads the archive, expands it, and puts the files in the directory where they want the application to appear.
As far as licenses go, many PHP applications have no external dependencies. PHP provides all of the functionality you need for most applications, and PHP developers have never really taken to using libraries to make things easier. Java developers tend to use tons of third party libraries, and Ruby on Rails applications often depend on dozens of Gems. PHP developers use what’s available as part of PHP and that’s it. PEAR is out there, but it isn’t terribly popular. I assume that’s because so many PHP applications are deployed on shared hosting. It’s just not worth the risk to bring in dependencies if you don’t have to.
Configuring a PHP application usually involves editing one heavily commented PHP file. Most people consider that to be inelegant, but it’s hard to argue with the simplicity.
PHP is ubiquitous, so there’s not much to worry about in terms of deployment. You just need Apache with PHP support.
When you look at those factors as compared to Java or Ruby, it’s easy to see why PHP maintains its massive popularity over other development platforms, and why we see explosive growth among applications built using PHP, like Drupal, WordPress, and MediaWiki. For all its drawbacks, PHP has evolved in a world where simple deployment and configuration are both hugely important, and that has given PHP some powerful advantages that other platforms aren’t even trying to compete with.
Java coding style, accessor methods, and IDEs
Last week I was asked to answer a question about our code base and wound up with the wrong answer for what I think are interesting reasons. Thus, a few thoughts on the power of IDEs, the importance of coding standards, and a problem with the way Java handles accessor methods.
The application I work on queries an external datasource and then does stuff with the incoming data to provide a variety of results. I often get questions about how, exactly, we’re using that external data to make decisions. The incoming data is copied into Java classes which are persisted in the database using Hibernate.
My usual approach to answering these types of questions is to open Eclipse, find the appropriate accessor method for the value in question, and then use the fantastic “Find References” function to locate all the places in our code where we use that value. (It’s Command-Shift-G on your keyboard if you’re a Mac user.) If someone asked where a certain value originates, I start by pulling up all of the references to to the setter method. If someone asks how the value is being used, I find all of the references to the getter. Sometimes the sleuthing involves navigating through the code by finding a method that calls an accessor, then finding all the places that method is called, and so on.
For all of the hassle associated with building Java applications, the power of Java IDEs almost makes it worth it. I find it easy to be productive using TextMate to work on Ruby on Rails applications, but I always miss features like “Find References” and “Open Declaration” that are found in Eclipse. Eclipse, IntelliJ IDEA, and other Java IDEs build a semantic model of Java code that makes it very easy to manage your code that aren’t available when using other languages and editors. Any developer who’s avoided a bug because their IDE told them a local variable is never referenced anywhere knows exactly what I’m talking about.
Anyway, I had trouble figuring out how our code worked because I was investigating a feature written by another developer. The get method in question didn’t have any usages in our code base, and I assumed that while the value was being stored in the database, it was not incorporated into our business logic. I was asked to look again, and deeper inspection revealed that the member variable associated with the accessor I was searching for was accessed directly in other methods in its class.
When people talk about coding standards, this sort of thing is a bigger deal than bracket placement or tab size. My habit is to always use accessor methods if they’re available, whereas this other developer’s habit was to use the instance variables within the class. It’s probably better to do it one way or the other, or at least to have a clear understanding of why you might use one or the other in a given situation. The fact that we didn’t cost us a little wasted time, and could have been worse had I not reinvestigated and made sure that things were working as expected and not the way I thought they were.
This also underscores a drawback of the way Java handles accessor methods. Because accessors are regular methods, there are no easy ways to pull up all of the references to a particular variable that includes both references to the instance variable and to the accessors. It seems like Ruby accessors would lend themselves better to a more consistent approach. I’d also be curious to know whether the accessor implementation in C# leads to better tools.