private static Version readImplementationVersion()

in apm-agent-plugin-sdk/src/main/java/co/elastic/apm/agent/sdk/bytebuddy/CustomElementMatchers.java [233:303]


    private static Version readImplementationVersion(@Nullable ProtectionDomain protectionDomain, @Nullable String mavenGroupId, @Nullable String mavenArtifactId) throws IOException, URISyntaxException {
        Version version = null;
        JarFile jarFile = null;

        if (protectionDomain == null) {
            logger.info("Cannot read implementation version - got null ProtectionDomain");
            return null;
        }

        try {
            CodeSource codeSource = protectionDomain.getCodeSource();
            if (codeSource != null) {
                URL jarUrl = codeSource.getLocation();
                if (jarUrl != null) {
                    // does not yet establish an actual connection
                    URLConnection urlConnection = jarUrl.openConnection();
                    if (urlConnection instanceof JarURLConnection) {
                        jarFile = ((JarURLConnection) urlConnection).getJarFile();
                    } else {
                        jarFile = new JarFile(new File(jarUrl.toURI()));
                    }

                    // read maven properties first as they have higher priority over manifest
                    // this is mostly for shaded libraries in "fat-jar" applications
                    if (mavenGroupId != null && mavenArtifactId != null) {
                        ZipEntry zipEntry = jarFile.getEntry(String.format("META-INF/maven/%s/%s/pom.properties", mavenGroupId, mavenArtifactId));
                        if (zipEntry != null) {
                            Properties properties = new Properties();
                            try (InputStream input = jarFile.getInputStream(zipEntry)) {
                                properties.load(input);
                            }
                            if (mavenGroupId.equals(properties.getProperty("groupId")) && mavenArtifactId.equals(properties.getProperty("artifactId"))) {
                                String stringVersion = properties.getProperty("version");
                                if (stringVersion != null) {
                                    version = Version.of(stringVersion);
                                }
                            }
                        }
                    }

                    // reading manifest if library packaged as a jar
                    //
                    // doing this after maven properties is important as it might report executable jar version
                    // when application is packaged as a "fat jar"
                    if (version == null) {
                        Manifest manifest = jarFile.getManifest();
                        if (manifest != null) {
                            Attributes attributes = manifest.getMainAttributes();
                            String manifestVersion = attributes.getValue("Implementation-Version");
                            if (manifestVersion == null) {
                                // fallback on OSGI bundle version when impl. version not available
                                manifestVersion = attributes.getValue("Bundle-Version");
                            }
                            if (manifestVersion != null) {
                                version = Version.of(manifestVersion);
                            }
                        }
                    }
                }
            }
        } finally {
            if (jarFile != null) {
                try {
                    jarFile.close();
                } catch (IOException e) {
                    logger.error("Error closing JarFile", e);
                }
            }
        }
        return version;
    }