Or are you asking how can you know if a .class file was compiled with the 1.5 or 1.6 or 1.7 JDK? To do that, run the javap command with the -verbose option and look for the major.version value. Example:
>javap -classpath . -verbose org.jbia.perf.Analyzer
Compiled from "Analyzer.java"
public class org.jbia.perf.Analyzer extends java.lang.Object SourceFile: "Analyzer.java"
final #254= #119 of #1; //Option=class org/jbia/perf/Analyzer$Option of class org/jbia/perf/Analyzer
minor version: 0
major version: 50
Or rereading your question again, it seems that you want to know the Subversion revision number of the source file that was used to build a .class file. Here's what we do. Our builds are performed by Jenkins which automatically set a SVN_REVISION env var, and we use that value in our Maven builds to add the revision number to the artifact version number, and also add this revision number into the MANIFEST.MF file. Then we can look at any JAR and know where the source came from, revision wise.
Joined: Feb 25, 2012
Thank you. Very helpful. Yes, given a .class file I want to know the version of the source, that would be the Subversion revision number. (I have not used Subversion, so I did not know how to say it.)
If someone makes one small change (bug fix) to a source file and if you need to deploy that change, then would you build a whole new jar file with a new Subversion revision number in the MANIFEST.MF file?
Carl Miller wrote:If someone makes one small change (bug fix) to a source file and if you need to deploy that change, then would you build a whole new jar file with a new Subversion revision number in the MANIFEST.MF file?
Joined: Feb 25, 2012
If a web application under Apache Tomcat is deployed by copying a directory (and subdirectories) instead of a .war file, how do people know the versions of the servlets and other .class files (several weeks or months later)?
Because even a WAR file can have a MANIFEST.MF file, and it will have the revision number of the most recently changes servlet. All other servlets will also be at that revision number (caveat: unless for some reason when you compiled the latest set of servlets you threw away the class files for some of the servlets, which I rather doubt.)
Here is an example (ignore the caveat for now).
For a given web app project, servlets A, B and C are all at revision 10, and that is what is deployed. Someone makes a change to servlet C and it is now at revision 11, so that is the revision in the manifest. Actually, all of the servlets are now at that revision. In other words, you could recompile all three servlets using revision 11 to pull the sources out of Subversion, and servlets A and B will be built exactly the same as if they were build from revision 10 sources.
I guess the point is that knowing the revision numbers when something was originally changed is not that important. (Actually, if you look at the revision history of a single file, you will also see this phenomenon. For example, the revision history for servlet A might be revision 2, 5 and 10. Actually, any revision number from 5 to 9 will yield that same source for that servlet. Thus you could assume that the second change could be any of those revisions.)
Now for the caveat. What I mean is something like this. Let's say both servlets B and C are changed again, so the revision number is now at 12. But for some reason you decide to build C but not B and deploy just C. Now you no longer know a useful revision number in the manifest because you can no longer rebuild A, B and C using 12 as the revision number. Obviously this is not something that you want to be doing. And if you use a CI system such as Jenkins to perform your production builds, things like this won't happen because it is way to difficult to convince Jenkins to do something like this. However, if you let developer perform production builds and deploy them, then you are asking for problems like this.
Joined: Feb 25, 2012
Thank you. Very nice explanation and helpful insights.
The Subversion revision number in the manifest can help us to answer many useful questions (where is the source code for file A, what changes were made to file A for this deploy, when was the last time file A was changed) by examining the repository history.
Suppose one file in the production directory is accidently deleted and is restored from a backup site. We cannot be sure this file belongs to Subversion revision 10 (that there was no mistake in selecting the backup) by examining the file.
Suppose someone accidently overwrites a file (copies a file to production instead of test, or copies TO the directory instead of FROM the directory, etc.) or maybe intentionally replaces one file. Other than the filesize and timestamp, the file does not tell us where it came from.
You are posing variations of the theme in my last paragraph. If you let people mess with the deployment, then all bets are off. The only way to guarantee the identification scheme is to ensure that only automated processes are mucking with production.