Scala/Android项目中的“多个scala库”

问题描述:

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

我的项目似乎有Scala库都在 “Scala库[2.9.1]”(如 “斯卡拉-library.jar”),并在 “Android相关性”(如 “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是一个函数返回一个tupleacceleration是一个向量)

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

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

我发现Scala自然和Android Proguard Scala在修复后很难修复。我不是100%确定你可以挽救现有的项目,但我们可以尝试看看会发生什么。首先,从您的项目中删除所有与scala相关的特性,并将它们恢复到初始状态,这些特性仅适用于普通的旧Java项目。

让我们通过使用Scala设置libGDX,看看那里的东西出了问题:

  1. Make sure your environment is setup correctly.(注:您将需要获得最新的版本)
  2. Set up the libGDX project as normal.(或者使用已有的项目中的情况)
  3. 右键单击Android项目,“添加斯卡拉自然”,然后“添加AndroidProgaurdScala自然”
  4. 右键单击主项目,“添加斯卡拉自然”
  5. 右键单击桌面上的项目,“添加斯卡拉自然”

现在,这可能是在那里你能对付了,但仍有AndroidProgaurdScala的,不知道你有你的主要项目是什么类的问题。它似乎忽略了包含的项目,并没有将它们添加到scala_library.min.jar。为了解决这个问题我已经找到一个解决方案,它工作得很好:

  1. 右键单击的Android项目>属性> Java构建路径
  2. 转到项目选项卡,去掉主体工程。我知道这是违反直觉的,但相信我。
  3. 转到源选项卡>链接源...
  4. 导航,并从您的主项目
  5. 按OK
  6. 清洁选择“SRC”文件夹和重建项目。

这个设置我已经测试和广泛使用,没有任何问题。 Android和桌面版本都很开心,并且无需使用Scala或混合代码进行投诉。这个android项目现在完全知道你在主项目中使用的所有Scala类,因为源代码现在被复制到了android项目的构建中。 (即没有NoClassDefFoundError应该与Scala相关的任何东西出现)。

+0

不幸的是,除主体工程和连接的“SRC”文件夹中给出了该文件夹已链接错误,而奇怪的是这样做不可逆的破坏的项目,所以这不是为我工作。不过,谢谢你的全面回答。 – 2013-04-25 11:56:49

+0

这确实很奇怪,考虑到链接应该没有实际效果。导航到eclipse之外的文件夹,并将源文件复制到其他地方。尝试再次设置eclipse,我感觉有些东西在你的工作空间中被损坏并造成严重破坏。我花了一段时间才让eclipse + scala + libgdx在一起愉快地工作。 – Jyro117 2013-04-25 14:18:51

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

  • 是Proguard的中运行
  • 您的配置文件有:-keep公共类** ** YourPackage或类似的东西
  • 您的配置文件被修改为斯卡拉库。 ,例如。

     
    ## 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; 
    }