Q: 为什么需要CLASS文件版本管理?
A: 在JAVA容器中运行的是CLASS文件,如果没有有效的管理, 经过一段长时间后, 维护人员往往不能确定JAVA容器中的CLASS 对应的源source版本,从而给后期的维护带来了麻烦,为了从根本上解决这个问题,做到一劳永逸,我们需要对 CLASS文件进行版本管理。
如何对CLASS文件版本进行管理才能做到一劳永逸?
1.JAVA文件这样来写。
public class fooWithVersion{
public static String getClassRevision(){
return "$Revision: 1 $";
}
每次source文件被CHECK IN 时,次处会被VSS管理器自动设置为次文件的当前版本号
public class fooWithVersion{
public static String getClassRevision(){
return "$Revision: 2 $";
}
2.从CLASS文件中获取版本信息。
(1).反编译CLASS文件,获取JAVA源码,从中查看版本信息
常用反编译工具: jad
命令行: jad -o -r -sjava -d src bin/**/*.class
注:将 bin 下的class文件反编译到src中.(bin/包名/../*.class)
(2).自己写的小工具: classFileVersionTool文件夹(ClassReversion.class , etVersion.bat)
ClassReversion.class 通过批处理执行,批处理文件如下:
@echo off
java -cp C:/workspace/ApplicationTest/classes ClassReversion file.lock.FileLock getClassRevision
pause
C:/workspace/ApplicationTest/classes :引入目标文件的CLASS PATH
ClassReversion :我们的类文件名
file.lock.FileLock :目标文件(包名 + .文件名)
getClassRevision:目标文件中取得版本的方法
执行批处理后在classFileVersionTool文件夹中产生文件classversion.txt ,写入了版本信息
ClassReversion.class 源码
* @author lerrywang008 mailto:lerrywang008@hotmail.com
* @Date 070801
*/
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ClassReversion ... {
public String getClassReversion(String className, String versionMethod) ...{
String version = null;
try ...{
// ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// Class oclass = classLoader.loadClass(className);
// Class oclass = (Class)Class.forName(className);
Class oclass = (Class) Class.forName(className);
Method[] methods = oclass.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) ...{
if (methods[i].getName().equals(versionMethod)) ...{
Object o = null;
try ...{
o = oclass.newInstance();
Object out = methods[i].invoke(o, new Object[] ...{});
version = out.toString();
System.out.println("The class " + className +" file version : " + out.toString());
} catch (InstantiationException e) ...{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) ...{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) ...{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) ...{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} catch (ClassNotFoundException e) ...{
System.out.println(className + "--ClassNotFound--");
e.printStackTrace();
}
return version;
}
/** *//**
* @param args
*/
public static void main(String[] args) ...{
String className = null;
String versionMethod = null;
if (args.length > 1) ...{
className = args[0];
versionMethod = args[1];
} else ...{
int count = 0;
byte[] byteBuffer = new byte[1024];
try ...{
count = System.in.read(byteBuffer, 0, 1024);
className = new String(byteBuffer, 0, count - 2);
System.out.println("className : " + className);
count = System.in.read(byteBuffer, 0, 1024);
versionMethod = new String(byteBuffer, 0, count - 2);
System.out.println("versionMethod : " + versionMethod);
System.in.close();
} catch (IOException e) ...{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String version = new ClassReversion().getClassReversion(className, versionMethod);
File file = new File("classversion.txt");
System.out.println(file.getAbsolutePath());
try ...{
if (!file.exists())...{
file.createNewFile();
}
else...{
file.delete();
file.createNewFile();
}
FileOutputStream out = new FileOutputStream(file, true);
out.write(("The class " + className +" version is ").getBytes("utf-8"));
out.write(version.getBytes("utf-8"));
out.close();
} catch (Exception e) ...{
e.printStackTrace();
}
}
}
mailto:lerrywang008@hotmail.com