Meaningless Drivel is fun!*
The moose likes IDEs, Version Control and other tools and the fly likes How do you know the version of Java .class file? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Engineering » IDEs, Version Control and other tools
Bookmark "How do you know the version of Java .class file?" Watch "How do you know the version of Java .class file?" New topic
Author

How do you know the version of Java .class file?

Carl Miller
Greenhorn

Joined: Feb 25, 2012
Posts: 7
How do you know which version of a .java file that a Java .class file was compiled from?

The source files are stored in a Subversion system.

It seems you would have to put a version constant in the source file and then use javap to see the constant.

Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10425
    
    8

Welcome to the Ranch.

Carl Miller wrote:.
It seems you would have to put a version constant in the source file and then use javap to see the constant.

Yup. That's what the serialVersionUID is all about. More on it here http://docs.oracle.com/javase/1.5.0/docs/api/java/io/Serializable.html

Peter Johnson
author
Bartender

Joined: May 14, 2008
Posts: 5835
    
    7

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"
InnerClass:
final #254= #119 of #1; //Option=class org/jbia/perf/Analyzer$Option of class org/jbia/perf/Analyzer
minor version: 0
major version: 50
Constant pool:

Then you need to know how the version number corresponds to Java versions. That's where wikipedia comes in handy. See "byte offset" 7 in this table:
http://en.wikipedia.org/wiki/Java_class_file#General_layout

JBoss In Action
Peter Johnson
author
Bartender

Joined: May 14, 2008
Posts: 5835
    
    7

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.
Carl Miller
Greenhorn

Joined: Feb 25, 2012
Posts: 7
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?
Peter Johnson
author
Bartender

Joined: May 14, 2008
Posts: 5835
    
    7

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?

Yes.
Carl Miller
Greenhorn

Joined: Feb 25, 2012
Posts: 7
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)?
Peter Johnson
author
Bartender

Joined: May 14, 2008
Posts: 5835
    
    7

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.
Carl Miller
Greenhorn

Joined: Feb 25, 2012
Posts: 7
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.

Is that correct?
Peter Johnson
author
Bartender

Joined: May 14, 2008
Posts: 5835
    
    7

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.
 
GeeCON Prague 2014
 
subject: How do you know the version of Java .class file?