package org.jboss.shrinkwrap.resolver.test; | |
import java.io.File; | |
import org.jboss.shrinkwrap.api.Archive; | |
import org.jboss.shrinkwrap.api.ShrinkWrap; | |
import org.jboss.shrinkwrap.api.spec.WebArchive; | |
import org.jboss.shrinkwrap.resolver.api.DependencyResolvers; | |
import org.jboss.shrinkwrap.resolver.api.maven.Maven; | |
import org.jboss.shrinkwrap.resolver.api.maven.MavenConfigurationTypes; | |
import org.jboss.shrinkwrap.resolver.api.maven.MavenDependencyResolver; | |
import org.jboss.shrinkwrap.resolver.api.maven.MavenDependencyShortcut; | |
import org.jboss.shrinkwrap.resolver.api.maven.MavenImporter; | |
import org.jboss.shrinkwrap.resolver.api.maven.filter.CombinedFilter; | |
import org.jboss.shrinkwrap.resolver.api.maven.filter.DependenciesFilter; | |
import org.jboss.shrinkwrap.resolver.api.maven.filter.ExclusionFilter; | |
import org.jboss.shrinkwrap.resolver.api.maven.filter.ExclusionsFilter; | |
import org.jboss.shrinkwrap.resolver.api.maven.filter.ScopeFilter; | |
import org.jboss.shrinkwrap.resolver.api.maven.filter.StrictFilter; | |
/** | |
* Manifestation of various use cases for ShrinkWrap Maven Resolver | |
* | |
* @author <a href="mailto:kpiwko@redhat.com">Karel Piwko</a> | |
* | |
*/ | |
public class ShrinkResUsageManifest { | |
/** | |
* Use case 1: | |
* | |
* Resolve a single artifact without transitive dependencies as Archive<?> | |
*/ | |
public void singleArtifact() { | |
DependencyResolvers.use(MavenDependencyResolver.class).artifact("G:A:V").resolveAs(Archive.class, new StrictFilter()) | |
.iterator().next(); | |
// or, if GenericArchive is expected, following shortcut can be used | |
DependencyResolvers.use(MavenDependencyShortcut.class).dependency("G:A:V"); | |
// or even shorter | |
Maven.dependency("G:A:V"); | |
} | |
/** | |
* Use case 2: | |
* | |
* Resolve a single artifact without transitive dependencies as File | |
*/ | |
public void singleArtifactAsFile() { | |
DependencyResolvers.use(MavenDependencyResolver.class).artifact("G:A:V").resolveAsFiles(new StrictFilter()); | |
// or | |
DependencyResolvers.use(MavenDependencyShortcut.class).resolveAsFile("G:A:V"); | |
// or | |
Maven.resolveAsFile("G:A:V"); | |
} | |
/** | |
* Use case 3: | |
* | |
* Resolve a single artifact without transitive dependencies, using version from a POM file | |
*/ | |
public void singleArtifactWithPomFile() { | |
// !assignment error! | |
File f = DependencyResolvers.use(MavenDependencyResolver.class).loadEffectivePom("pom.xml").artifact("G:A") | |
.resolveAsFiles(new StrictFilter())[0]; | |
// or | |
f = DependencyResolvers.use(MavenDependencyResolver.class).loadEffectivePom("pom.xml").artifact("G:A").exclusion("*") | |
.resolveAsFiles()[0]; | |
// or | |
f = DependencyResolvers.use(MavenDependencyResolver.class).loadEffectivePom("pom.xml") | |
.importAnyDependencies(new DependenciesFilter("G:A")).resolveAsFiles(new StrictFilter())[0]; | |
// or | |
f = DependencyResolvers.use(MavenDependencyResolver.class).loadEffectivePom("pom.xml") | |
.importAnyDependencies(new DependenciesFilter("G:A")).resolveAsFiles(new DependenciesFilter("G:A"))[0]; | |
// or | |
DependencyResolvers.use(MavenDependencyShortcut.class).withPom("pom.xml").resolveAsFile("G:A"); | |
// or | |
Maven.withPom("pom.xml").resolveAsFile("G:A"); | |
// or using ShrinkWrap Maven plugin and current Maven execution | |
f = DependencyResolvers.use(MavenDependencyResolver.class).configureFrom(MavenConfigurationTypes.ENVIRONMENT) | |
.artifact("G:A").resolveAsFiles(new StrictFilter())[0]; | |
} | |
/** | |
* Use case 4: | |
* | |
* Resolve two or more artifacts without transitive dependencies | |
*/ | |
public void multipleArtifacts() { | |
DependencyResolvers.use(MavenDependencyResolver.class).artifact("G:A:V").artifact("G:B:V") | |
.resolveAsFiles(new StrictFilter()); | |
// or | |
DependencyResolvers.use(MavenDependencyResolver.class).artifacts("G:A:V", "G:B:V").resolveAsFiles(new StrictFilter()); | |
// or | |
DependencyResolvers.use(MavenDependencyShortcut.class).resolveAsFiles("G:A:V", "G:B:V"); | |
// or | |
Maven.resolveAsFiles("G:A:V", "G:B:V"); | |
} | |
/** | |
* Use case 5: | |
* | |
* Resolve an artifact with transitive dependencies | |
*/ | |
public void transitiveArtifact() { | |
DependencyResolvers.use(MavenDependencyResolver.class).artifact("G:A:V").resolveAsFiles(); | |
} | |
/** | |
* Use case 6: | |
* | |
* Resolve an artifact with transitive dependencies using extra exclusion | |
*/ | |
public void transitiveArtifactExtraExclusion() { | |
DependencyResolvers.use(MavenDependencyResolver.class).artifact("G:A:V").exclusion("G:B").resolveAsFiles(); | |
// or | |
DependencyResolvers.use(MavenDependencyResolver.class).artifact("G:A:V").resolveAsFiles(new ExclusionFilter("G:B")); | |
} | |
/** | |
* Use case 7: | |
* | |
* Resolve artifacts with transitive dependencies using extra exclusions | |
*/ | |
public void transitiveArtifactsExtraExclusions() { | |
DependencyResolvers.use(MavenDependencyResolver.class).artifact("G:A:V").exclusion("G:B").artifact("G:B:V") | |
.exclusion("G:C").resolveAsFiles(); | |
// or | |
DependencyResolvers.use(MavenDependencyResolver.class).artifact("G:A:V").artifact("G:B:V") | |
.resolveAsFiles(new ExclusionsFilter("G:B", "G:C")); | |
// or | |
// note, this does exclusion of both exclusions for both artifacts which is not same! | |
DependencyResolvers.use(MavenDependencyResolver.class).artifacts("G:A:V", "G:B:V").exclusions("G:B", "G:C") | |
.resolveAsFiles(); | |
} | |
/** | |
* Use case 8: | |
* | |
* Resolve an artifact with transitive dependencies, using pom for version | |
*/ | |
public void transitiveArtifactWithPom() { | |
DependencyResolvers.use(MavenDependencyResolver.class).loadEffectivePom("pom.xml").artifact("G:A").resolveAsFiles(); | |
// or using ShrinkWrap Maven plugin and current Maven execution | |
DependencyResolvers.use(MavenDependencyResolver.class).configureFrom(MavenConfigurationTypes.ENVIRONMENT) | |
.artifact("G:A").resolveAsFiles(); | |
} | |
/** | |
* Use case 9: | |
* | |
* Import the same dependencies as Maven would do. | |
*/ | |
public void mimickMavenDependencies() { | |
DependencyResolvers.use(MavenDependencyResolver.class).loadSettings("settings.xml").loadEffectivePom("pom.xml") | |
.importAnyDependencies(new ScopeFilter("compile", "runtime", "")).resolveAsFiles(); | |
// or using ShrinkWrap Maven plugin and current Maven execution | |
DependencyResolvers.use(MavenDependencyResolver.class).configureFrom(MavenConfigurationTypes.ENVIRONMENT) | |
.importAnyDependencies(new ScopeFilter("compile", "runtime", "")).resolveAsFiles(); | |
// or using MavenImporter, which does a bit different thing | |
ShrinkWrap.create(MavenImporter.class).loadSettings("settings.xml").loadEffectivePom("pom.xml") | |
.importAnyDependencies(new ScopeFilter("compile", "runtime", "")); | |
} | |
/** | |
* Use case 10: | |
* | |
* Import test dependencies and exclude G:A:V | |
*/ | |
public void importTestDependenciesWithExtraExclusion() { | |
DependencyResolvers.use(MavenDependencyResolver.class).loadEffectivePom("pom.xml") | |
.importTestDependencies(new ExclusionFilter("G:A")).resolveAsFiles(); | |
// or | |
DependencyResolvers.use(MavenDependencyResolver.class).loadEffectivePom("pom.xml").importTestDependencies() | |
.resolveAsFiles(new ExclusionFilter("G:A:V")); | |
// or | |
// note this would not work if G:A:V is a transitive dependency! | |
DependencyResolvers.use(MavenDependencyResolver.class).loadEffectivePom("pom.xml") | |
.importAnyDependencies(new CombinedFilter(new ScopeFilter("test"), new ExclusionFilter("G:A:V"))) | |
.resolveAsFiles(); | |
} | |
/** | |
* Use case 11: | |
* | |
* Import test dependencies and exclude arquillian/shrinkwrap/container (SHRINKRES-30) | |
*/ | |
public void importTestDependenciesWithArquillianExclusions() { | |
// solution 1 = enumerate within previous use case | |
// solution 2 = write a GroupExclusionFilter, note that MavenDependency has no getter for groupId! | |
// solution 3 = move shrinkwrap/arquillian/container to a distinct profile, then exclude it | |
} | |
/** | |
* Use case 12: | |
* | |
* Import a dependency using different classloader (SHRINKRES-26) | |
*/ | |
public void bootstrapShrinResWithDifferentClassloader() { | |
// not possible | |
} | |
/** | |
* Use case 13: | |
* | |
* Do the same as Maven would do | |
*/ | |
public void mimickMaven() { | |
ShrinkWrap | |
.create(WebArchive.class) | |
.addClasses(Class.class) | |
.addAsResource("resources") | |
.addAsLibraries( | |
DependencyResolvers.use(MavenDependencyResolver.class).loadEffectivePom("pom.xml") | |
.importAnyDependencies(new ScopeFilter("compile", "", "runtime")).resolveAsFiles()); | |
// or | |
// note current implementation is expecting mvn package to be run first (SHRINKRES-18) | |
ShrinkWrap.create(MavenImporter.class).loadEffectivePom("pom.xml").importBuildOutput(); | |
// note usage of ENVIRONMENT configuration is not possible | |
} | |
} |
This comment has been minimized.
This comment has been minimized.
Why is use case #3 returning an array of results instead of an iterator. I don't really have a preference as to which return type is best, but what is important is that it's consistent. Karel: => We are returning an Array for all cases, so we are consistent. reason given by what Archive.addAsLibrary(...) supports. No support for Iterator in ShrinkWrap. Yes, Arrays have disadvantages, but so has collections. |
This comment has been minimized.
This comment has been minimized.
In use case #13, my instinct is to rename importAnyDependencies to importAllDependencies. I would then read the statement as "import all dependencies that are of scope runtime or compile". At the moment, I can't recall why "any" is not appropriate here, but my gut tells me it's not. Karel: If importAllDependencies will add runtime and compile, how would user add "test" and "provided" ones? What about subsets? Dan: I was reading the example as it is coded. Of course, if you added different scopes, then the sentence would be different. I'm basically just saying that the word "Any" should be "All", grammatically speaking. |
This comment has been minimized.
This comment has been minimized.
When you are doing a single exclusion, I think that "exclude()" reads better than "exclusion()". Case in point:
In fact, this is consistent with the naming that Ivy uses. Although perhaps we can even be more explicit (at the cost of a few more characters):
...or something to that effect, to call out what you are excluding. Karel: exclusion is consistent with ...... from Maven. However, we can have a better naming if it makes more sense in Java API. |
This comment has been minimized.
This comment has been minimized.
There may be a better name for the StrictFilter, to make it more clear what it is being strict about. How about ExclusiveFilter, where exclusive means "select the artifact exclusively" (ignoring its friends). Another alternative is ExactFilter or even SingularFilter. Karel: Any more clear naming is welcomed. Note this we've discussed a proposal of resolution strategies, which might render StrictFilter obsolete. |
This comment has been minimized.
This comment has been minimized.
Dan, I've update your comments with my responses. I'm not sure if that will trigger notification, so I'm writing an extra comment just in case. |
This comment has been minimized.
This comment has been minimized.
Cool! Yep, you have to add a comment for the notification to kick in. |
This comment has been minimized.
This comment has been minimized.
Linking this back to the forum Thread from which this discussion is based: https://community.jboss.org/message/732721 |
This comment has been minimized.
This comment has been minimized.
I can't use DependencyResolvers, Do I need any additional thing in my POM file? |
This comment has been minimized.
This comment has been minimized.
This is my POM file:
|
This comment has been minimized.
Rather than the term "Shortcut", I recommend the term "Shorthand". Shorthand means "abbreviated writing to increase speed or brevity", so it fits rather perfectly.
Karel: => Makes sense. Note that this class should be hidden from user perspective or removed completely.