public JarNativeInfo()

in src/advisor/tools/graviton-ready-java/src/main/java/com/amazonaws/labs/GravitonReadyAssessor/JarNativeInfo.java [85:153]


    public JarNativeInfo(@NonNull Path realJarPath, Path nominalPath) throws IOException {
        this.realJarPath = realJarPath;
        this.nominalJarPath = nominalPath;

        if (nominalPath == null) {
            log.info("🛃 Checking JAR " + realJarPath);
        } else {
            log.info("🛃 Checking embedded JAR " + nominalPath.toString());
        }

        try {
            @Cleanup JarFile jarFile = new JarFile(realJarPath.toFile());
            final Enumeration<JarEntry> entries = jarFile.entries();

            while (entries.hasMoreElements()) {
                final JarEntry entry = entries.nextElement();
                final String entryName = entry.getName();

                if (entry.isDirectory()) continue;

                if (entryName.endsWith(".jar")) {
                    // Embedded JAR file
                    // Extract the JAR file to a temporary location
                    @Cleanup InputStream is = jarFile.getInputStream(entry);
                    Path tmpJarPath = Files.createTempFile(null, null);
                    tmpJarPath.toFile().deleteOnExit();
                    @Cleanup OutputStream os = Files.newOutputStream(tmpJarPath, APPEND);
                    is.transferTo(os);
                    // Process the embedded JAR recursively
                    JarNativeInfo nativeInfo = new JarNativeInfo(tmpJarPath, Path.of(entryName));
                    children.add(nativeInfo);
                } else if (entryName.endsWith(".class")) {
                    String className = entryName
                            .substring(0, entry.getName().length() - ".class".length())
                            .replace('/', '.');
                    // Skip JDK internal classes
                    if (Arrays.stream(IGNORED_PREFIXES).anyMatch(className::startsWith))
                        continue;
                    // Load the class and find its native methods
                    Class<?> c = loadClass(className, realJarPath);
                    if (c != null) {
                        try {
                            nativeMethods.addAll(findNativeMethods(c));
                        } catch (NoClassDefFoundError ignored) {
                        }
                    }
                }
            }

            // No need to proceed if there aren't any native methods.
            if (nativeMethods.isEmpty()) return;

            JarChecker scanner;

            // First try to find the shared libraries by scanning the JAR manifest
            scanner = new JarManifestScanner(jarFile);
            sharedLibs.addAll(scanner.getSharedLibraryPaths());

            // Then try to find shared libraries by examining the JAR table of contents
            scanner = new JarFileScanner(jarFile);
            sharedLibs.addAll(scanner.getSharedLibraryPaths());
        } catch (ZipException e) {
            // Treat empty JAR files as though they have no methods at all.
            if (e.getMessage().equals("zip file is empty")) {
                return;
            }
            throw e;
        }
    }