Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LibGDX project written in Scala, on Android, using IntelliJ

So I've been working on a LibGDX project in IntelliJ v12.1.6 using Scala after getting set up using this tutorial: http://www.gamefromscratch.com/post/2013/12/01/Using-LibGDX-with-IntelliJ-with-Gradle.aspx. However I've noticed, when testing the game on my android device, I receive the following error

12-04 17:46:22.483: ERROR/AndroidRuntime(18951): FATAL EXCEPTION: GLThread 475
    Process: com.voliant.rsoss, PID: 18951
    java.lang.NoClassDefFoundError: scala.Predef$
    at com.voliant.rsoss.Actors.Player.act(Player.scala:20)
    at com.badlogic.gdx.scenes.scene2d.Group.act(Group.java:48)
    at com.badlogic.gdx.scenes.scene2d.Stage.act(Stage.java:225)
    at com.badlogic.gdx.scenes.scene2d.Stage.act(Stage.java:189)
    at com.voliant.rsoss.Screens.GameScreen.render(GameScreen.scala:46)
    at com.badlogic.gdx.Game.render(Game.java:46)
    at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(AndroidGraphics.java:499)
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1523)
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)

Whenever I attempt to utilize a method that's native to Scala (such as the standard println() method).

I suspected that the android class could not find the classes utilized by Scala, so I attempted to export the android project with the Scala library. Whenever I try this however, I get an error that I have too many methods, (similar to this) which would make sense as Scala introduces well over enough methods into the project to warrant this error.

My question is how could I make the android project aware of the Scala classes and methods, so that I could use them as effectively in the android project as I have been able to in the desktop project?

Thanks!

like image 824
Ooo Avatar asked Dec 04 '13 22:12

Ooo


1 Answers

Alright, It appears I've been able to resolve my issue.

I was able to use ProGuard to cut down the methods used by my projects, and Scala is now operating as expected on android. I ran into a bit of a snag with LibGDX itself actually, but managed to figure out how to add it to the config as well. (with a little help from google of course)

For anyone else who has the same problem, here's my ProGuard cfg and links I used to help come up with a solution. Happy Coding!

https://github.com/yareally/android-scala-intellij-no-sbt-plugin

-dontwarn scala.**
-dontwarn java.awt.**
-dontnote java.awt.**
-dontwarn com.badlogic.gdx.jnigen.**
-dontwarn com.badlogic.gdx.backends.android.AndroidDaydream
-dontwarn com.badlogic.gdx.backends.android.AndroidInputThreePlus
-dontwarn com.badlogic.gdx.backends.android.AndroidGraphicsDaydream

-keepclasseswithmembers public class * {
    public static void main(java.lang.String[]);
}

-keep class * implements org.xml.sax.EntityResolver

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

-keep class com.badlogic.gdx.backends.android.AndroidInput {
  public protected private *;
}

-keep class com.badlogic.gdx.backends.android.AndroidInputFactory {
  public protected private *;
}

-keep class com.badlogic.gdx.backends.android.AndroidInputThreePlus {
  public protected private *;
}

-keep class com.badlogic.gdx.backends.android.AndroidApplicationConfiguration {
  public protected private *;
}

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
like image 167
Ooo Avatar answered Oct 17 '22 03:10

Ooo