-1

Ours is a legacy Java project, which is maintained for more than 15 years. We have more than 800 modules.

From struts to spring, variety of framework have been used. Based upon the need at that time, developers has chosen the framework and done the development. So there is no standardization.

Now we have requirement to upgrade JDK from 1.6 to 1.8 version.

  1. Is there any way to know easily, which frameworks will have a impact?
  2. Whether any information available as API, to get the JDK version of any framework?

Pls let me know know....

MohanGV
  • 59
  • 1
  • 1
  • 4

2 Answers2

0

Is there any way to know easily, which frameworks will have a impact?

There is no easy way.

You need to read the documentation for each framework you are using to find out if you need to upgrade it.

Or just try upgrading the Java platform and see what breaks. (As a general rule, things won't break in the Java 6 to Java 8 migration. More stuff breaks in Java 8 to Java 11 ... but that's not what you are doing now.)

Whether any information available as API, to get the JDK version of any framework?

There is no such API.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

Upgrading will tell you, with some testing. If you have a system of 800+ modules you should consider addressing your standardisation issues before you upgrade - try to use same versions of your dependencies - such as JDBC drivers, logging jars etc, and same for your developer build environments so everyone can make the same step together - and therefore rollback together if it fails at some stage.

This class will dump out versions of all .class and .jar files it sees in any directories or files it scans. It may help. Or not.

public class ShowClassVersions {
    private TreeMap<String, ArrayList<String>> vers = new TreeMap<>();
    private static final byte[] CLASS_MAGIC = new byte[] { (byte) 0xca, (byte) 0xfe, (byte) 0xba, (byte) 0xbe };
    private final byte[] bytes = new byte[8];

    private String versionOfClass(InputStream in) throws IOException  {
        int c = in.readNBytes(bytes, 0, bytes.length);
        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);
            return ""+ majorVersion + "." + minorVersion;
        }
        return "Unknown";
    }

    private Matcher classes = Pattern.compile("\\.(class|ear|war|jar)$").matcher("");

    // This code scans any path (dir or file):
    public void scan(Path f) throws IOException {
        try (var stream = Files.find(f, Integer.MAX_VALUE,
                (p, a) -> a.isRegularFile() && classes.reset(p.toString()).find())) {
            stream.forEach(this::scanFile);
        }
    }

    private void scanFile(Path f) {
        String fn = f.getFileName().toString();
        try {
            if (fn.endsWith(".ear") || fn.endsWith(".war") || fn.endsWith(".jar"))
                scanArchive(f);
            else if (fn.endsWith(".class"))
                store(f.toAbsolutePath().toString(), versionOfClass(f));
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    private void scanArchive(Path p) throws IOException {
        try (InputStream in = Files.newInputStream(p)) {
            scanArchive(p.toAbsolutePath().toString(), Files.newInputStream(p));
        }
    }

    private void scanArchive(String desc, InputStream in) throws IOException {
        HashSet<String> versions = new HashSet<>();
        ZipInputStream zip = new ZipInputStream(in);
        for (ZipEntry entry = null; (entry = zip.getNextEntry()) != null; ) {
            String name = entry.getName();
            // There could be different compiler versions per class in one jar
            if (name.endsWith(".class")) {
                versions.add(versionOfClass(zip));
            } else if (name.endsWith(".jar") || name.endsWith(".war")) {
                scanArchive(desc + " => " + name, zip);
            }
        }
        if (versions.size() > 1)
            System.out.println("Warn: "+desc+" contains multiple versions: "+versions);

        for (String version : versions)
            store(desc, version);
    }

    private String versionOfClass(Path p) throws IOException {
        try (InputStream in = Files.newInputStream(p)) {
            return versionOfClass(in);
        }
    }

    private void store(String path, String jdkVer) {
        vers.computeIfAbsent(jdkVer, k -> new ArrayList<>()).add(path);
    }

    // Could add a mapping table for JDK names, this guesses based on (JDK17 = 61.0)
    public void print() {
        for (var ver : vers.keySet()) {
            System.out.println("Version: " + ver + " ~ " +jdkOf(ver));
            for (var p : vers.get(ver)) {
                System.out.println("   " + p);
            }
        }
    }

    private static String jdkOf(String ver)  {
        try {
            return "JDK-"+((int)Float.parseFloat(ver)-44);
        }
        catch(NumberFormatException nfe)
        {
            return "JDK-??";
        }
    }

    public static void main(String[] args) throws IOException {
        var files = Arrays.stream(args).map(Path::of).collect(Collectors.toList());
        ShowClassVersions v = new ShowClassVersions();
        for (var f : files) {
            v.scan(f);
        }
        v.print();
    }
}
DuncG
  • 12,137
  • 2
  • 21
  • 33