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:
开发者_运维问答Some parts of the project use
commons-io:commons-io, others usedorg.apache.commons:commons-ioThe wrong version of a dependency was used
staxuses the versions1.0-2and1.0.1. Using the automatic dependency resolution,1.0-2wins.
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?
@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);
}
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" ) );
}
}
加载中,请稍侯......
精彩评论