我在eclipse中有一个libgdx android项目,我已经添加了scala和AndroidProguardScala性质。 这很好用,但突然eclipse开始给我警告“在构建路径上找到多个Scala库”。我仍然可以在设备上构建和安装项目,但它会立即退出使用NoClassDefFoundError: scala.Tuple2$mcZZ$sp
,所以看起来根本没有包含Scala库。
我的项目似乎将Scala库放在“Scala Library [2.10.1]”(作为“scala-library.jar”)和“Android Dependencies”下(作为“scala_library.min.jar”) )所以我猜Proguard输出与原始库相冲突,但我不知道为什么会发生这种情况或者如何修复它。
此时我可以创建一个新项目并将源文件复制过来,但如果有人能够对此有所了解,那就太棒了。
编辑:经过一些实验后发现,这段代码(来自特质方法)似乎导致了问题。
acckeys match {
case (true, false) => acceleration.set(0, accel).rotate(rotation)
case (false, true) => acceleration.set(0, -accel).rotate(rotation)
case _ => acceleration.set(0, 0)
}
(其中acckeys是一个返回tuple
且acceleration
为向量的函数)
多个库警告仍然存在,所以我猜这与问题无关。幸运的是,我实际上并不需要从项目的android版本中引用此代码,但知道此代码编译但无法运行的原因仍然很有用。
答案 0 :(得分:0)
我确切地知道你遇到了什么问题。这与AndroidProgaurdScala无法识别主项目中的类文件有关。结果是,包含了在android项目中定义的任何类,但是任何“新的”类,例如你的元组都将丢失,因此你会得到精彩的NoClassDefFoundError。我没有遇到“在构建路径上找到多个Scala库”的警告,但这可能意味着您已将scala特性添加到项目中,并且还在其上添加了library.jar。尝试撤消您的配置并按照我下面的内容进行操作;否则,请按照以下步骤设置新项目并复制您的来源。
我发现Scala Nature和Android Proguard Scala在运行渣土后有点痛苦。我不是100%肯定你能够抢救现有的项目,但我们可以试着看看会发生什么。首先,从项目中删除所有与scala相关的性质,并将它们恢复到初始状态,这些状态只适用于普通的Java项目。
让我们一起使用Scala设置libGDX,看看出了什么问题:
现在,这可能已经到了你的位置,但仍然存在AndroidProgaurdScala的问题,不知道你的主项目中有哪些类。它似乎忽略了包含的项目,并没有将它们添加到scala_library.min.jar。为了解决这个问题,我找到了一个效果很好的解决方案:
此设置我已经过广泛测试和使用,没有任何问题。 Android和桌面版本都很开心,并且在没有Scala或混合代码的任何投诉的情况下工作。 android项目现在完全了解您在主项目中使用的所有Scala类,因为源现在被复制到android项目的构建中。 (即没有NoClassDefFoundError出现与Scala相关的任何内容)。
答案 1 :(得分:0)
当我的Proguard配置文件出现问题时,我收到了类似的消息。你可能会检查:
您的配置文件已针对Scala库进行了修改,例如
## SCALA SETTINGS -dontwarn **$$anonfun$* -dontwarn scala.android.** -dontwarn scala.beans.ScalaBeanInfo -dontwarn scala.collection.generic.GenTraversableFactory -dontwarn scala.collection.immutable.RedBlack$Empty -dontwarn scala.concurrent.forkjoin.** -dontwarn scala.reflect.** -dontwarn scala.sys.process.** -dontwarn scala.tools.**,plugintemplate.** #(org.xml.sax.EntityResolver)Class.forName(variable).newInstance() -dontnote org.xml.sax.EntityResolver #(org.apache.james.mime4j.storage.StorageProvider)Class.forName(variable).newInstance() -dontnote org.apache.james.mime4j.storage.DefaultStorageProvider -dontnote scala.android.app.Activity -keep class scala.android.package** -keep class * extends scala.android.app.Activity ## Fixes ==> Warning: ... can't find referenced class sun.misc.Unsafe -libraryjars D:\Program Files\Apache\m2\repository\com\google\code\findbugs\jsr305\2.0.1\jsr305-2.0.1.jar -dontwarn sun.misc.Unsafe -keep class * extends scala.runtime.MethodCache { public ; } -keepclassmembers class * { ** MODULE$; } -keepclassmembernames class scala.concurrent.forkjoin.ForkJoinPool { long eventCount; int workerCounts; int runControl; scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode syncStack; scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode spareStack; } -keepclassmembernames class scala.concurrent.forkjoin.ForkJoinWorkerThread { int base; int sp; int runState; } -keepclassmembernames class scala.concurrent.forkjoin.ForkJoinTask { int status; } -keepclassmembernames class scala.concurrent.forkjoin.LinkedTransferQueue { scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference head; scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference tail; scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference cleanMe; }