Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using more than one android resources library/directory, R not found #787

Closed
Nikolas-LFDesigns opened this issue Jun 28, 2022 · 4 comments
Closed

Comments

@Nikolas-LFDesigns
Copy link
Contributor

Nikolas-LFDesigns commented Jun 28, 2022

In our project we use flat resources structure like

package:
- ResourceUser.java
- resources_common
- res

and BUILD.bazel like this:

android_library(
    name = "resource_user",
    resource_files = glob(["res/**"]),
    srcs = ["ResourceUser.java"],
    deps = [
        ":resources_common",
        [...]
    ],
)

android_library(
    name = "resources_common",
    resource_files = glob(["resources_common/**"]),
    [...]
)

One even could depend on some common resources from other packages if appropriate.

When trying to replace android_library definition in resource_user from example above with kotlin rules' kt_android_library (even not actually converting anything to kotlin at all and leaving a java file) and building the project, the kotlin compiler seems confused and can't find resource_files' R definitions that are linked in the [resource_user] library (but can find resources from the [resources_common] android library which is in its deps).

An error is as follows:

ERROR: [project_root]/kotlin-android-resources-example/example/src/main/java/examples/android/lib/BUILD.bazel:3:19: KotlinCompile //example/src/main/java/examples/android/lib:example_fragment_kt { kt: 1, java: 0, srcjars: 0 } for k8 failed: (Exit 1): build failed: error executing command bazel-out/host/bin/external/io_bazel_rules_kotlin/src/main/kotlin/build '--flagfile=bazel-out/k8-fastbuild/bin/example/src/main/java/examples/android/lib/example_fragment_kt-kt.jar-0.params'
example/src/main/java/examples/android/lib/MainFragment.kt:16:35: error: unresolved reference: layout
        return inflater.inflate(R.layout.sample_layout, container,  /*attachToRoot=*/false)
                                  ^
example/src/main/java/examples/android/lib/MainFragment.kt:20:39: error: unresolved reference: id
        view.findViewById<TextView>(R.id.text_view).text = getString(R.string.hello_new)
                                      ^
Jun 29, 2022 12:38:07 AM worker request 0

Might be related to some internal resource library not properly linked, but .params-0 .params-1 files for an example_fragment_kt-kt look A-OK to me (at least they have all the resources listed here).

Rules kotlin: 1.6.0
Bazel: 4.1.0, reproducible even on 5.2.0

Example which illustrates the case:
https://github.com/Nikolas-LFDesigns/kotlin-android-resources-example

Similar issues:
An issue bazelbuild/bazel#8109 sounds similar to me, but it was fixed eons ago (still, might be useful on triaging)

@arunkumar9t2
Copy link
Contributor

The root cause is due to AndroidManifest.xml. Since you are using same manifest file for both targets, two R class will be generated with same package name in the classpath and only one will get imported. In your case, it seems like R class from resources_second is getting imported which does not contain layout files.

You could fix it by either specifying different package name via custom_package or use a separate AndroidManifest.xml with a different package name.

This worked:

 android_library(
     name = "resources_second",
     manifest = "AndroidManifest.xml",
+    custom_package = "examples.android.lib.res",
     resource_files = glob(["res-second/**"]),
     visibility = ["//visibility:public"],
 )

@Nikolas-LFDesigns
Copy link
Contributor Author

The point is, we need two libraries with the same R class package and standard Bazel rules (android_library, or even android_binary) handle it gracefully by merging resources from different libraries on the same physical package as needed. That way, we can construct a library of any complexity and atomicity as we would imagine.
Also don’t forget that way we can use common resources from package1 in package2 without sharing a whole “src/main/res”, like ex. Gradle does by default.

arunkumar9t2 pushed a commit to arunkumar9t2/rules_kotlin that referenced this issue Jun 29, 2022
…ixes bazelbuild#787

When two `kt_android_library` or `android_library` has the same package name either provided via `custom_package` or due to same package name in `AndroidManifest.xml`, R class fields from current module's resources were not compilable due to order of jars appearing in `--direct_dependencies`.

This CL ensure the merged resources jar always comes first.
@arunkumar9t2
Copy link
Contributor

I just realized this is a supported case in bazel. The root problem still remains, i.e two different R class with the same package name in the classpath. Bazel handles it by ensuring the merged R jar comes first so that alone gets imported. Attempted fix in #790

@Nikolas-LFDesigns
Copy link
Contributor Author

Great job!
Though provided solution might use some generalization.. @cgruber @Bencodes could you help us here?

arunkumar9t2 pushed a commit to arunkumar9t2/rules_kotlin that referenced this issue Jun 29, 2022
…ixes bazelbuild#787

When two `kt_android_library` or `android_library` has the same package name either provided via `custom_package` or due to same package name in `AndroidManifest.xml`, R class fields from current module's resources were not compilable due to order of jars appearing in `--direct_dependencies`.

This CL ensure the merged resources jar always comes first.
arunkumar9t2 pushed a commit to arunkumar9t2/rules_kotlin that referenced this issue Jun 29, 2022
…ixes bazelbuild#787

When two `kt_android_library` or `android_library` has the same package name either provided via `custom_package` or due to same package name in `AndroidManifest.xml`, R class fields from current module's resources were not compilable due to order of jars appearing in `--direct_dependencies`.

This CL ensure the merged resources jar always comes first.
arunkumar9t2 pushed a commit to arunkumar9t2/rules_kotlin that referenced this issue Jun 29, 2022
…ixes bazelbuild#787

When two `kt_android_library` or `android_library` has the same package name either provided via `custom_package` or due to same package name in `AndroidManifest.xml`, R class fields from current module's resources were not compilable due to order of jars appearing in `--direct_dependencies`.

This CL ensure the merged resources jar always comes first.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants