为啥生成的清单中没有 Main-Class 属性?

Posted

技术标签:

【中文标题】为啥生成的清单中没有 Main-Class 属性?【英文标题】:Why is there no Main-Class attribute in generated manifest?为什么生成的清单中没有 Main-Class 属性? 【发布时间】:2014-12-02 04:51:30 【问题描述】:

我有一个包含程序集插件的 build.sbt 文件。直到最近的构建,Main-Class 属性都包含在组装的 far jar 中,但突然之间,情况不再如此。

当我尝试运行 jar 时,我得到了无与伦比的:

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

但是使用 sbt 控制台运行,效果很好。

我的 build.sbt 目前看起来像这样(在程序集中添加 mainClass 是为了强制向程序集插件指示它确实应该包含,尽管我在插件源代码中注意到,它看起来像是在检查指定的无论如何都要运行)。

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"
)

当我解压 jar 文件并检查 META-INF/MANIFEST.MF 时,没有包含 Main-Class: 属性。

【问题讨论】:

愚蠢的问题 - Proces-s-relogger 中是否有多个主电源? 我的第一个猜测是尝试 FQDN 而不仅仅是类名。 sbt-assembly 的版本是多少? 使用0.11.2的sbt-assembly,ProcessRelogger中没有多个main,是FQDN,在根包里。 你能删除两个mainClass 行并重新开始吗?之后你可以做show compile:run::mainClass 并将其包含在问题中吗?你也可以用主类的名字执行assembly然后last-grep吗?将输出添加到问题中。 【参考方案1】:

这是尝试使用最新版本的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")

将以上所有文件放在一个项目中:

> 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

【讨论】:

确实 - 这曾经可以正常工作,然后停止正常工作,我似乎无法弄清楚可能会产生这种影响的变化。【参考方案2】:

这并不能回答原始问题的“为什么”,但正如其他 cmets 所提到的,如果您引入另一个 main(例如通过另一个对象间接包括),就会发生这种情况。

因此您可以在 build.sbt 中明确定义它:

mainClass in assembly := Some("path.to.intended.Main")  // object with main

【讨论】:

不确定这与上面的 build.sbt 中给出的有什么不同?【参考方案3】:

尝试在 (Compile, run) 中注释掉 mainClass := Some("ProcessRelogger") ]$ sbt clean assembly ]$ java -jar target/xxx.jar

【讨论】:

以上是关于为啥生成的清单中没有 Main-Class 属性?的主要内容,如果未能解决你的问题,请参考以下文章

运行 java -jar 时无法加载 Main-Class 清单属性

Java 遇到的奇葩问题

jar中没有主清单属性

Jacob.jar 运行报错,提示没有主属性清单是为啥?

在idea中把springboot项目打成jar包遇到的问题(没有主清单属性)(没有内置tomcat)(闪退)

一次记录 java非web项目部署到linux