3

I have a build.sbt file that includes the assembly plugin. Up until the most recent build, the Main-Class attribute was being included in the assembled far jar, but all of a sudden, this is no longer the case.

When I attempt to run the jar, I get the inimitable:

no main manifest attribute, in ./target/scala-2.10/foo-0.3.0-SNAPSHOT.jar

but using run from the sbt console, works fine.

My build.sbt currently looks like this (the mainClass in assembly added in an attempt to force indicate to the assembly plugin that it really should include, though I noticed in the plugin source code, it looks like it's checking the one specified for run anyway).

import AssemblyKeys._

name := "foo"

version := "0.3.0-SNAPSHOT"

organization := "com.mycompany.myproduct"

scalaVersion := "2.10.4"

mainClass in (Compile, run) := Some("ProcessRelogger")

mainClass in assembly := Some("ProcessRelogger")

assemblySettings

libraryDependencies ++= Seq(
  "org.scalatest" % "scalatest_2.10" % "1.9.2" % "test",
  "ch.qos.logback" % "logback-classic" % "1.0.9",
  "com.typesafe.akka" %% "akka-actor" % "2.2.4",
  "joda-time" % "joda-time" % "2.3",
  "com.rabbitmq" % "amqp-client" % "3.3.4",
  "org.scalaz" % "scalaz-core_2.10" % "7.0.6",
  "com.typesafe.slick" %% "slick" % "2.0.2",
  "postgresql" % "postgresql" % "9.1-901.jdbc4",
  "com.escalatesoft.subcut" %% "subcut" % "2.0"
)

and when I unzip the jar file, and check META-INF/MANIFEST.MF, there's no Main-Class: attribute included.

Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
PlexQ
  • 3,154
  • 2
  • 21
  • 26
  • Silly question - are there multiple mains in Processrelogger? – Azzie Oct 07 '14 at 17:38
  • My first guess would be to try FQDN instead of just class name. – lgasior Oct 07 '14 at 20:22
  • What's the version of sbt-assembly? – Jacek Laskowski Oct 08 '14 at 07:07
  • Using 0.11.2 of sbt-assembly, and there aren't multiple mains in ProcessRelogger, and it is the FQDN, it's in the root package. – PlexQ Oct 08 '14 at 17:19
  • Could you remove the two `mainClass` lines and start over? Can you do `show compile:run::mainClass` afterwards and include it to the question? Can you also execute `assembly` and then `last-grep` with the name of the main class? Add the outputs to the question. – Jacek Laskowski Oct 08 '14 at 19:39
  • I have discovered another thing, the system has TWO app classes that are used in different situations. I reproduced the test setup given below, and if I put in a mainClass := Some("Thing") where the class does not exist, it does not fail, but simply picks the class that is the app?! – PlexQ Oct 08 '14 at 21:27
  • > show compile:run::mainClass [info] Some(ProcessRelogger) – PlexQ Oct 08 '14 at 21:42
  • and grepping for the main class on assembly shows a whole lot of bupkiss – PlexQ Oct 08 '14 at 21:48

3 Answers3

2

This is an attempt to reproduce the issue with the latest version of sbt-assembly 0.11.2.

project/build.properties

sbt.version=0.13.7-M3

project/assembly.sbt

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")

build.sbt

import AssemblyKeys._

assemblySettings

scalaVersion := "2.11.2"

src/main/scala/Main.scala

object HelloApp extends App {
  println("Hello")
}

With all the files above in a single project:

> about
[info] Updating {file:/Users/jacek/sandbox/sbt-assembly/}sbt-assembly...
[info] Resolving jline#jline;2.12 ...
[info] Done updating.
[info] This is sbt 0.13.7-M3
[info] The current project is {file:/Users/jacek/sandbox/sbt-assembly/}sbt-assembly 0.1-SNAPSHOT
[info] The current project is built against Scala 2.11.2
[info] Available Plugins: sbt.plugins.IvyPlugin, sbt.plugins.JvmPlugin, sbt.plugins.CorePlugin, sbt.plugins.JUnitXmlReportPlugin, com.typesafe.sbteclipse.plugin.EclipsePlugin, net.virtualvoid.sbt.graph.Plugin, com.github.tototoshi.sbt.musical.Plugin, com.timushev.sbt.updates.UpdatesPlugin, sbtassembly.Plugin
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.4

> assembly
[info] Updating {file:/Users/jacek/sandbox/sbt-assembly/}sbt-assembly...
[info] Resolving jline#jline;2.12 ...
[info] Done updating.
[info] Compiling 1 Scala source to /Users/jacek/sandbox/sbt-assembly/target/scala-2.11/classes...
[info] Including: scala-library-2.11.2.jar
[info] Checking every *.class/*.jar file's SHA-1.
[info] Merging files...
[warn] Merging 'META-INF/MANIFEST.MF' with strategy 'discard'
[warn] Strategy 'discard' was applied to a file
[info] SHA-1: a5c09d7626fe19f4e3cd98d709966a77f127b048
[info] Packaging /Users/jacek/sandbox/sbt-assembly/target/scala-2.11/sbt-assembly-assembly-0.1-SNAPSHOT.jar ...
[info] Done packaging.
[success] Total time: 4 s, completed Oct 8, 2014 9:27:41 AM

> eval "unzip -p target/scala-2.11/sbt-assembly-assembly-0.1-SNAPSHOT.jar META-INF/MANIFEST.MF" !
Manifest-Version: 1.0
Implementation-Title: sbt-assembly
Implementation-Version: 0.1-SNAPSHOT
Specification-Vendor: default
Specification-Title: sbt-assembly
Implementation-Vendor-Id: default
Specification-Version: 0.1-SNAPSHOT
Main-Class: HelloApp
Implementation-Vendor: default

[info] ans: Int = 0
Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
  • Indeed - this used to work fine, and then it stopped working fine, and I can't seem to figure out what changed that might have that effect. – PlexQ Oct 08 '14 at 17:20
0

This doesn't answer the "why" for the original question, but as other comments mentioned this can happen if you introduced another main (e.g. including indirectly through another object).

So you can explicitly define it for example in your build.sbt:

mainClass in assembly := Some("path.to.intended.Main")  // object with main
Core
  • 410
  • 2
  • 10
0

Try comment out mainClass in (Compile, run) := Some("ProcessRelogger") ]$ sbt clean assembly ]$ java -jar target/xxx.jar

Michaelzh
  • 441
  • 5
  • 14