0

I know there are a few dozen people (like this one) who've posted with the same stacktrace, but after working through each of them I'm still missing a solution. I have a school project I'm working on which we're building in Android Studio (Gradle is the build tool) that depends on Gson. It is structured with three modules:

  • app (the android app generated by Android Studio)
  • server (the server which the app will be directing its calls to)
  • shared (classes that the server and app both depend on)

Both app and server have the following line in their build.gradle dependency:

implementation project(':shared')

So both depend on shared. shared, in turn, has gson-2.6.2.jar in shared/libs (though I've tried removing it and using the remote repository instead too), and all three have this as a dependency:

implementation fileTree(dir: 'libs', include: ['*.jar'])

There's a class in shared called Serializer which uses Gson. But when I'm running the server module within Android Studio and it gets to a call to Serializer, I get this stack trace:

Exception in thread "Thread-2" java.lang.NoClassDefFoundError: com/google/gson/Gson
    at my.t2r.comm.Serializer.<init>(Serializer.java:25)
...
Caused by: java.lang.ClassNotFoundException: com.google.gson.Gson
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 13 more

Solutions on Stack Overflow focus on making sure the dependencies are in the build.gradle files and cleaning and rebuilding the project. I've tried including the dependency on Gson in all three modules individually, tried using a remote Gson, and cleaned and rebuilt countless times. I'm always able to use Gson while coding, but it refuses to work at runtime. I'm at a loss, and any help would be appreciated!

app/build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "my.t2r"
        minSdkVersion 24
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    buildToolsVersion '26.0.2'
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    implementation project(':shared')
    compile 'com.android.support:recyclerview-v7:26.1.0'
    compile 'com.bignerdranch.android:expandablerecyclerview:1.0.3'
}

server/build.gradle:

apply plugin: 'java-library'

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation project(':shared')
    testImplementation 'junit:junit:4.12'
    implementation 'com.google.code.gson:gson:2.8.2' // I've also tried api instead
}

sourceCompatibility = "1.7"
targetCompatibility = "1.7"

shared/build.gradle:

apply plugin: 'java-library'

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    testImplementation 'junit:junit:4.12'
    implementation 'com.google.code.gson:gson:2.8.2' // I've also tried api instead
}

sourceCompatibility = "1.7"
targetCompatibility = "1.7"

EDIT: Updated to indicate that I'm using the directive to use remote instead of libs/

nschulzke
  • 1
  • 4
  • add your gradle file – MJM Feb 10 '18 at 03:15
  • All three have been added at the bottom. – nschulzke Feb 10 '18 at 03:59
  • where you have include theGSON lib?, add `compile 'com.google.code.gson:gson:2.8.1'` in app/build.gradle file – MJM Feb 10 '18 at 04:02
  • It's in the libs folder. I tried adding the compile line too, it didn't change anything. Updating the description. – nschulzke Feb 10 '18 at 17:49
  • Not clear why you need a JAR file when you have added the other way – OneCricketeer Feb 10 '18 at 17:55
  • That was based on what other people have tried to do to solve the problem. I've tried doing them one at a time, not at the same time. Neither the jar independently nor the `implementation 'com.google.code.gson:gson:2.8.2'` work, the result is the same either way. – nschulzke Feb 10 '18 at 17:59
  • Since your shared library includes gson, none of the other modules need to explicitly include it. You mention the jar file was a lower version, but what you added is higher. Have you tried downgrading gson? – OneCricketeer Feb 10 '18 at 18:12
  • Yes, I've used both versions. I just solve it though! I think the problem was with Android Studio, I'm posting the solution below. – nschulzke Feb 10 '18 at 19:13

3 Answers3

0

Add this dependency in your app\build.gradle

implementation 'com.google.code.gson:gson:2.8.2'
Md Tanbir Hossen
  • 393
  • 4
  • 13
  • Thanks for your answer! I've already tried that, it did not help. The files above were what I changed to after using the remote implementation command didn't work: they have the gson.jar in the libs/ folder. `implementation 'com.google.code.gson:gson:2.8.2'` had the same effect. – nschulzke Feb 10 '18 at 17:54
0

I found an answer!

I'm assuming there was something wrong with the IDE. When I loaded up the project in IDEA instead of Android Studio, the Gson dependency was scoped as Provided instead of Compile. Unfortunately, in Android Studio there's no way to see those settings. After hours of googling different, I finally turned up this answer in an SO chat room:

artifacts.add("default", file('libs/gson-2.6.2.jar'))

Adding this line to shared/build.gradle (not inside of any brackets, just free) solved my problem! I did not need anything changed in server/build.gradle.

nschulzke
  • 1
  • 4
0

I had the same problem, nothing like cleans or cache invaidates or Gradle changes helped. Finally it turned out that it was exclusive to one emulator instance (API 19). Both other emulators and physical device work fine.

comodoro
  • 1,489
  • 1
  • 19
  • 30