7
votes

Problem:

This question has likely been answered implicitly from all the other similar questions but I can't seem to get it to work.

  • If I reference a particular java file in another flavor (different source set) from a java file in the main source set it works.

  • If I try to reference that same file from a Kotlin file in the main source set it complains that it can't see it ("Unresolved reference").

  • If I move the same file to the main source set it works (so it's not the file itself).

  • If I convert the Java file to Kotlin it works (and this is my current solution) but I'd like to know why it doesn't work since it's not always so easy to convert and it should work without converting.

Based on my Googling it seems it's related to the source sets in Gradle but I don't want a separate Kotlin folder alongside the Java folder so I'm not sure I need this. Also, another project where I have both Java and Kotlin doesn't have this configured and works fine.

I'm using productFlavors with flavorDimensions and have a source set called "dimension1Dimension2" (that's where the Java file I'm trying to reference is located).

Looking at my setup below, what am I possibly doing wrong or missing? This project is mostly Java so I'm just starting to add Kotlin to it. I can't see any differences with my other project that is mostly Kotlin and some Java.

One other thing that is weird is that it does work for one of the three flavors. There are two types of dimension1 and three types of dimension2. Just one of the dimension2 types works.

Maybe code is clearer:

flavorDimensions "product", "mode"    
productFlavors {
        mock { // only this one works (e.g. <company_name>Mock is the source set)
            applicationIdSuffix = ".mock"
            dimension "mode"
        }
        dev {
            applicationIdSuffix = ".dev"
            dimension "mode"
        }
        prod {
            dimension "mode"
        }
        demo {
            applicationIdSuffix = ".demo"
            dimension "product"
            buildConfigField "String", "UPDATE_DIRECTORY", "\"/release/\""
            buildConfigField "boolean", "SHOW_STREAM_STATUS", "false"
        }
        <company_name> {
            applicationIdSuffix = ".<company_name>"
            dimension "product"
        }
    }

Setup:

  • Kotlin version: 1.2.21
  • Gradle version: 3.0.1
  • Plugins:
    • apply plugin: 'kotlin-android'
    • apply plugin: 'kotlin-kapt'
    • apply plugin: 'kotlin-android-extensions'
  • Project level dependencies:
    • classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  • App level dependencies:
    • implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
  • Using Java 8 in project settings
1
Did you ever solve this? I'm in the same position as you and I'm starting to avoid writing Kotlin classes if they need to reference Java classes that are in different flavors. If I have time I spend the time converting the old classes to Kotlin, but this is not always an option, being on a tight deadline and you can't always trust the built-in converter to convert the Java code to something meaningful in Kotlin in my experience.Darwind
I actually can't remember but I don't think so since I would have posted the answer. I may have just converted more classes to Kotlin.Michael Vescovo
Ok, thanks. You wrote, that based on your search, you've found out that if you have a Kotlin source set folder, it should also work. I haven't found anything about that approach - do you have a link as to what to change to use this approach?Darwind
I don't have any saved links and I don't know for sure if using separate sourceSets would do anything since it shouldn't be required. I think it's probably a bug. Fortunately this was the only time it happened. I would just convert to Kotlin if you can.Michael Vescovo
Ok, I've created a bug in the big tracker for Android Studio now with a small sample project that has the exact same issue. I could always convert to Kotlin, but it's not a good solution right now, because every time I convert one file I end up having to convert 10 more because the next file uses a file that are in a flavour, so a small story ends up taking a day for something that should've taken 10 minutes. I don't have that extra time right now with a deadline coming up, so I'll have to stick to Java still for some features.Darwind

1 Answers

12
votes

So I had the same issue and I couldn't just change everything on the fly to Kotlin as our app is a production app and we couldn't afford the time to change to Kotlin right away - the legacy code should stay Java for now at least.

I reported a bug to Google regarding this: https://issuetracker.google.com/issues/110100405

And lo and behold, a Google engineer actually answered my bug report quite fast :-)

If you don't want to read the conversation we had, I'll make it short:

TL;DR version:

The reason this doesn't work with Kotlin is because your packages are wrongly set up. I will bet you, that in some of your flavors you've done the same mistake as me and created directories like com.example.mypackage instead of creating the parent directory called com and then a sub-directory with the name example and then a sub-sub-directory called mypackage.

So if your folders look com.example.mypackage change them to com with sub-directories and all should be fine.

Another solution, which is probably the easiest is to create packages with the name com.example.mypackage in the different flavors, but this can only be done, when you've selected the flavor you want to create a package for.

As to why, this doesn't create issues with Java, I have no idea and the Google guy didn't either, but it's probably an IntelliJ issue, which I'll report to JetBrains unless they're already aware of it.

It's also a big issue that the Kotlin compiler just spits out a vague error saying Unresolved reference, but that's a talk for another day and another bug report or enhancement.