升级会告诉你,通过一些测试。如果你有一个由800多个模块组成的系统,你应该考虑在升级之前解决你的标准化问题——试着使用相同版本的依赖关系——比如JDBC驱动程序、日志JAR等等,并且在你的开发人员构建环境中使用相同的版本,这样每个人都可以一起完成相同的步骤——因此,如果某个版本失败了,就可以一起回滚舞台。
这个类将转储它在它扫描的任何目录或文件中看到的所有.class和.jar文件的版本。可能会有帮助。或者不是。
public class ShowClassVersions implements FileVisitor {
private static final byte[] CLASS_MAGIC = new byte[] {(byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe};
private static final byte[] bytes = new byte[8];
private TreeMap> vers = new TreeMap<>();
ShowClassVersions() {
}
private void scan(Path f) throws IOException {
if (Files.isDirectory(f)) {
Files.walkFileTree(f, this);
return;
}
record(f);
}
private static String versionOfFile(Path f) throws IOException {
String fn = f.getFileName().toString();
if (fn.endsWith(".class"))
return String.valueOf(versionOfClass(f));
if (fn.endsWith(".jar"))
return String.valueOf(versionOfJar(f));
return null;
}
public static String versionOfClass(Path p) throws IOException {
String version = null;
try(InputStream in = Files.newInputStream(p)) {
version = versionOfClass(in);
}
return version;
}
public static String versionOfClass(InputStream in) throws IOException {
String version = null;
int c = in.read(bytes);
if (c == bytes.length && Arrays.mismatch(bytes, CLASS_MAGIC) == CLASS_MAGIC.length) {
int minorVersion = (bytes[4] << 8) + (bytes[4] << 0);
int majorVersion = (bytes[6] << 8) + (bytes[7] << 0);
version = ""+majorVersion + "." + minorVersion;
}
return version;
}
public static String versionOfJar(Path p) throws IOException {
String version = null;
try(ZipInputStream in = new ZipInputStream(Files.newInputStream(p))) {
ZipEntry entry = null;
while (version == null && (entry = in.getNextEntry()) != null) {
if (entry.getName().endsWith(".class") /* && entry.getSize() > bytes.length */) {
version = versionOfClass(in);
}
}
}
return version;
}
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
record(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
void record(Path p) throws IOException {
String v = versionOfFile(p);
if (v != null) {
vers.computeIfAbsent(v, k -> new ArrayList()).add(p);
}
}
public static void main(String[] args) throws IOException {
ShowClassVersions v = new ShowClassVersions();
var files = Arrays.stream(args).map(Path::of).collect(Collectors.toList());
for (var f : files) {
v.scan(f);
}
for (var ver : v.vers.keySet()) {
System.out.println("Version: "+ver);
for (var p : v.vers.get(ver)) {
System.out.println(" "+p);
}
};
}
}