2010-12-21 45 views
1

我已经编写了一个简单的Scala应用程序,我想以独立的可执行jar的形式发布到没有Scala运行时的服务器上。当通过SBT run调用时,一切正常,但不是java -jar运行使用SBT和ProGuard构建的独立jar时的AbstractMethodError

当我运行通过Java的罐子,我得到以下未处理的异常:

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和它的记录仪,而且,每的Javadoc AbstractMethodError,认为这可能与斯卡拉/ SBT使用与我从shell调用的版本不同的Java版本。但是,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-less部署?

回答

1

查看您在SiteWiki.scala第29行所做的呼叫;这是违规的电话。你可能用一种抽象方法在那里调用特质/类。很可能应该实现抽象方法的方法被proguard撕掉(或者Scala覆盖不匹配(我已经看到发生这种情况))。

如果线路很长,找到有问题的电话;尝试分解多行。

+0

你是对的:ProGuard正在消除一些重要的事情。现在,我可以通过删除我的'-keep'选项并改为使用'-dontshrink'来解决它。现在我不在乎罐子的大小。谢谢! – Jeremy 2010-12-21 17:36:48