SBT Assembly Plugin Error - sbt

I'm trying to run sbt assembly on my project but I get error saying:
[error] Not a valid command: assembly
[error] Not a valid project ID: assembly
[error] Expected ':' (if selecting a configuration)
[error] Not a valid key: assembly
[error] assembly
[error] ^
I have the following structure:
MyProject
- project
- assembly.sbt
- build.properties
- BuildSettings.scala
- MyProjectBuild.scala
- src
- main
- com
- mypkg
- MyMainClass.scala
I have the following in my assembly.sbt:
resolvers += Resolver.url("artifactory", url("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases"))(Resolver.ivyStylePatterns)
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")
// dont upgrade to 0.12.0 as there is assembly conflict
My build.properties is:
sbt.version=0.13.6
My BuildSettings.scala is:
import sbt._
import Keys._
object BuildSettings {
lazy val basicSettings = Seq[Setting[_]](
organization := "com.eon.vpp",
version := "0.1.0-SNAPAHOT",
description := "vpp metrics producer to a kafka instance",
scalaVersion := "2.11.7",
scalacOptions := Seq("-deprecation", "-encoding", "utf8"),
resolvers ++= Dependencies.resolutionRepos
)
// sbt-assembly settings for building one fat jar
import sbtassembly.Plugin._
import AssemblyKeys._
lazy val sbtAssemblySettings = assemblySettings ++ Seq(
jarName in assembly := {
name.value + "-" + version.value + ".jar"
},
// META-INF discarding
mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) =>
{
case PathList("META-INF", xs # _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
}
)
lazy val buildSettings = basicSettings ++ sbtAssemblySettings
}
Any suggestions as to why is this error?

Yes, I figured out what the problem was. I had to move the plugins.sbt file inside the project folder. It was that simple!

Related

FlyWay plugin with sbt

I'm trying to apply FlyWay plugin by sbt build configuration.
In plugins.sbt
In my build.sbt:
lazy val CustomConfig = config("custom") extend Runtime
lazy val customSettings: Seq[Def.Setting[_]] = Seq(
flywayUser := "andrej",
flywayPassword := "123456",
flywayUrl := "jdbc:postgresql://localhost:5432/database",
flywayLocations += "db/migration"
)
lazy val flyWay = (project in file("."))
.settings(inConfig(CustomConfig)(FlywayPlugin.flywayBaseSettings(CustomConfig) ++
customSettings): _*)
In resources.db.migration-directory sql-file is created.
And trying to run migration to database it with command: sbt flywayMigrate
But it returns the following errors:
[error] Expected ';'
[error] Not a valid command: flywayMigrate
[error] No such setting/task
[error] flywayMigrate
[error] ^
Looks like you did not enable the plugin.
Add following line to your project/plugin.sbt
addSbtPlugin("io.github.davidmweber" % "flyway-sbt" % "7.4.0")
and enable the plugin in you build.sbt file:
enablePlugins(FlywayPlugin)

sbt says "not a valid command" but plugin enabled

I have a plugin called sonar, which is developed and published as an AutoPlugin:
object Sonar extends AutoPlugin {
object autoImport {
lazy val sonar = taskKey[Unit]("sonar")
}
import autoImport._
override def trigger = allRequirements
lazy val sonarTask = Def.task {
<snip task code here which runs sonarqube scanner>
}
}
We then have a project which uses that plugin, with plugins.sbt that looks like this:
resolvers ++= Seq(
"Nexus Snapshot repo" at "url here"
)
credentials += Credentials(Path.userHome / ".ivy2" / ".credentials")
addSbtPlugin("packagename" % "sonar" % "1.0-SNAPSHOT")
And build.sbt like this:
name := "hashing-library"
organization := "org name here"
scalaVersion := "2.12.6"
autoScalaLibrary := false
crossPaths := false
resolvers += "Nexus Release repo" at "https://nexusurl/content/repositories/releases/"
resolvers += "nexus Snapshot repo" at "https://nexusurl/content/repositories/snapshots/"
credentials += Credentials(Path.userHome / ".ivy2" / ".credentials")
// Publishing options:
publishMavenStyle := true
publishArtifact in Test := false
pomIncludeRepository := { x => false }
publishTo := {
val nexus = "nexus url here"
if (isSnapshot.value)
Some("sonatype-snapshots" at nexus + "content/repositories/snapshots")
else
Some("sonatype-releases" at nexus + "content/repositories/releases")
}
When I try to run sbt plugins, it says the plugin is enabled:
<snip output>
packagename.sonar.Sonar: enabled in hashingLibrary
So why is it that my plugin is enabled, but I cannot run sbt sonar? When I do, it says:
[info] Set current project to hashing-library (in build file:/home/work/hashing-library/)
[error] Not a valid command: sonar
[error] Not a valid project ID: sonar
[error] Expected ':'
[error] Not a valid key: sonar
[error] sonar
[error]
(Obviously org names and url's have been removed to protect confidentiality of my client, but hopefully that doesn't impact my question!)
The missing part of your plugin is the connection between the sonar task key and the sonarTask task implementation, i.e. you need to say somewhere that the key is set to the value of the implementation. You normally do it by overriding project settings in the plugin:
override def projectSettings = Seq(
sonar := sonarTask.value
)

Unresolved dependency in published assembly package in SBT

In my project there are 3 sub projects under root. build.sbt is as below.
proj_C depends on proj_A and proj_B.
If I created the assembly proj_C package with below command. It success and the assembly package could be imported in other projects.
sbt "project proj_C" assembly
If I publish with "sbt publish", as I defined addArtifact in proj_C settings, an assembly jar package is also generated and then published. But when I try to compile another project which imports this assembly jar, it will below error
[error] unresolved dependency: proj_A;1.0.0: not found
part of build.sbt is as below. Could anyone point me what I made wrong in my way?
Many thanks!
artifact in (Compile, assembly) := {
val art = (artifact in (Compile, assembly)).value
art.withClassifier(Some("assembly"))
}
lazy val assemblySettings = Seq(
assemblyMergeStrategy in assembly := {
{
case PathList("META-INF", xs # _*) => MergeStrategy.discard
case _ => MergeStrategy.first
}
}
)
lazy val root = Project(base = file("."))
.disablePlugins(sbtassembly.AssemblyPlugin)
.aggregate(proj_A, proj_B, proj_C)
.settings(
commonSettings,
skip in publish := true,
name := "proj_root"
)
lazy val proj_A= (project in file("proj_A"))
.disablePlugins(sbtassembly.AssemblyPlugin)
.settings(
commonSettings,
skip in publish := true,
name := "proj_A"
)
lazy val proj_B= (project in file("proj_B"))
.disablePlugins(sbtassembly.AssemblyPlugin)
.settings(
commonSettings,
skip in publish := true,
name := "proj_B"
)
lazy val proj_C= (project in file("proj_C"))
.settings(
commonSettings,
assemblySettings,
addArtifact(artifact in (Compile, assembly), assembly),
name := "proj_C"
) dependsOn(proj_A, proj_B)
First of all, I hope you know that the publishing of the fat jar is not recommended. And to be honest, in your case I really see no benefit in doing so.
If you simply publish A, B, C separately and then add the dependency in your other project it will all be automatically downloaded (along with dependencies of those projects). And the dependency management will be much easier...
But, since you want to add the A-assembly dependency, by the error I guess that you are actually adding the wrong jar. My guess would be that you publish both C.jar and C-assembly.jar, and you added the dependency like:
"your.organisation" %% "C" % "version"
but you should have:
"your.organisation" %% "C" % "version" classifier "assembly"

How to combine crossProject and dependsOn

I have a multi-project definition something like the following:
lazy val commonSettings = settings(
libraryDependencies ++= Seq(
"ch.qos.logback" % "logback-classic" % "1.1.2",
...
)
lazy val core = (project in file(".")).
settings(commonSettings: _*).
settings(...
)
lazy val web = (project in file("web")).
settings(commonSettings: _*).
settings(...
).dependsOn(core)
The problem is that I want to set up the web project to use the Scala JS client/server model. So I need to expand the web project to use crossProject to split into the js/jvm/shared parts. But I am not sure of the best way to achieve this. If I try to do something like:
lazy val web = crossProject.
settings(commonSettings: _*).
settings(...
).jsSettings(...
).jvmSettings(...
).dependsOn(core)
I get a compilation error for my build.scala:
... type mismatch; [error] found : sbt.Project [error] required:
org.scalajs.sbtplugin.cross.CrossClasspathDependency [error] lazy val
web =
crossProject.settings().jsSettings().jvmSettings().dependsOn(core)
[error]
^
Leave out the dependsOn for the web project.
lazy val webJS = web.js.dependsOn(...)
It made the trick for me.

Why is the error "Not a valid command: assembly-merge-strategy"?

I have the following build.sbt file.
import AssemblyKeys._
name := "approxstrmatch"
version := "1.0"
scalaVersion := "2.10.4"
libraryDependencies+="org.apache.spark" %% "spark-core" % "1.0.0"
resolvers += "AkkaRepository" at "http://repo.akka.io/releases/"
// My merge strategy is specified here.
lazy val app = Project("approxstrmatch", file("approxstrmatch"),
settings = buildSettings ++ assemblySettings ++ Seq(
mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) =>
{
case PathList("javax", "servlet", xs # _*) => MergeStrategy.first
case PathList("javax", "transaction", xs # _*) => MergeStrategy.first
case PathList("javax", "mail", xs # _*) => MergeStrategy.first
case PathList("javax", "activation", xs # _*) => MergeStrategy.first
case PathList(ps # _*) if ps.last endsWith ".html" => MergeStrategy.first
case "application.conf" => MergeStrategy.concat
case "unwanted.txt" => MergeStrategy.discard
case x => old(x)
}
})
)
mainClass in assembly := Some("approxstrmatch.JaccardScore")
// jarName in assembly := "approstrmatch.jar"
When I execute the following command sbt assembly-merge-strategy there's an error I don't understand. Any help appreciated.
approxstrmatch]$ sbt assembly-merge-strategy
[info] Loading project definition from /apps/sameert/software/approxstrmatch/project
[info] Set current project to approxstrmatch (in buildfile:/apps/sameert/software/approxstrmatch/)
[error] Not a valid command: assembly-merge-strategy
[error] No such setting/task
My understanding tells me there's no assembly-merge-strategy task in sbt-assembly plugin (I can only suspect you use that plugin in your build).
Execute assembly as described in https://github.com/sbt/sbt-assembly#assembly-task as "an awesome new assembly task which will compile your project, run your tests, and then pack your class files and all your dependencies into a single JAR file".
There is a setting named assemblyMergeStrategy (aka assembly-merge-strategy). It's just that you won't directly use it. The way sbt-assembly uses it is scoped to assembly task:
mergeStrategy in assembly <<= ....
So here's what you have to do to call it from the shell:
$ sbt assembly::assemblyMergeStrategy
[info] blabla other things...
[info] <function1>
add assemblySettings in your build.sbt will help

Resources