objectbox / objectbox-java

Android Database - first and fast, lightweight on-device vector database
https://objectbox.io
Apache License 2.0
4.4k stars 302 forks source link

Improve Kotlin support #9

Closed greenrobot closed 7 years ago

greenrobot commented 7 years ago

Right now entities must be defined in Java. This is because the ObjectBox Gradle plugin uses JDT to parse and modify Java code.

Possible options:

EricKuck commented 7 years ago

FWIW, I don't view not being able to change source files to be a bad thing. I never, ever want a library to change code that I have written. I would view using the standard annotation processor as a big upgrade, not only because it would add support for Kotlin/Scala/Groovy/whatever, but because it would leave my files alone.

greenrobot commented 7 years ago

+EricKuck I see your point. Just a few comments on that: technically, ObjectBox never touches code you have written. It only adds code to your class or replaces previously generated code. Other tools do byte code manipulation, which can get confusing during debugging. One could say ObjectBox is fully transparent about those changes and see this as an advantage even.

EricKuck commented 7 years ago

I agree that bytecode weaving isn't ideal, but annotation processing doesn't typically do that. I haven't looked into what this project uses code manipulation for enough to know if an apt dependency would cover everything, but it would be a huge upgrade to switch to something like this if it did.

Miha-x64 commented 7 years ago

As examples say, ObjectBox (and GreenDAO) need our models to have all-arg-constructor, no-arg constructor, and getters/setters. In Kotlin, a primary constructor with all default values specified yields a compiler to generate both all-arg and no-arg constructors. And getters/setters are exist in Kotlin by default. So, ObjectBox just should force us to declare all default values in a primary constructor.

greenrobot commented 7 years ago

ObjectBox just should force us to declare all default values in a primary constructor.

The "force us" might be the problem. The big constructor expects the parameters in a certain order, for example. Potential for big trouble if left to humans... 🤖

LouisCAD commented 7 years ago

@greenrobot There could be a check at compile time, and maybe a lint too to prevent us from compiling and shipping such an app with mis-ordered all parameters constructor.

greenrobot commented 7 years ago

And there also should be some fallback. Some plan B that works without the constructor.

Miha-x64 commented 7 years ago

The big constructor expects the parameters in a certain order

GreenDAO uses such constructors from generated classes. And humans can (and should) use named arguments.

LouisCAD commented 7 years ago

Hope this issue is resolved before ObjectBox leaves beta status

carmas123 commented 7 years ago

+1

greenrobot commented 7 years ago

Internally, we have the first Kotlin entities (data classes) running with ObjectBox.

Next step is to look into how to improve the API specific to Kotlin, for example with extension functions. An obvious improvement would be BoxStore.boxFor to work nicely with KClass.

Any other ideas?

greenrobot commented 7 years ago

We just released a release candidate with full Kotlin support. Please give version "0.9.13-RC" a try!

Check the Kotlin docs and the example project (currently only in dev branch).

Because this is a rather big update, we would like to get some feedback early on. Thanks!!

jumaallan commented 7 years ago

have tried the version 0.9.13-RC, however am getting this error, Error:(33, 20) Unresolved reference: MyObjectBox. How do I resolve this?

greenrobot commented 7 years ago

@jumadeveloper Did you try to build the projects first? This class is generated during build.

jumaallan commented 7 years ago

@greenrobot I have tried several times. Still no luck, When i switch to Java Model, it works just fine. I dont think am missing anything, because I have been using Objectbox for a while

jumaallan commented 7 years ago

I have retried, still not working. That's the only issue am getting : Unresolved reference: MyObjectBox.

greenrobot commented 7 years ago

@jumadeveloper Does this occur in Android Studio? Did you check building with gradlew?

greenrobot commented 7 years ago

There's a new version "0.9.13-RC2" with fixes for transient lists etc.

jumaallan commented 7 years ago

@greenrobot Yes, this occurs with Android Studio. Just added the 0.9.13-RC2 dependency, synced gradle, but getting the error during run. See my code snippets for my model, and my gradle files. Am not sure if there is something am missing here.

User Model `package com.androidstudy.kotlinretrofitobjectbox.models

import io.objectbox.annotation.Entity import io.objectbox.annotation.Id

/**

@Entity data class User( @Id var id: Long = 0, val first_name: String, val last_name: String, val username: String, val email: String, val password: String, val image: String )`

Build.gradle (Project) `// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript { ext.kotlin_version = '1.1.3-2' ext.objectBoxVersion = "0.9.13-RC2" repositories { jcenter() maven { url "http://objectbox.net/beta-repo/" } } dependencies { classpath 'com.android.tools.build:gradle:2.3.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "io.objectbox:objectbox-gradle-plugin:$objectBoxVersion"

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}

}

allprojects { repositories { jcenter() maven { url "http://objectbox.net/beta-repo/" } } }

task clean(type: Delete) { delete rootProject.buildDir } `

build.gradle (app) `apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'io.objectbox.android.transform'

android { compileSdkVersion 25 buildToolsVersion "26.0.0" defaultConfig { applicationId "com.androidstudy.kotlinretrofitobjectbox" minSdkVersion 10 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } sourceSets { main.java.srcDirs += 'build/generated/source/objectbox' } }

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' }) androidTestCompile 'com.google.code.findbugs:jsr305:3.0.2' compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.android.support.constraint:constraint-layout:1.0.2' testCompile 'junit:junit:4.12' compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"

compile "io.objectbox:objectbox-android:$objectBoxVersion"
compile "io.objectbox:objectbox-kotlin:$objectBoxVersion"
kapt "io.objectbox:objectbox-processor:$objectBoxVersion"

compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'

} repositories { mavenCentral() } And this is my App.kt package com.androidstudy.kotlinretrofitobjectbox

/**

import java.io.File

import io.objectbox.BoxStore

class App : Application() {

companion object Constants {
    const val TAG = "ObjectBoxExample"
    const val EXTERNAL_DIR = false
}

lateinit var boxStore: BoxStore
    private set

override fun onCreate() {
    super.onCreate()

    //        if (EXTERNAL_DIR) {
    //            // Example how you could use a custom dir in "external storage"
    //            // (Android 6+ note: give the app storage permission in app info settings)
    //            File directory = new File(Environment.getExternalStorageDirectory(), "objectbox-notes");
    //            boxStore = MyObjectBox.builder().androidContext(App.this).directory(directory).build();
    //        } else {
    // This is the minimal setup required on Android
    boxStore = MyObjectBox.builder().androidContext(this).build()
    //        }
}

}`

greenrobot commented 7 years ago

@jumadeveloper What do you see if you do ./gradlew clean build --stacktrace?

jumaallan commented 7 years ago

@greenrobot How do i run this? on my terminal or where?

jumaallan commented 7 years ago

I am currently on a Windows machine, so cmd not terminal

LouisCAD commented 7 years ago

@jumadeveloper Most gradle commands are platform agnostic, hence work on Windows cmd too. You also have access to it from the Terminal tool window in Android Studio

greenrobot commented 7 years ago

@jumadeveloper cmd is fine, go to your project dir, and run gradlew clean build --stacktrace

jumaallan commented 7 years ago

@LouisCAD Thanks, just learnt that now

jumaallan commented 7 years ago

@greenrobot FAILURE: Build failed with an exception.

BUILD FAILED

Total time: 4 mins 12.808 secs

greenrobot commented 7 years ago

@jumadeveloper It might be a standard compilation error. Caused by: org.gradle.api.GradleException: Compilation error. See log for more details hints at that. Please run again without --stacktrace and check for compilation errors other than Unresolved reference: MyObjectBox.

jumaallan commented 7 years ago

@greenrobot This is the result D:\Dev\Android\KotlinRetrofitObjectBox\app\src\main\java\com\androidstudy\kotlinretrofitobjectbox\App.kt: (33, 20): Unresolved reference: MyObjectBox :app:compileDebugKotlin FAILED

FAILURE: Build failed with an exception.

BUILD FAILED

Total time: 18.78 secs

greenrobot commented 7 years ago

@jumadeveloper After the build, what do you see in the build folder in the path "build/generated/kapt/debug"? Do you see any generated Java source files like MyObjectBox(.java)?

jumaallan commented 7 years ago

@greenrobot There is no generated folder inside the build folder, the one outside the app directory. It is however present inside the build folder inside the app directory but has no kapt folder

greenrobot commented 7 years ago

@jumadeveloper It might be that you applied the ObjectBox Gradle plugin to your top level Gradle project. It should be applied to the app level project where your entities are. We just updated the docs to be more clear on this: http://objectbox.io/documentation/kotlin/ Hope that helps.

jumaallan commented 7 years ago

@greenrobot Lemmi have a look at the docs, then try it again.

jumaallan commented 7 years ago

I have matched my gradle with your documentation, still getting the same error. I'll probably try this with another machine and see if it works

greenrobot commented 7 years ago

@jumadeveloper If you want to put your gradle files somewhere (e.g. do a gist), I'm happy to have a look too.

jumaallan commented 7 years ago

@greenrobot Sure, Kindly check them out

https://gist.github.com/jumadeveloper/f8797b5c3c7fb034b8021cb6f1acce2f

greenrobot commented 7 years ago

@jumadeveloper Using your code we could reproduce the issue. This line was missing in the app Gradle file: apply plugin: 'kotlin-kapt'

Without that line, kapt1 is used which may or may not work - for our test projects it worked. That line enables kapt3, which fixes issues like that.

You can also check 0.9.13-RC3, which should become 0.9.13 later today.

Thanks for working on that issue!

jumaallan commented 7 years ago

Thanks a lot, Appreciated. When is version one expected to be released?

jumaallan commented 7 years ago

And one question, why is it that i can not use a variable _id yet Objectbox uses id?

greenrobot commented 7 years ago

@jumadeveloper do you have an example to help me understand your question?

jumaallan commented 7 years ago

@greenrobot I got some error a while back when using _id as an Entity. Let me try use the version RC3 and see if get any error

jumaallan commented 7 years ago

@greenrobot It works now, perfectly well. Thanks!

greenrobot commented 7 years ago

PS.: Here's the announcement post

jumaallan commented 7 years ago

@greenrobot Thanks, just checked it out. I will be writting an article about it sometime today in my blog, make sure to check it out. Thanks

jumaallan commented 7 years ago

@greenrobot Does objectbox have a maximum limit? Or when does it log Database Full, and what could be the reason? Because it appears on some phones

greenrobot commented 7 years ago

@jumadeveloper Thanks for sharing your first article on ObjectBox. Ping us if you continue with the second, we're happy to have a look. Yes, there is a maximum size, which is 512 MB. This is a precaution to avoid the disk being flooded when your app is misbehaving. If you need more space, check out BoxStoreBuilder.maxSizeInKByte(long).

jumaallan commented 7 years ago

@greenrobot Thanks, I will be writting it later today. Appreciated

jdeebee commented 7 years ago

Hey @greenrobot Thanks for the great work! I stumbled upon the same issue (MyObjectBox not resolved), and I seem to have got everything right. Have added the repositories in the top-level project and applied the plugin (after applying kotlin-kapt plugin) and added the dependencies (both compile and annotation processing stage - kapt) to the app module. I also tried adding the generated directory to the projects's source sets: main.java.srcDirs += 'build/generated/source/objectbox', but no effect. I was afraid that Proguard is removing the generated class, but tried adding an explicit keep rule, with no effect again. Any ideas?

Here is the stacktrace:

:app:clean :sdk:clean :app:objectboxPrepareBuild :app:preBuild :app:extractProguardFiles :app:preDebugBuild :app:checkDebugManifest :app:preReleaseBuild :app:preStagingBuild :app:prepareComAndroidSupportAnimatedVectorDrawable2531Library :app:prepareComAndroidSupportAppcompatV72531Library :app:prepareComAndroidSupportCardviewV72531Library :app:prepareComAndroidSupportDesign2531Library :app:prepareComAndroidSupportGridlayoutV72531Library :app:prepareComAndroidSupportPercent2531Library :app:prepareComAndroidSupportRecyclerviewV72531Library :app:prepareComAndroidSupportSupportCompat2531Library :app:prepareComAndroidSupportSupportCoreUi2531Library :app:prepareComAndroidSupportSupportCoreUtils2531Library :app:prepareComAndroidSupportSupportFragment2531Library :app:prepareComAndroidSupportSupportMediaCompat2531Library :app:prepareComAndroidSupportSupportV42531Library :app:prepareComAndroidSupportSupportVectorDrawable2531Library :app:prepareComAndroidSupportTransition2531Library :app:prepareComBraintreepaymentsApiBraintree253Library :app:prepareComBraintreepaymentsApiCore253Library :app:prepareComBraintreepaymentsBrowserSwitch013Library :app:prepareComGoogleAndroidGmsPlayServicesAnalytics1102Library :app:prepareComGoogleAndroidGmsPlayServicesBase1102Library :app:prepareComGoogleAndroidGmsPlayServicesBasement1102Library :app:prepareComGoogleAndroidGmsPlayServicesLocation1102Library :app:prepareComGoogleAndroidGmsPlayServicesMaps1102Library :app:prepareComGoogleAndroidGmsPlayServicesPlaces1102Library :app:prepareComGoogleAndroidGmsPlayServicesTasks1102Library :app:prepareComGoogleFirebaseFirebaseAnalytics1102Library :app:prepareComGoogleFirebaseFirebaseAnalyticsImpl1102Library :app:prepareComGoogleFirebaseFirebaseCommon1102Library :app:prepareComGoogleFirebaseFirebaseConfig1102Library :app:prepareComGoogleFirebaseFirebaseCore1102Library :app:prepareComGoogleFirebaseFirebaseIid1102Library :app:prepareComGoogleFirebaseFirebaseMessaging1102Library :app:prepareComGoogleMapsAndroidAndroidMapsUtils043Library :app:prepareComJakewhartonButterknife801Library :app:prepareComJakewhartonTimberTimber451Library :app:prepareComMcxiaokeViewpagerindicatorLibrary241Library :app:prepareComMixpanelAndroidMixpanelAndroid487Library :app:prepareComOrhanobutLogger115Library :app:prepareComOrhanobutTracklyticsTracklyticsRuntime200Library :app:prepareComPaypalAndroidSdkPaypalOneTouch253Library :app:prepareComSquareupLeakcanaryLeakcanaryAndroid15Library :app:prepareComSquareupPicassoPicasso300SNAPSHOTLibrary :app:prepareComWdullaerMaterialdatetimepicker230Library :app:preDebugAndroidTestBuild :app:preDebugUnitTestBuild :app:preReleaseUnitTestBuild :app:preStagingUnitTestBuild :app:prepareIoMironovSmugglerSmugglerRuntime01213Library :app:prepareIoObjectboxObjectboxAndroid101Library :app:prepareIoReactivexRxandroid120Library :app:prepareMeZhanghaiAndroidMaterialprogressbarLibrary115Library :sdk:compileKotlin Using Kotlin incremental compilation :sdk:compileJava Note: Some input files use unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. :sdk:copyMainKotlinClasses :sdk:compileRetrolambdaMain :sdk:processResources UP-TO-DATE :sdk:classes :sdk:jar :app:prepareDebugDependencies :app:compileDebugAidl :app:compileDebugRenderscript :app:generateDebugBuildConfig :app:mergeDebugShaders :app:compileDebugShaders :app:generateDebugAssets :app:mergeDebugAssets :app:processDebugManifest :app:fabricGenerateResourcesDebug :app:generateDebugResValues :app:processDebugGoogleServices Parsing json file: /Users/me/dev/pepper/app/google-services.json :app:generateDebugResources :app:mergeDebugResources :app:processDebugResources :app:generateDebugSources :app:incrementalDebugJavaCompilationSafeguard :app:javaPreCompileDebug :app:kaptGenerateStubsDebugKotlin Using Kotlin incremental compilation :app:kaptDebugKotlin :app:compileDebugKotlin Using Kotlin incremental compilation e: /Users/me/dev/pepper/app/src/main/kotlin/com/foo/bar/DefaultApplication.kt: (38, 18): Unresolved reference: MyObjectBox :app:compileDebugKotlin FAILED

jumaallan commented 7 years ago

@sadeqzadeh Hi there, which version of objectbox are you using?

jdeebee commented 7 years ago

Hi @jumadeveloper I use 1.0.1

jumaallan commented 7 years ago

@sadeqzadeh If you don't mind, I have done a tutorial on my blog, on how to set it up using Kotlin. You could check it out here http://androidstudy.com