Search code examples
androidparse-platformparse-server

Add Parse server to an already existing project


I have a project and I want to add Parse to it. I installed the Parse server in my PC, downloaded the SDK from their website and it worked perfectly fine.
However, I don't want to use the SDK from their website, I just want to add the libraries to my project.

Here is what I did: I copied these libraries files into my project libs folder

'libs/parse-android-1.13.1.jar'
'libs/bolts-android-1.2.0.jar'

and here is my code :

in the build.gradle file :

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:24.2.1'
    testCompile 'junit:junit:4.12'

    compile files('libs/parse-android-1.13.1.jar')
    compile files('libs/bolts-android-1.2.0.jar')

}

I added the dependencies as above.

for the main Activity:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Parse.initialize(new Parse.Configuration.Builder(getApplicationContext())
                .applicationId("kooora.com100plus")
                .clientKey("kooora.com100plusMasterKey")
                .server("http://10.0.2.2:1337/parse/")
                .build()
        );


        ParseObject gameScore = new ParseObject("GameScore");
        gameScore.put("score", 1337);
        gameScore.put("playerName", "Sean Plott");
        gameScore.put("cheatMode", false);
        gameScore.saveInBackground(new SaveCallback() {
            public void done(ParseException e) {
                if (e == null) {
                    Log.i("Parse", "Save Succeeded");
                } else {
                    Log.i("Parse", e.getMessage());
                }
            }
        });
    }
}

Here is the log for the error I get :

10-16 06:34:42.539 25428-25428/? I/art: Not late-enabling -Xcheck:jni (already on)
10-16 06:34:42.563 25428-25436/? E/art: Failed writing handshake bytes (-1 of 14): Broken pipe
10-16 06:34:42.563 25428-25436/? I/art: Debugger is no longer active
10-16 06:34:42.696 25428-25428/? D/AndroidRuntime: Shutting down VM  
10-16 06:34:42.696 25428-25428/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sabirmoglad.big_boss, PID: 25428
java.lang.NoClassDefFoundError: Failed resolution of: Lbolts/TaskCompletionSource;
   at com.parse.ParseTaskUtils.callbackOnMainThreadAsync(ParseTaskUtils.java:100)
   at com.parse.ParseTaskUtils.callbackOnMainThreadAsync(ParseTaskUtils.java:72)
   at com.parse.ParseTaskUtils.callbackOnMainThreadAsync(ParseTaskUtils.java:59)
   at com.parse.ParseObject.saveInBackground(ParseObject.java:1529)
   at com.example.sabirmoglad.big_boss.MainActivity.onCreate(MainActivity.java:31)
   at android.app.Activity.performCreate(Activity.java:5937)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
   at android.app.ActivityThread.access$800(ActivityThread.java:144)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:135)
   at android.app.ActivityThread.main(ActivityThread.java:5221)
   at java.lang.reflect.Method.invoke(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:372)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.ClassNotFoundException: Didn't find class "bolts.TaskCompletionSource" on path: DexPathList[[zip file "/data/app/com.example.sabirmoglad.big_boss-2/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]
   at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
   at com.parse.ParseTaskUtils.callbackOnMainThreadAsync(ParseTaskUtils.java:100) 
   at com.parse.ParseTaskUtils.callbackOnMainThreadAsync(ParseTaskUtils.java:72) 
   at com.parse.ParseTaskUtils.callbackOnMainThreadAsync(ParseTaskUtils.java:59) 
   at com.parse.ParseObject.saveInBackground(ParseObject.java:1529) 
   at com.example.sabirmoglad.big_boss.MainActivity.onCreate(MainActivity.java:31) 
   at android.app.Activity.performCreate(Activity.java:5937) 
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105) 
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251) 
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360) 
   at android.app.ActivityThread.access$800(ActivityThread.java:144) 
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) 
   at android.os.Handler.dispatchMessage(Handler.java:102) 
   at android.os.Looper.loop(Looper.java:135) 
   at android.app.ActivityThread.main(ActivityThread.java:5221) 
   at java.lang.reflect.Method.invoke(Native Method) 
   at java.lang.reflect.Method.invoke(Method.java:372) 
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 
    Suppressed: java.lang.ClassNotFoundException: bolts.TaskCompletionSource
   at java.lang.Class.classForName(Native Method)
   at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
   at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
        ... 19 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available

I don't know what went wrong! I just get a runtime error and it stops working


UPDATE:

As suggested in the comments, I put the initialization in my Application class,
in fact I copied the class from the original SDK but it seems like this initialization doesn't execute,

here is the class I added from the original SDK:

public class StarterApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // Enable Local Datastore.
        Parse.enableLocalDatastore(this);

        // Add your initialization code here
        Parse.initialize(new Parse.Configuration.Builder(getApplicationContext())
                .applicationId("kooora.com100plus")
                .clientKey("kooora.com100plusMasterKey")
                .server("http://10.0.2.2:1337/parse/")
        .build()
        );

          ParseUser.enableAutomaticUser();
        ParseACL defaultACL = new ParseACL();
        // Optionally enable public read access.
        // defaultACL.setPublicReadAccess(true);
        ParseACL.setDefaultACL(defaultACL, true);
    }

}

Solution

  • Firstly, adding those two libs lines to the Gradle file was not necessary. This one line includes all JAR files on its own.

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

    Now, I generally recommend that you try your best to avoid JAR libraries when you can find the dependencies in JCenter or Maven Central (look those up, if you are unsure). Reason being - transitive dependencies get included for you, version management requires some number changes, not overwriting a file, etc.

    Then, the Class not found error could originate from using an outdated version of the libraries.

    All in all, remove the JAR files, compile the libraries with these dependencies. (latest versions in comments above)

    dependencies {
        // other stuff 
    
        compile 'com.parse:parse-android:1.13.1'
        compile 'com.parse.bolts:bolts-tasks:1.4.0'
        compile 'com.parse.bolts:bolts-applinks:1.4.0'
    }