0

我在 Eclipse 中有一个 libgdx android 项目,我添加了 scala 和 AndroidProguardScala 特性。这工作得很好,但突然 eclipse 开始给我警告“在构建路径上发现了多个 Scala 库”。我仍然可以在设备上构建和安装该项目,但它会立即退出NoClassDefFoundError: scala.Tuple2$mcZZ$sp因此看起来根本不包含 Scala 库。

我的项目似乎在“Scala Library [2.10.1]”(作为“scala-library.jar”)和“Android Dependencies”(作为“scala_library.min.jar”)下都有Scala库,所以我猜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 是一个返回 a 的函数tuple并且acceleration是一个向量)

多个库警告仍然存在,所以我想这与问题无关。幸运的是,我实际上不需要从项目的 android 版本中引用此代码,但了解此代码为何编译但无法运行仍然很有用。

4

2 回答 2

0

我确切地知道你遇到了什么问题。这与 AndroidProgaurdScala 无法识别您在主项目中的类文件有关。结果是,包含在 android 项目中定义的任何类,但是任何“新”类,例如您的元组,都将丢失,因此您会得到美妙的 NoClassDefFoundError。我没有遇到“在构建路径上找到多个 Scala 库”的警告,但这可能意味着您在项目中添加了 scala 特性,并且还在其顶部添加了 library.jar。尝试撤消您的配置并按照我在下面的内容进行操作;否则,请按照以下步骤设置一个新项目并复制您的源代码。

我发现 Scala Nature 和 Android Proguard Scala 在运行混乱后有点难以修复。我不能 100% 确定您是否能够挽救现有项目,但我们可以尝试看看会发生什么。首先,从您的项目中删除所有与 scala 相关的性质,并将它们恢复到它们的初始状态,它们将处于一个普通的旧 Java 项目中。

让我们通过 Scala 来设置 libGDX,看看哪里出了问题:

  1. 确保您的环境设置正确。(注意:您需要获取最新版本)
  2. 正常设置 libGDX 项目。(或在您的情况下使用现有项目)
  3. 右键单击android项目,“添加Scala性质”然后“添加AndroidProgaurdScala性质”
  4. 右键单击主项目,“添加Scala性质”
  5. 右击桌面项目,“添加Scala性质”

现在,这可能是您已经到达的地方,但仍然存在 AndroidProgaurdScala 不知道您的主项目中有哪些类的问题。它似乎忽略了包含的项目,并且没有将它们添加到 scala_library.min.jar。为了解决这个问题,我找到了一种效果很好的解决方案:

  1. 右键单击 Android 项目 > 属性 > Java 构建路径
  2. 转到项目选项卡,删除主项目。我知道这是违反直觉的,但请相信我。
  3. 转到源选项卡 > 链接源...
  4. 导航并从主项目中选择“src”文件夹
  5. 按确定
  6. 清理并重建项目。

我已经测试并广泛使用了这个设置,没有任何问题。Android 和桌面版本都非常满意,并且可以毫无怨言地使用 Scala 或混合代码。android 项目现在完全了解您在主项目中使用的所有 Scala 类,因为现在将源代码复制到 android 项目的构建中。(即 NoClassDefFoundError 应该与 Scala 相关的任何内容出现)。

于 2013-04-24T17:26:39.690 回答
0

当我的 Proguard 配置文件出现问题时,我收到了类似的消息。你可能会检查:

  • Proguard 是否正在运行
  • 您的配置文件有: -keep public class **.YourPackage.** 或类似的东西
  • 您的配置文件已针对 Scala 库进行了修改,例如。

    ## 标量设置
    
    -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(变量).newInstance()
    -dontnote org.xml.sax.EntityResolver
    
      #(org.apache.james.mime4j.storage.StorageProvider)Class.forName(变量).newInstance()
    -dontnote org.apache.james.mime4j.storage.DefaultStorageProvider
    
    -dontnote scala.android.app.Activity
    
    
    -保留类 scala.android.package**
    -keep 类 * 扩展 scala.android.app.Activity
    
    ## 修复 ==> 警告:...找不到引用的类 sun.misc.Unsafe
    -libraryjars D:\Program Files\Apache\m2\repository\com\google\code\findbugs\jsr305\2.0.1\jsr305-2.0.1.jar
    -不要警告 sun.misc.Unsafe
    
    
    -keep 类 * 扩展 scala.runtime.MethodCache {
        上市 ;
    }
    
    -keepclassmembers 类 * {
        ** 模块$;
    }
    
    -keepclassmembernames 类 scala.concurrent.forkjoin.ForkJoinPool {
        长事件计数;
        诠释工人计数;
        诠释运行控制;
        scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode syncStack;
        scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode 备用堆栈;
    }
    
    -keepclassmembernames 类 scala.concurrent.forkjoin.ForkJoinWorkerThread {
        整数基数;
        诠释 sp;
        诠释运行状态;
    }
    
    -keepclassmembernames 类 scala.concurrent.forkjoin.ForkJoinTask {
        整数状态;
    }
    
    -keepclassmembernames 类 scala.concurrent.forkjoin.LinkedTransferQueue {
        scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference 头;
        scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference 尾;
        scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference cleanMe;
    }
    
于 2013-04-24T17:33:16.667 回答