Skip to content

Commit

Permalink
add classpath scan packages intersection validation
Browse files Browse the repository at this point in the history
  • Loading branch information
xvik committed Oct 12, 2015
1 parent a51824b commit d837e71
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
* Add classpath scan packages validation for intersection (to prevent duplicate instances)

### 3.1.0 (2015-09-06)
* JerseyProviderInstaller:
- add support for: ParamConverterProvider, ContextResolver, MessageBodyReader, MessageBodyWriter, ReaderInterceptor, WriterInterceptor,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package ru.vyarus.dropwizard.guice.module.installer.scanner;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import ru.vyarus.dropwizard.guice.module.installer.scanner.util.OReflectionHelper;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;

Expand All @@ -16,7 +20,7 @@ public class ClasspathScanner {
private final Set<String> packages;

public ClasspathScanner(final Set<String> packages) {
this.packages = packages;
this.packages = validate(packages);
}

/**
Expand All @@ -39,4 +43,30 @@ public void scan(final ClassVisitor visitor) {
}
}
}

/**
* @param packages specified packages
* @return original set if validation pass
* @throws IllegalStateException if packages intersect
*/
private Set<String> validate(final Set<String> packages) {
final List<String> pkg = Lists.newArrayList(packages);
Collections.sort(pkg, new Comparator<String>() {
@Override
public int compare(final String o1, final String o2) {
return Integer.compare(o1.length(), o2.length());
}
});
for (int i = 0; i < pkg.size(); i++) {
final String path = pkg.get(i);
for (int j = i + 1; j < pkg.size(); j++) {
final String path2 = pkg.get(j);
Preconditions.checkState(!path2.startsWith(path + "."),
"Autoscan path '%s' is already covered by '%s' and may lead "
+ "to duplicate instances in runtime",
path2, path);
}
}
return packages;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package ru.vyarus.dropwizard.guice.unit

import ru.vyarus.dropwizard.guice.AbstractTest
import ru.vyarus.dropwizard.guice.module.installer.scanner.ClasspathScanner

/**
* @author Vyacheslav Rusakov
* @since 01.10.2015
*/
class PackagesValidationTest extends AbstractTest {

def "Check packages integrity validation"() {

when: "duplicate subpackage"
new ClasspathScanner(['com.pack', 'com.pack.sub'] as Set)
then: "not allowed"
thrown(IllegalStateException)

when: "duplicate subpackage inverse order"
new ClasspathScanner(['com.pack.sub', 'com.pack'] as Set)
then: "not allowed"
thrown(IllegalStateException)

when: "valid packages"
new ClasspathScanner(['com.pack.sub', 'com.pack.sub2', 'com.pack.sub3.foo'] as Set)
then: "valid"
true

when: "duplicate subpackage"
new ClasspathScanner(['com.pack.sub', 'com.pack.sub2', 'com.pack.sub3.foo', 'com.pack.sub.bar'] as Set)
then: "not allowed"
thrown(IllegalStateException)
}
}

0 comments on commit d837e71

Please sign in to comment.