Maven has the optional dependency concept. Search of the SBT documentation for optional dependencies finds only "However, sometimes we have optional dependencies for special features.".
How can I declare an optional dependency in SBT?
Unfortunately SBT documentation doesn't list all available scopes that map to Ivy Configurations, but the source code does: https://github.com/sbt/sbt/blob/0.13/ivy/src/main/scala/sbt/Configuration.scala
You can do this in the same way you scope a dependency for test, runtime or provided scope.
libraryDependencies += "group id" % "artifact id" % "version" % "optional"
or
libraryDependencies += "group id" % "artifact id" % "version" % Optional
Related
I'm trying to weave the testing library scalatest (https://mvnrepository.com/artifact/org.scalatest/scalatest_2.12/3.2.0-SNAP10). This library dependency is in my build.sbt:
enablePlugins(SbtAspectj)
libraryDependencies += "org.scalactic" %% "scalactic" % "3.0.5"
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test"
aspectjInputs in Aspectj ++= update.value.matching(moduleFilter(organization = "com.typesafe.akka", name = "akka-actor*"))
aspectjInputs in Aspectj ++= update.value.matching(moduleFilter(organization = "org.scalatest", name = "scalatest*"))
fullClasspath in Runtime := aspectjUseInstrumentedClasses(Runtime).value ++ aspectjUseInstrumentedClasses(Test).value
Looking at the maven website it lists several other optional dependencies such as org.jmock, etc.
The problem is that SBT only downloads scalatest.jar and not jmock.jar (along the other optional dependencies). Printing out the aspectjInputs indeed does show scalatest.jar, but not jmock.jar.
Because of that reason (?), it gives me the following errors:
[error] error at (no source information available)
[error] /Users/jonas/.ivy2/cache/org.scalatest/scalatest_2.12/bundles/scalatest_2.12-3.0.5.jar:0::0 can't determine superclass of missing type org.jmock.Expectations
[error] when weaving type org.scalatest.jmock.JMockExpectations
[error] when weaving classes
[error] when weaving
[error] when batch building BuildConfig[null] #Files=1 AopXmls=#0
[error] [Xlint:cantFindType]
I'm assuming that I somehow need the .jar file of the optional dependencies of ScalaTest, but as they are not downloaded by sbt, I'm lost on how to solve this.
So, how can I resolve them or add them to the classpath when the weaving happens?
I'm using the aspectj-sbt plugin.
You can include the optional dependencies with a configuration mapping like this:
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test->compile,optional"
We assemble multiple projects into one jar:
val asmDep = "org.scala-lang.modules" % "scala-asm" % "5.0.3-scala-3"
lazy val compiler = (project in file(".") / "src" / "compiler")
.settings(
libraryDependencies ++= Seq(asmDep),
mappings in Compile in packageBin :=
(mappings in Compile in packageBin).value ++
(mappings in Compile in packageBin in LocalProject("interactive")).value ++
[...])
I'd like to also include the content of the asmDep dependency (it's a single JAR) into the project package. Is there an easy way to get that?
You want to use sbt-assembly.
I'm not sure if asmDep is the only dependency out of many in your project you want to add to your package or not, but there's a few different configuration options available in sbt-assembly that might suit your needs.
I have a project that uses sbt 0.13.6 with the assembly 0.12.0 plugin to create the farJar. My build.sbt is:
name := "test"
version := "0.0.1"
scalaVersion := "2.10.4"
libraryDependencies ++= Seq(
("org.apache.kafka" % "kafka_2.10" % "0.8.0" % "provided").
exclude("javax.jms", "jms").
exclude("com.sun.jdmk", "jmxtools").
exclude("com.sun.jmx", "jmxri").
exclude("org.slf4j", "slf4j-simple")
)
When I run sbt assembly I get a file called target/scala-2.10/test-assembly-0.0.1.jar but it is missing some kafka classes, included the one that I need at runtime:
> diff <(jar -tf /home/rief/.ivy2/cache/org.apache.kafka/kafka_2.10/jars/kafka_2.10-0.8.0.jar) <(jar -tf target/scala-2.10/test-assembly-0.0.1.jar) | grep "^<"
...
kafka/consumer/ZookeeperConsumerConnector$ZKRebalancerListener$$anonfun$kafka$consumer$ZookeeperConsumerConnector$ZKRebalancerListener$$closeFetchersForQueues$1.class
...
Is this a correct behaviour? How can I include kafka in my fatJar?
That's the intended behavior. % "provided" is skipped, since it's intention is to provide those classes from the container like Apache Spark, Kafka etc.
If you want everything in it here's what you can do:
fullClasspath in assembly := (fullClasspath in Compile).value
I've tried this
resolvers <<= resolvers.map { r =>
Resolver.withDefaultResolvers(r ++ Seq(
"my repository" at "http://example.com/repo"
), mavenCentral = false)
},
but it doesn't compile.
I'm actually not even sure how it is downloading from repo1.maven.org, since sbt resolvers doesn't list it (ever).
According to the sbt docs you need to change resolvers to externalResolvers.
resolvers does not contain the default resolvers; only additional ones added by your build definition. sbt combines resolvers with some default repositories to form externalResolvers. Therefore, to change or remove the default resolvers, you would need to override externalResolvers instead of resolvers.
My build.sbt has the following content:
name := "hello-world"
version := "1.0"
scalaVersion := "2.10.3"
libraryDependencies += "net.sourceforge.htmlunit" %% "htmlunit" % "2.13"
When I perform update in sbt console it says:
[error] (*:update) sbt.ResolveException: unresolved dependency: net.sourceforge.htmlunit#htmlunit_2.10;2.13: not found
What should I do to make sbt find this library?
Just use a single % instead of double %% in the dependency.
libraryDependencies += "net.sourceforge.htmlunit" % "htmlunit" % "2.13"
%% is only required when the path of the jar contains Scala version which is not a case for the dependency. I figured it out consulting mvnrepository - http://mvnrepository.com/artifact/net.sourceforge.htmlunit/htmlunit/2.13. Just hover over the 'Download(JAR)' link and you can see the full path.
Note: By default sbt uses the standard Maven2 repository. In case you have dependent jars that cannot be found in the default repo, then you need to add custom resolvers like this
resolvers += "custom_repo" at "url"
For this particular example resolvers are not required since htmlunit is present in default repo.