Code review is part of my job, and you cannot know the crap I’ve seen. Like someone pointed out, it’s also sometimes the crap I’ve written 🙂
In all cases, however, it’s because some developers do not have deep knowledge of how things work: most learnt something (in university or from a senior developer) years ago and don’t challenge this information regularly though technology evolve. Others just google the problem at hand and copy-paste the first snippet in their environment.
This little article is basically a how-to describing the right way to get a handle on the manifest in the context of a web application. It seems easy but there are many ways to do it and as far as I know only one is the right way at this moment.
To begin with, one baaddd way to do it would be this:
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("/META-INF/MANIFEST.MF");
Manifest manifest = new Manifest(inputStream);
Why so? Because dependending on your classloading strategy, you’ll fetch another manifest, that has nothing to do with the web application: for example, the above snippet will incidentally fetch the EAR manifest when using the default classloading strategy (Parent-First).
Another wrong code would be the following, for the same reason:
URL url = getClass().getProtectionDomain().getCodeSource().getLocation();
InputStream inputStream = url.openStream();
Manifest manifest = new Manifest(inputStream);
Finally, one could also try to get the war as a file, then read inside it: forget this path since we don’t know if the WAR will be wrapped in an EAR or deployed in exploded format (or not).
No, the only way (at the time of the writing of this post) is to use the API provided by an application server:
ServletContext application = getServletConfig().getServletContext();
InputStream inputStream = application.getResourceAsStream("/META-INF/MANIFEST.MF");
Manifest manifest = new Manifest(inputStream);