Aaron Digulla
Aaron Digulla

Reputation: 328556

Verify dependencies in a Maven build

Is there a way to write a test that checks Maven dependencies?

In our project, we found these problems:

So what I want is to write a test case which takes the current dependency tree as input and runs a couple of checks on it. Is that possible?

Upvotes: 3

Views: 406

Answers (2)

palacsint
palacsint

Reputation: 28865

@Test
public void testCommonsIo() throws Exception {
    assertDependencyVersion("commons-io", "commons-io", "2.0");
}

private void assertDependencyVersion(final String groupId, 
        final String artifactId, final String expectedVersion) 
        throws IOException {

    final StringBuilder sb = new StringBuilder("/META-INF/maven/");
    sb.append(groupId).append("/").append(artifactId);
    sb.append("/pom.properties");
    final String resourcePath = sb.toString();

    final InputStream propertiesStream = this.getClass()
        .getResourceAsStream(resourcePath);
    assertNotNull("no dependency found: " + groupId + ":" + artifactId, 
        propertiesStream);

    final Properties properties = new Properties();
    properties.load(propertiesStream);

    assertEquals("group", groupId, properties.getProperty("groupId"));
    assertEquals("artifact", artifactId, properties.getProperty("artifactId"));
    assertEquals("version", expectedVersion, properties.getProperty("version"));
}

Check this answer too.


Here is an assert method for StAX and other dependencies which don't contain pom.properties just manifest.mf. Maybe it would worth caching the Properties instances if there are lots of assertDependencyByMetaInf calls.

@Test
public void testStaxDependency() throws Exception {
    assertDependencyByMetaInf("StAX", "1.0.1");
}

private void assertDependencyByMetaInf(final String specTitle, 
        final String expectedSpecVersion) throws IOException {
    final ClassLoader cl = this.getClass().getClassLoader();

    final String resourcePath = "META-INF/MANIFEST.MF";
    final Enumeration<URL> resources = cl.getResources(resourcePath);

    boolean found = false;
    while (resources.hasMoreElements()) {
        final URL url = resources.nextElement();
        final InputStream metaInfStream = url.openStream();

        final Properties metaInf = new Properties();
        metaInf.load(metaInfStream);

        final String metaInfSpecTitle = 
            metaInf.getProperty("Specification-Title");
        if (!specTitle.equals(metaInfSpecTitle)) {
            continue;
        }

        final String specVersion = 
            metaInf.getProperty("Specification-Version");
        assertEquals("version mismatch for " + specTitle, 
            expectedSpecVersion, specVersion);
        found = true;
    }
    assertTrue("missing dependency: " + specTitle, found);
}

Upvotes: 1

Aaron Digulla
Aaron Digulla

Reputation: 328556

Following the advice from palacsint, here is another approach: Count how often a class is on the classpath and print the URLs if there is more than one.

private void assertOnceOnClassPath( String resourcePath ) throws IOException {
    ClassLoader cl = getClass().getClassLoader();

    Enumeration<URL> resources = cl.getResources( resourcePath );
    List<URL> urls = new ArrayList<URL>();
    while( resources.hasMoreElements() ) {
        URL url = resources.nextElement();
        urls.add( url );
    }

    if( urls.size() != 1 ) {
        fail( "Expected exactly 1 item:\n" + StringUtils.join( urls, "\n" ) );
    }
}

Upvotes: 0

Related Questions