Created
March 17, 2012 11:19
-
-
Save soren/2057725 to your computer and use it in GitHub Desktop.
Perl script that can determine the version of a java class file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
use warnings; | |
use strict; | |
use Pod::Usage; | |
=head1 NAME | |
java_class_version.pl - determines the version of a java class file | |
=head1 USAGE | |
java_class_version.pl [class file ...] | |
Example: | |
$ java_class_version.pl *.class | |
AbstractFacesServlet.class 6 (1.6) (50.0) | |
AbstractFacesServlet$InnerFacesContext.class 6 (1.6) (50.0) | |
DocumentServlet.class 6 (1.6) (50.0) | |
=head1 OPTIONS | |
No options. But if you call the script without any class file names it | |
will display its manual page. | |
=head1 DESCRIPTION | |
This script can tell you the version of a java class file. This can | |
come in handy if you want to deploy some third party jar on an older | |
platform. You don't need to do a try-and-error, but can determine | |
compability upfront. | |
The class file format is descibed in [ClassFile.doc]. The important | |
parts are the first eight bytes, that contain a magic number, the | |
minor and the major version of the file. It looks like this for a java | |
5 class file: | |
+----+----+----+----+----+----+----+----+ | |
| ca | fe | ba | be | 00 | 00 | 00 | 31 | | |
+----+----+----+----+----+----+----+----+ | |
| magcic number | minor | major | | |
+-------------------+---------+---------+ | |
The integers are always stored in big-endian order, also know as | |
network order. | |
What java platform supports which class file version is a little fuzzy | |
for the first 1.0 and 1.1 releases. But | |
[source_target_class_file_version] has a nice summary, that at least | |
is simple for all later releases. | |
=for text | |
=encoding utf-8 | |
=end | |
=head1 AUTHOR | |
Søren Lund, C<< <soren at lund.org> >> | |
=head1 SEE ALSO | |
=over | |
=item [ClassFile.doc] | |
http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html | |
=item [source_target_class_file_version] | |
http://blogs.sun.com/darcy/entry/source_target_class_file_version | |
=back | |
=head1 COPYRIGHT | |
Copyright (C) 2012 Søren Lund | |
This program is free software; you can redistribute it and/or modify | |
it under the terms of the GNU General Public License as published by | |
the Free Software Foundation; version 2 dated June, 1991 or at your option | |
any later version. | |
This program is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU General Public License for more details. | |
A copy of the GNU General Public License is available in the source tree; | |
if not, write to the Free Software Foundation, Inc., | |
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
=cut | |
my %java_platforms = ( | |
"45.3" => "1.1", | |
"46.0" => "1.2", | |
"47.0" => "1.3", | |
"48.0" => "1.4", | |
"49.0" => "5 (1.5)", | |
"50.0" => "6 (1.6)", | |
"51.0" => "7 (1.7)" | |
); | |
pod2usage(-verbose => 2) if $#ARGV < 0; | |
foreach my $arg (@ARGV) { | |
open my $file, '<', $arg or die $!; | |
my $magic = read_int($file, 4); | |
if ($magic != 0xcafebabe) { | |
printf STDERR "%s is not a valid Java class.\n", $arg; | |
} else { | |
my $minor = read_int($file, 2); | |
my $major = read_int($file, 2); | |
my $version = sprintf("%d.%d", $major, $minor); | |
printf "%s %s (%s)\n", $arg, $java_platforms{$version}, $version; | |
} | |
close $file; | |
} | |
sub read_int { | |
my ($file, $size) = (@_); | |
my $data; | |
read $file, $data, $size; | |
return unpack($size==2?'n':'N',$data); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment