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:[email protected]
* @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();
}
}
}