运行使用SBT和ProGuard构建的独立jar时的AbstractMethodError

时间:2010-12-21 00:59:50

标签: scala executable-jar sbt proguard

我编写了一个简单的Scala应用程序,我想以独立的可执行jar的形式分发给没有Scala运行时的服务器。通过SBT run调用时,一切正常,但不是java -jar

当我通过java运行jar时,我得到以下未处理的异常:

Exception in thread "main" java.lang.AbstractMethodError: java.util.logging.Handler.publish(Ljava/util/logging/LogRecord;)V
    at java.util.logging.Logger.log(Logger.java:458)
    at net.lag.logging.Logger.log(Logger.scala:108)
    at net.lag.logging.Logger.log(Logger.scala:91)
    at net.lag.logging.Logger.info(Logger.scala:121)
    at com.rentawebgeek.sitewiki.SiteWiki$.main(SiteWiki.scala:29)
    at com.rentawebgeek.sitewiki.SiteWiki.main(SiteWiki.scala)
Exception in thread "Thread-0" java.lang.AbstractMethodError: java.util.logging.Handler.close()V
    at java.util.logging.LogManager.resetLogger(LogManager.java:682)
    at java.util.logging.LogManager.reset(LogManager.java:665)
    at java.util.logging.LogManager$Cleaner.run(LogManager.java:223)

我正在使用Configgy和它的Logger,并且根据AbstractMethodError的javadoc,认为它可能与使用与我从shell调用的Java版本不同的Java版本的Scala / SBT有关。但是,java -version$JAVA_HOME/bin/java -version/usr/local/bin/scala使用的内容)都匹配为1.6.0_22。

我的ProGuard选项包括:

//program entry point
override def mainClass: Option[String] = Some("com.rentawebgeek.sitewiki.SiteWiki")

//proguard
override def proguardOptions = List(
    "-keepclasseswithmembers public class * { public static void main(java.lang.String[]); }",
    "-dontoptimize",
    "-dontobfuscate",
    "-keep class *",
    proguardKeepLimitedSerializability,
    proguardKeepAllScala,
    "-keep interface scala.ScalaObject"
)

override def proguardInJars = Path.fromFile(scalaLibraryJar) +++ super.proguardInJars

如何解决此错误?或者找到另一种从SBT项目构建可执行jar的方法,以实现无Scala部署?

2 个答案:

答案 0 :(得分:1)

在SiteWiki.scala第29行查看您正在拨打的电话;这是违法的电话。你可能用抽象方法调用特征/类。很可能应该实现抽象方法的方法被proguard扯掉(或者Scala覆盖不匹配(我已经看到了这种情况发生))。

如果线路很长,可以找到违规的电话;尝试分解多行。

答案 1 :(得分:0)

最新的ProGuard版本包含用于处理Scala应用程序和Scala运行时的示例配置:

http://proguard.sourceforge.net/manual/examples.html#scala

如果这不起作用,-printconfiguration和控制台输出的输出可能有助于找到根本原因。