apache / cordova-android

Apache Cordova Android
https://cordova.apache.org/
Apache License 2.0
3.59k stars 1.52k forks source link

Configure the need of `kotlin-android-extensions` plugin to support Kotlin 1.9 #1642

Open adjorno opened 8 months ago

adjorno commented 8 months ago

Feature Request

Kotlin 1.9 does not make use of kotlin-android-extesions plugin which is still being generated by the latest cordova-android 12.0.0 version and thus android app build fails. It would be nice to add another preference apart of { xmlKey: 'GradlePluginKotlinEnabled', gradleKey: 'IS_GRADLE_PLUGIN_KOTLIN_ENABLED', type: Boolean } to be able to configure the need of kotlin-android-extensions plugin for the android app

Motivation Behind Feature

Kotlin 1.9 does not work out of the box with the latest Cordova 12.0.0 framework. It requires manual interference to remove the line apply plugin 'kotlin-android-extensions' from the /platforms/android/app/build.gradle file.

Feature Description

Add new xml key and preference { xmlKey: 'GradlePluginKotlinExtEnabled', gradleKey: 'IS_GRADLE_PLUGIN_KOTLIN_EXT_ENABLED', type: Boolean } and apply the kotlin-android-extesions plugin only in case the property is set to true.

breautek commented 8 months ago

Do you know if kotlin-android-extensions is becoming obsolete as of kotlin 1.9?

I'd rather not add in a new preference and instead just remove kotlin-android-extensions on our next major if it's no longer being used moving forward.

Edit: Found the relevant blog post: https://android-developers.googleblog.com/2020/11/the-future-of-kotlin-android-extensions.html

It does appear to be obsolete moving forward.

adjorno commented 8 months ago

The first time Google released the intention to remove the kotlin-android-extensions was in 2020: https://android-developers.googleblog.com/2020/11/the-future-of-kotlin-android-extensions.html

Starting from Kotlin 1.7 the build process was generating a warning that this plugin is deprecated. And in the version Kotlin 1.9 the issue got stricter and now the build process fails with an error.

I believe it would be safe to remove the plugin from the template of the upcoming major version of Cordova.

bkohler616 commented 3 months ago

If anyone else runs into this when moving to Kotlin 1.9+; Add a cordova hook of before_prepare to replace the line apply plugin: 'kotlin-android-extensions' with nothing. Granted, my app doesn't use any major features of the extensions, so I didn't need to have to use the kotlin-parcelize system. Unknown on compatibility with that, your mileage may vary.

Regardless, I am now able to run with kotlin 1.9.22 just fine.

CaioMelo8 commented 2 months ago

Following @bkohler616's suggestion, for anyone interested, here's an rough draft script to remove kotlin-android-extensions from build.gradle:

#!/usr/bin/env node
'use strict';

const fs = require('fs');
const path = require('path');

const plugins = ['kotlin-android-extensions'];

module.exports = function () {
  const file = path.join('platforms', 'android', 'app', 'build.gradle');

  if (fs.existsSync(file)) {
    let newFile = fs.readFileSync(file).toString();

    console.log('Removing lines from build.gradle... ');

    newFile = removeRegExp(newFile, plugins, applyPluginRegExp);

    fs.writeFileSync(file, newFile);
  } else {
    throw `Couldn't find file: ${file}`;
  }
};

function removeRegExp(file, items, regExp) {
  const lines = [];

  for (const item of items) {
    lines.push(...Array.from(file.matchAll(regExp(item))));
  }

  if (lines.length > 0) {
    lines.sort((a, b) => b.index - a.index);

    for (const line of lines) {
      console.log(`Removing line from build.gradle: ${line[0].trim()}`);

      file = file.slice(0, line.index) + file.slice(line.index + line[0].length);
    }
  }

  return file;
}

function applyPluginRegExp(plugin) {
  return new RegExp("\\s*?apply plugin: '" + plugin + "'.*?", 'gm');
}

You can add it as a before_prepare hook, but from what I've tested, adding it as an after_platform_add hook worked just fine.

webberig commented 1 month ago

When updating to the latest Firebase SDK versions, these require you to use Kotlin 1.9. After I added the GradlePluginKotlinVersion preference to my config.xml, build failed with following error:

> Task :app:compileDebugKotlin FAILED
e: The Android extensions ('kotlin-android-extensions') compiler plugin is no longer supported. Please use kotlin parcelize and view binding. More information: https://goo.gle/kotlin-android-extensions-deprecation

FAILURE: Build failed with an exception.

It seems that adding kotlin-android-extensions causes an error when using Kotlin 1.9, so a preference would be useless.