Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does enablePlugins(DockerPlugin) from sbt-docker in Play project give "error: reference to DockerPlugin is ambiguous"?

I am trying to dockerize a play web app and I am using sbt-docker. I get the gollowing error when I execute sbt docker:

error: reference to DockerPlugin is ambiguous;
it is imported twice in the same scope by
import _root_.sbtdocker.DockerPlugin
and import _root_.com.typesafe.sbt.packager.docker.DockerPlugin
enablePlugins(DockerPlugin)
              ^
[error] Type error in expression
Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? q

I get the above error and my build.sbt looks like this:

enablePlugins(DockerPlugin)

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.6"

libraryDependencies ++= Seq(
  jdbc,
  cache,
  ws,
  specs2 % Test
)

resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"

// Play provides two styles of routers, one expects its actions to be injected, the
// other, legacy style, accesses its actions statically.
routesGenerator := InjectedRoutesGenerator

// Make docker depend on the package task, which generates a jar file of the application code
docker <<= docker.dependsOn(sbt.Keys.`package`.in(Compile, packageBin))

// Define a Dockerfile
dockerfile in docker := {
  val jarFile = artifactPath.in(Compile, packageBin).value
  val classpath = (managedClasspath in Compile).value
  val mainclass = mainClass.in(Compile, packageBin).value.getOrElse(sys.error("Expected exactly one main class"))
  val jarTarget = s"/app/${jarFile.getName}"
  // Make a colon separated classpath with the JAR file
  val classpathString = classpath.files.map("/app/" + _.getName).mkString(":") + ":" + jarTarget
  new Dockerfile {
    // Base image
    from("java")
    // Add all files on the classpath
    add(classpath.files, "/app/")
    // Add the JAR file
    add(jarFile, jarTarget)
    // On launch run Java with the classpath and the main class
    entryPoint("java", "-cp", classpathString, mainclass)
  }
}

My suspicion is that the sbt-native-packager is conflicting with sbt-docker. But I am not importing sbt-native-packager anywhere.

like image 872
pphanireddy Avatar asked Nov 21 '15 22:11

pphanireddy


2 Answers

If there's a conflict then use the full name.

enablePlugins(sbtdocker.DockerPlugin)
like image 104
pfn Avatar answered Sep 25 '22 17:09

pfn


As the message says "and import _root_.com.typesafe.sbt.packager.docker.DockerPlugin" sbt-native-packager comes with the conflicting DockerPlugin class. But that's what you know already.

The trick is that the Play plugin depends on sbt-native-packager to...ease people's lifes and hence the conflict (sorry, too much help might break people's lifes :)).

A solution is to use fully-qualified plugin class names as @pfn recommended or disablePlugins(SbtNativePackager).

See http://www.scala-sbt.org/sbt-native-packager/topics/play.html.

like image 33
Jacek Laskowski Avatar answered Sep 24 '22 17:09

Jacek Laskowski