Reputation: 804
In my example, I need to resolve a dependency whose artifacts don't have the conventional jar
as the packaging type, but rather maven-plugin
(more concretely, the artifact i'm interested in is a Maven plugin). This, in Maven land, is specified via the <packaging>
XML tag.
When I add the plugin my project depends on in the sbt build, sbt successfully updates the project but the resolved dependency is not in the classpath. How can I get sbt to add the artifact to my classpath so that code that depends on such dependency compiles?
Code that I used to add the maven plugin to my build:
libraryDependencies += "net.alchim31.maven" % "scala-maven-plugin" % "3.3.1"
Upvotes: 0
Views: 646
Reputation: 804
There are two reasons why sbt doesn't add the desired artifact to the classpath, and hence compilation fails.
The first reason is that, by default, sbt only recognises artifacts whose packaging type is limited (jar
, bundle
and a few more). In order to tell sbt we're interested in an artifact whose packaging type is maven-plugin
, we'll need to explicitly tell which artifacts we want from the dependency with:
libraryDependencies += ("net.alchim31.maven" % "scala-maven-plugin" % "3.3.1")
.withExplicitArtifacts(Vector("scala-maven-plugin", "maven-plugin", "jar"))
Once we've done this, we can confirm that sbt did indeed get our artifact by running the following code in consoleProject
:
Keys.update.in(myScope).in(myProject).eval.allFiles
.find(_.getAbsolutePath.contains("net"))
Note that myScope
must be either Compile
, Test
or Runtime
(usually, it's Compile
) and that myProject
must be a reference to the project you have declared the dependency in. The result of the previous operation, if everything has gone well, will be Some(...)
, indicating that the artifact was indeed resolved and detected.
However, we're not done. If we run myProject/dependencyClasspath
, this time from the sbt shell, we won't see our artifact there. This is where the second step is required: we need to add our new packaging type to classpathTypes
so that sbt adds the artifact to our compilation classpath.
classpathTypes += "maven-plugin"
With all this done, we should run myProject/dependencyClasspath
and see our artifact present.
But the story is not over, and here we enter "bug" territory. Sbt does not automatically add the packaging types in classpathTypes
to the pom configuration that is responsible for declaring the dependencies in the pom file. Note that otherwise your application will fail with ClassNotFoundException
or a similar issue because not all the dependent artifacts have been resolved and classloaded.
So in order to have a working application, you'll need to do it yourself:
makePomConfiguration :=
makePomConfiguration.value.withIncludeTypes(classpathTypes.value)
The fact that this is not done by default it's just an sbt bug in 1.x.
Upvotes: 2