Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect which Guava version is used? [duplicate]

Tags:

java

guava

I have a project that uses an old Cassandra driver library, which relies on deprecated features of Guava that have been removed in release 20. I was thinking about adding a test that fails when someone accidentally increases the version of Guava from 19 to 20.

How can I programmatically find out which Guava version is used?

like image 828
Philipp Claßen Avatar asked Nov 30 '16 16:11

Philipp Claßen


People also ask

How do I know my guava version?

You can get a version string from files under META-INF/ in the guava. jar. At runtime you'll need to use appropriate ClassLoader instance in order to load the META-INF/ files you want.

What is guava version?

Guava is a suite of core and expanded libraries that include utility classes, google's collections, io classes, and much much more. Guava has only one code dependency - javax.

What is guava dependency used for?

Guava is an open-source “Collection Library” library for Java, developed by Google. It provides utilities for working with Java collections. As you dive deep into Guava you'll notice how it reduces coding errors, facilitates standard coding practices and boost productivity by making code concise and easy to read.

What is com Google guava guava?

Guava is a set of core Java libraries from Google that includes new collection types (such as multimap and multiset), immutable collections, a graph library, and utilities for concurrency, I/O, hashing, caching, primitives, strings, and more!


2 Answers

You can get a version string from files under META-INF/ in the guava.jar. At runtime you'll need to use appropriate ClassLoader instance in order to load the META-INF/ files you want. You can either use Guava's Resources utility class to load a resource with a unique name directly or you can iterate through resources with the same name across multiple jar files using $someGuavaClassName.class.getClassLoader().getResources(String). If you go with the latter then you will need to use someGuavaClassName that will exist in the version you are testing against. Resources itself has been in Guava since 1.0 and I don't suspect it going anywhere anytime soon so that should be a safe class to use.

I tested the following on Guava 20.0 and 12.0 and it worked for both. I suspect it will work for all relatively recent versions of Guava:

public class GuavaVersionFetcher {
    public static void main(String... args) throws IOException {
        System.out.println(determineGuavaMavenVersion());
        System.out.println(determineGuavaManifestVersion());
    }

    public static String determineGuavaMavenVersion() throws IOException {
        String resourceName = "META-INF/maven/com.google.guava/guava/pom.properties";
        Properties properties = new Properties();
        try (InputStream inputStream = Resources.getResource(resourceName).openStream()) {
            properties.load(inputStream);
        }
        return properties.getProperty("version");
    }

    public static String determineGuavaManifestVersion() throws IOException {
        Enumeration<URL> resources = Resources.class.getClassLoader()
                .getResources("META-INF/MANIFEST.MF");
        while (resources.hasMoreElements()) {
            Manifest manifest;
            try (InputStream inputStream = resources.nextElement().openStream()) {
                manifest = new Manifest(inputStream);
            }
            Attributes mainAttributes = manifest.getMainAttributes();
            String symbolicName = mainAttributes.getValue("Bundle-SymbolicName");
            if ("com.google.guava".equals(symbolicName)) {
                return mainAttributes.getValue("Bundle-Version");
            }
        }
        return null;
    }
}

Example output:

20.0
20.0.0

Note: If the Guava team ever moves away from using Maven the first method may no longer work so I suggest using the manifest method.

like image 164
mfulton26 Avatar answered Sep 17 '22 23:09

mfulton26


I did not find a simple way to get access to the version, but here is a solution that works for me:

@Test(expected = ClassNotFoundException.class)
public void mustNotUpgradeToGuava20_asItIsIncompatibleWithCassandra() throws ClassNotFoundException {
    Class.forName("com.google.common.graph.Graph");
}

This test passes up to Guava 19 and will fail with Guava 20. The Graph class is just the first hit of added classes that I found in the release notes.

like image 36
Philipp Claßen Avatar answered Sep 18 '22 23:09

Philipp Claßen