_From @NathanaelA on February 25, 2016 23:55_
Windows only supports 255 character length paths... This is VERY IMPORTANT to this issue!
For some reason the CLI is creating a really long path for merging stuff using the names of each installed plugin. So for example when using 8 plugins if each of them are an average of 22 characters (nativescript = 12 by itself, almost every plugin is prefixed with those 12 characters). = 176 characters.
So If I have D:\projects\nativescript\projname = 35
Then you add in \platforms\android\build\intermediates\res\merged = 59
(176 in Plugin name characters) = 172
Then you add the image part of the path \debug\drawable-xxhdpi\someimage.png = 49
= 315 Characters. Guess what happens. No Worky :grinning: and now your platform folder is totally screwed up.
THIS IS A BAD ISSUE! It leaves the project effectively dead.
Plugins I was using:
"nativescript-barcodescanner": "^1.2.0",
"nativescript-cardview": "^0.1.1",
"nativescript-dom": "^1.0.0",
"nativescript-drop-down": "^1.2.1",
"nativescript-grid-view": "^1.3.0",
"nativescript-liveedit": "file:..\repos\nativescript-liveedit",
"nativescript-sqlite": "file:..\repos\nativescript-sqlite",
"nativescript-telerik-ui": "file:..\nativescript-ui-debug-dev.tgz",
"tns-core-modules": "^1.6.2"
Then I attempted to add: nativescript-floatingactionbutton
This is a BLOCKING issue for most people when they hit this. I have some ways I think I can work around this.
_Copied from original issue: NativeScript/nativescript-cli#1546_
_From @NathanaelA on February 26, 2016 2:28_
Ok; for anyone who runs into this -- this is a gradle issue, not a TNS specific issue.
However, the issue is still the same. Gradle / aapt apparently has a couple bugs already in for this:
https://code.google.com/p/android/issues/detail?id=187430
https://code.google.com/p/android/issues/detail?id=160994
Who knows when they will be fixed; but their is a way to mitigate the primary issue I ran into. The include.gradle files internal names can be shortened.
Inside the include.gradle files are a section that (example nativescript-cardview) looks like this
android {
productFlavors {
"nativescriptcardview" {
dimension "nativescriptcardview"
}
}
}
Edit and make it look like this:
android {
productFlavors {
"nscv" {
dimension "nscv"
}
}
}
Now the plugin only uses 4 characters rather than 20 characters. By doing this to all the existing include.gradle files the size was reduced to considerably under the 255 length.
A couple notes, this could be done via the CLI automatically; We would make the CLI when it copies over the include.gradle files automatically shorten the name... When it generates a new default include.gradle it uses a shortened name.
_From @Daxito on February 26, 2016 3:30_
Is there a way to know when we run into this issue? Any error message or something?
_From @NathanaelA on February 26, 2016 4:8_
In my case it threw lots of error messages about aapt not being able to process some of the png files. At the end it just says gradlew failed.
Here is one of the many errors sets (each error has these 5 lines)
AAPT out(1144172198) : No Delegate set : lost message:Crunching D:\projects\nativescript\test1\platforms\android\build\intermediates\exploded-aar\barcodescanner-release\res\drawable\flip_camera.png
AAPT out(1144172198) : No Delegate set : lost message:Crunching single PNG file: D:\projects\nativescript\test1\platforms\android\build\intermediates\exploded-aar\barcodescanner-release\res\drawable\flip_camera.png
AAPT out(1144172198) : No Delegate set : lost message: Output file: D:\projects\nativescript\test1\platforms\android\build\intermediates\res\merged\nativescript-barcodescannernativescriptcardviewnativescriptfloatingactionbuttonnativescript-liveeditnativescript-telerik-ui\debug\drawable\flip_camera.png
AAPT out(1144172198) : No Delegate set : lost message:Error
AAPT out(1144172198) : No Delegate set : lost message:Done
And then finally tns reports:
Command D:\projects\nativescript\test1\platforms\android\gradlew.bat failed with exit code 1
The problem is we currently make every plugin into a flavor (which is not the brightest idea), and gradle includes every flavor name to the name of the package somewhere in the build folder
This problem will automatically go away if there are only include.gradle, .aar files in the plugin's platforms/android folder.
Then gradle won't have to concat these plugin names at all.
@Plamen5kov Well that is good that only occurs in certain cases. But odds are likely when you have several plugins that at least one of them has a .jar.
Question though that you might know:
productFlavors {
"nscv" {
dimension "nscv"
}
}
Hi, @NathanaelA
Odds really are that a plugin would have .jar and that's why the .aar format may include java source code that is later .jar-ed. Another option, still available would be to put a normal .jar inside <plugin-name>/platforms/android/ folder but it would have to be only custom source code which does not require any additional resources.
If you have the scenario where you need to use resources, you would need to use the .aar format, either by dragging it along with the plugin or simply by referencing it in the <plugin-name>/platforms/android/include.gradle file.
And as for the question: The productFlavors key needs to hold the same name as plugin's name in the package.json file. You can read more about flavor dimensions here.
@PanayotCankov - Ok.
On my question; your answer doesn't match what I have found out.
productFlavors {
"nscv" {
dimension "nscv"
}
}
This is actually the changed include.gradle file I'm using for the nativescript-cardview. This works perfectly fine and I did NOT change the name in the package.json or any other files of any of the plugins. I also did this same change to 5 or so other plugin's include.gradle files to use the 4-5 character shortened names. Everything builds and is working properly. So the include.gradle doesn't care about the package.json names as far as I can see..
Hi, @NathanaelA
So the include.gradle doesn't care about the package.json names as far as I can see.., your's is an isolated case, because you have only an include.gradle file. ...did this same change to 5 or so other plugin's include.gradle files... again if they only had an include.gradle file there shouldn't be any issues. And if there is an AndroidManifest.xml there is a possibility for them to build but not work properly.The the cases I'm talking about include other scenarios which will be depricated soon. You can read more about them here, having in mind the linked documentation.
@NathanaelA it would be great if you be more careful while trying to @mention somebody.
@Plamen5kov - Ok, So if I am following you; those cases you are talking about are going away and re-naming the fields inside the include.gradle will even be safer in the future. As it is currently the only way to get around this issue on windows. From what I gather from the changes in the docs, you will be pre-merging (during installation of the plugin) the android manifest to the master one now in /app/app_resources/android?
On the @mention, oy -- I can't believe I did that. Sorry PanayotCankov.
@NathanaelA there will be no need for any naming at all.
productFlavors {
"nscv" {
dimension "nscv"
}
}
This whole block, will no longer be necessary.
It will be a breaking change for some plugins, and the scenarios I've described in the docs are what will be asked of developers to migrate to the new version of the plugins.
The unfortunate fact is, it will be a breaking change.
The good news is, for most plugins the migration should be easy.
I will take care of describing in detail how to migrate the current plugins!
Keep in mind the change won't happen overnight and you will have proper time to prepare and migrate the plugins.
Oh, very SWEET! Is this a 1.7, 1.8 or something scheduled for the whole world breaks 2.0? :grinning:
We haven't talked about it yet but it will be no earlier than 1.8
Ping @tjvantoll , @EddyVerbruggen , @sitefinitysteve, @bradmartin, @AntonioCuevaUrraco, @hdeshev , @vakrilov , @PeterStaev, @alexziskind1, @emiloberg, @PanayotCankov , @TobiasHennig, @NathanaelA, @ginev
This is concerning plugin migration. With the 1.7 release there will be a warning during build time, saying some plugins have soon to be deprecated files. This warning will be there for one release and this will be the appropriate time to migrate your plugins to the new structure. Because this will be a breaking change there is a blog post describing how exactly to migrate your current plugins to the state they need to be in.
@Plamen5kov So if my plugin needs an AndroidManifest.xml file only because it requires some permissions, I need to create a full AAR file? This does not seem right.
@Plamen5kov I was going to mention the same thing as @PeterStaev. Consider this one fi.: https://github.com/EddyVerbruggen/nativescript-bluetooth/tree/master/platforms/android
@PeterStaev
If your plugin requires only AndroidManifest.xml you'll do better to tell the user to all everything he needs in the app/App_Resources/Android/AndroidManifest.xml, in the other case where you'll need source code besides the AndroidManifest.xml :
Since 1.6 release there is an AndroidManifest.xml in `app/App_Resources/Android/` and you can put all configurations there.
@EddyVerbruggen
In this case you won't need a plugin at all you'll be able to tell the user to add all permissions the plugin needs in the app/App_Resources/Android/AndroidManifest.xml, which is the common way to do thing when developing with android plugins.
I see pro/con to having the user do this. The con being devs who have no
clue about permissions since the plugins have so far handled this. So there
should definitely be a doc section dedicated to explaining the permissions
to reduce the repetitive questions against plugins such as 'this didn't
work, it's broken' when it's just the permissions. The pro is the opposite
it gets users more comfortable with permissions and is something I think
they should know when developing mobile apps. Just my thoughts on telling
the user to add the permissions. I have no problem with the migration, as
long as it's not more work for us to ship plugins.
On Mon, Mar 14, 2016, 7:51 AM Plamen Petkov [email protected]
wrote:
@PeterStaev https://github.com/PeterStaev
If your plugin requires only AndroidManifest.xml you'll do better to tell
the user to all everything he needs in the
app/App_Resources/Android/AndroidManifest.xml, in the other case where
you'll need source code besides the AndroidManifest.xml :Since 1.6 release there is an AndroidManifest.xml in
app/App_Resources/Android/and you can put all configurations there.@EddyVerbruggen https://github.com/EddyVerbruggen
In this case you won't need a plugin at all you'll be able to tell the
user to add all permissions the plugin needs in the
app/App_Resources/Android/AndroidManifest.xml, which is the common way to
do thing when developing with android plugins.—
Reply to this email directly or view it on GitHub
https://github.com/NativeScript/android-runtime/issues/369#issuecomment-196297370
.
@Plamen5kov I like my plugins to be plug & play so usually I go to great lengths to achieve that. For me it doesn't feel right if a developer needs to manually adjust his project after he added my plugin.
Consider the case where a dev updates a plugin and in this new release a new permission is required. I can't expect devs to check the docs every time, which means I will have even more issues opened on my GitHub issue tracker.
And it's not only permissions I'm concerned about. For instance AdMob requires you to define an activity:
https://github.com/EddyVerbruggen/nativescript-admob/tree/master/platforms/android - devs may paste it in the wrong place and stuff won't work. I'd rather avoid unpleasant stuff like this.
IMO, if we want to attract webdevs and former Cordova users then we should not make it harder for them to use plugins.
@Plamen5kov I agree with @EddyVerbruggen on this one. Making plugins Plug & Play is there for cordova plugins, why complicate things here for developers asking them to read plugin documentation and manually add permissions? For people using the CLI it might be relatively OK as they most probably visited NPM/GitHub to find the plugin so they will see it in the readme. But imagine this for people using Telerik Platform that add plugins via Visual Studio extension UI for example. They will have absolutely no clue that they will have to add the permissions manually in order for the plugin to work.
If it _has_ to be this way, what if we had a spot in the package.json to define the required permissions and on build it checks to see if those are in the manifest and cancels the build with the proper message (although it really would just be nice to have the merge happen as is)
@EddyVerbruggen, @PeterStaev I'm not disagreeing with you, quite the opposite, I would do exactly the same as you. I would want my plugins to be plug and play, and @EddyVerbruggen as you said I like my plugins to be plug & play so usually I go to great lengths to achieve that.. There is a way for you plugins to be plug & play that the way is creating an .aar file where you can declare whatever you want in your AndroidManifest.xml. You are right that it puts a strain on the plugin developer, but this will pay off in the future, when there isn't unexpected behavior because of the flying AndroidManifest.xml files.
@Plamen5kov Are there (or will there be) detailed docs on how to make the aar (I've never done this before)
Was about to ask that also. No clue how to do an .aar
On Mon, Mar 14, 2016, 8:23 AM Steve McNiven-Scott [email protected]
wrote:
@Plamen5kov https://github.com/Plamen5kov Are there (or will there be)
detailed docs on how to make the aar (I've never done this before)—
Reply to this email directly or view it on GitHub
https://github.com/NativeScript/android-runtime/issues/369#issuecomment-196308495
.
Thanks @Plamen5kov - If there is a(n easy) way to create an .aar from only an AndroidManifest.xml file then I will be on board. It looks like stuff like classes.jar is required though.
@sitefinitysteve the way it is now is broken, I'd rather fix the plugins situation as soon as possible, rather than trying to patch things up
On how to create an .aar file if you read the blog post under the What possible question you may have after seeing the new structure?:
"You can simply move the content of the platforms/android/AndroidManifest.xml to the .aar’s AndroidManifest.xml. In case you don’t know what an .aar file is: it’s the output from an Android Studio module project. As you can see in this specification the .aar project structure has an AndroidManifest.xml."
In short: it's the result of Android Studio module project. it's just like an extended .jar file.
@Plamen5kov Okay, I've never even opened AndroidStudio so I'm not even sure what that's all about is the problem. Like is it literally just a (for all intents and purposes, humor me here) like a zip file to only contain the manifest. We will never have to touch that thing again to make plugin updates unless we need to add new permissions... and does this mean we have to now have some android studio project as part of our git plugins for other people to add to the aars if they have a PR?
@sitefinitysteve,
...like a zip file to only contain the manifest...and does this mean we have to now have some android studio project as part of our git plugins for other people to add to the aars if they have a PR.aar file is a product of an Android Studio Module project. If people want to contribute yo your plugin they will make PR to you Android Studio Module project and the only thing left to do, will be to publish your .aar file.@Plamen5kov The problem I see is that if we want PnP for the plugin we have to keep simple text/xml files in binary format in source control, which will make merging simple changes in those files a lot more difficult. So if the runtime needs AAR files in order to work, I feel like there should some automatic process during CLI's plugin preparation that automatically makes those AARs. If the AAR is a simple zip that the CLI could take the platforms/android directory, zip it and then put the zip as an AAR that will be used in the actual build.
@PeterStaev I'm not sure I understand correctly we have to keep simple text/xml files in binary format in source control. (in binary format - yes / in source control - no) The node_modules folder where the plugins will be, should not be included in the source control.
... which will make merging simple changes in those files a lot more difficult the changes to the plugin concerning the .aar file will consist of:
.aar file (additional step, which android studio provides with a click of a button)I feel like there should some automatic process during CLI's plugin preparation that automatically makes those AARs IMHO CLI shouldn't take over Android Studios Job of building .aar files, but that's just my opinion I'll be glad to hear more opinions on this matter.
If the AAR is a simple zip it's some kind of a zip yes, but not so simple, because it's a self contained project. It's the job of Android Studio to build that package in the correct manner.
The CLI won't do anything with the .aar files besides downloading them from npm. From there on out, gradle build system takes over and deals with all .aar files.
@Plamen5kov According to the link you put . The .aar requires a classes.jar; how does that work in the case where all I need is just a AndroidManifest.xml but have no compiled java code?
@NathanaelA, because .aar files are self contained projects they need to have some basic information about them like what's the project's name and version. This information is stored in the BuildConfig file generated by android studio, so even if you don't put any source code inside your Android Studio Module project classes.jar will be created with only one file in it BuildConfig.class containing:
package org.nativescript.mylibrary;
public final class BuildConfig
{
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "org.nativescript.mylibrary";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
}
@Plamen5kov Thanks for the insight. I was hoping to be able to short circuit the system. Create a .zip, drop the manifest in it and rename to .aar ;-D
So basically in summary; the work of a plugin developer will now be harder because any plugins that have any of the following things will now also need a Android Studio Project to create the .aar file:
@NathanaelA well, it depends. I've described in detail when .aar files will be needed in the blog post, but you can have stand alone .jar file in the platforms/android directory. In general, yes, the plugin developers will have to learn to work with Android Studio, and that might prove to put some strain on them at first.
@Plamen5kov Can we use .aar files right now without any issues -- so can I test upgrade one of my plugins to see how it works right now; or do i need to wait until some bits land in the different repos?
@Plamen5kov well now hearing more how AAR files work I see more cons for having this. Take the example of @EddyVerbruggen that he gave above about the BlueTooth plugin. There is an AndroidManifest ONLY to add appropriate permissions. So from your comments seems he cannot just add this XML file in a .zip rename it to .aar and add it to the platforms folder. He needs to create a full blown Android Studio project with some dummy module namespace just to have the plugin PnP and appropriate permissions applied correctly. And this new project will probably have to be in a separate GitHub project. This definitely does not seem right to me.
@NathanaelA thats a really good question. I encourage everyone to start trying out the new plugin structure. You don't need to wait for the next release. The functionality is already there, and you can migrate the plugins as soon as you see fit and test them out with the 1.6 and 1.7 release.
I think at this point given the choice, I'd opt to just update my readme with the permissions required and have the user add them... I don't love it, but I dont want to deal with android studio. Would also love CLI to kak still if the user doesn't add those permissions though...
@PeterStaev there are two ways of creating a plugin. Provide an .aar file which will be PnP, or telling the user to add the necessary permissions in app/App_Resources/Android/AndroidManifest.xml. The plugin developer can choose one of those options.
Let me say again that the current way of doing things is broken and we try to provide you with suitable solutions considering the build system restrictions.
If you have any ideas or proposals I'll be more than happy to discuss them.
@Plamen5kov I hope you don't feel like we are attacking you. You happen to be the lucky person to be the bearer of bad news. Creating a aar adds additional work; none of us want additional work. So we :scream: about it. :grinning:
I do think that In the majority of the situations this will be a pain since I know most of my plugins are just simple small things. However, @PeterStaev we shouldn't have to create a new repo for it; we can use the .npmignore file to ignore the whole Android Studio stuff. So I plan on trying:
| Root (Contains the plugins & packages.json)
| -> Demo
| -> AS_Project
Then I will just ignore the AS_Project folder for npm purposes.
@Plamen5kov how does the cordova-cli handle merges in configuration files? Why {N} cannot adopt a similar approach?
@NathanaelA ok, but still a whole dummy project and module only for permissions is a bit of an overkill for me :)
I agree with @PeterStaev dummy project to package up a simple manifest makes we want to checkout on android plugin development
@PeterStaev if the thing that's bothering you is the dummy project inside the platforms/android folder, there's an alternative. You can publish your .aar file in jcenter and in the platforms/android/include.gradle refer your .aar file which will be downloaded from jcenter. This will allow a plugin to be distributed with a single change in version inside the platforms/android/include.gradle file. That way your plugin won't have to drag the .aar file.
Edit: how does the cordova-cli handle merges in configuration files i've no idea, but I will check it out.
@Plamen5kov Is there no CLI android build tool that can pack the aar with just the dummy stuff and the aar at tns build? I think @PeterStaev has the same issue I do, where we don't want to even have the android studio project anywhere in the first place... like we don't want to open it to do this, and we also don't love the idea of GitIssues related to people forgetting to add the local required permissions.
...or also I mean someone adds plugin X, updates their manifest, later removes plugin X, but then has leftover permissions related to plugin X that are no longer required by the app. The current system would "just work" because it merges in at build.
Feels like how React says like "Just open XCode and do XYZ", does that make sense? Makes things more complicated, I'm not sure I would have bothered starting plugins if someone said go open android studio to do literally anything.
@Plamen5kov what is bothering me is that we need to create a dummy project and module to create a .aar file just for setting permissions, it is not the way we will distribute this file. Coming from the cordova world I do not understand how can the cordova-cli successfully merge configuration file changes required by a plugin, where with {N} we need to create a project/module to do the same thing. Since I do not know very well exactly how {N} prepares the build and how cordova does the same thing, there might be a very valid reason for you to require us to build .aar file. But you should also see that there are many cons against this approach.
To continue my brainstorming on this one: Why it is needed {N} to gradle build each individual plugin AndroidManifest.xml and res? Can't the CLI be made so that during project preparation it parses the application AndroidManifest.xml, parses each plugin's AndroidManifest.xml and adds missing XML elements to the AndroidManifest.xml that is to be used in the gradle build (basically merge all AndroidManifest.xml files in one). Then do a similar thing for the res. Won't that be possible?
@sitefinitysteve
Is there no CLI android build tool that can pack the aar with just the dummy stuff and the aar at tns build?
We might think of building projects and not just expecting .aar files, bot for now we don't have it planed.
The current system would "just work" because it merges in at build.
It doesn't work properly. That's why the migration is necessary.
@PeterStaev
... parses each plugin's AndroidManifest.xml and adds missing XML elements to the AndroidManifest.xml that is to be used in the gradle build (basically merge all AndroidManifest.xml files in one). Then do a similar thing for the res. Won't that be possible?
Yes, it is possible, that's exactly what we're doing now but it's not working properly. We should "play by the rules" and use the build system as it's intended and not try to fight it.This intended way is the .aar files.
About how cordova are doing things:
https://cordova.apache.org/docs/en/dev/guide/platforms/android/plugin.html
under Android Permissions
They have a config.xml. In it you specify a special tag pointing to the AndroidManifest.xml which is merged later on. In {N} I don't see the benefit from doing this, because we'll be adding another configuration file besides AndroidManifest.xml, which won't cover all the general cases.
Edit:
I agree with @PeterStaev dummy project to package up a simple manifest makes we want to checkout on android plugin development
You can specify the necessary permissions in the documentation and leave the user to add them in app/App_Resources/Android/AndroidManifest.xml, but if you want your plugin to by PnP, you'll have to build an .aar file.
@Plamen5kov sorry but I really fail to see how can cordova can merge changes and {N} cannot. To my understanding this problem comes because {N} uses gradle build to merge manifest changes. Instead of that I'm suggesting to merge the changes manually via some script/command/etc BEFORE the actual gradle build. So basically for the time when the gradle build is run we will have one AndroidManifest.xml file that has all the items from the app/App_Resource/android/AndroidManifest.xml as well as all additional items from the individual plugins. This has nothing to do with fighting the build system.
Requiring us to build dummy .aar for simple XML file changes is really a wrong way, plus adding overhead to the whole final .apk - imagine using 10 plugins that all require some permission: this will result in 10 AAR dummy modules containing dummy .jar being included for the sole purpose of handling permission and nothing more. Next thing you know, you will be you asking us to build .a/.framework files for iOS for handling plugin Info.plist changes...
@PeterStaev it's not that {N} can't merge resources, but rather that it wouldn't be smart to do so, keeping in mind the fact gradle does these merges for us. And this "manual" script you speak of is error prone and demands additional effort when there is a tool chain already dealing with all cases.
imagine using 10 plugins that all require some permission: this will result in 10 AAR dummy modules containing dummy .jar being included for the sole purpose of handling permission and nothing more.
This will not affect performance in any way, and will cover more corner cases, than ones that are covered now.
@Plamen5kov of course it will be error prone. Everything is error prone. As you see even the current gradle build you are using is also error prone... But this is no valid reason for not doing it.
Is it better to compile my plugin all the way down to an .aar and .a for android and iOS respectively and only ship .aar .a files (instead of JS) to which {N} can just add reference and build? Sure it is and it is less error prone as there will be very limited room for errors on the {N} side. But does this make it a good way to handle cross-platform projects? I would say it is not.
But seeing this is a lost cause (and seems it is only me that sees problems and wrong ways of doing things :)) I will just bail out of the topic and as @sitefinitysteve said will just put a note in the readme of the plugin and then let end users hammer their heads why the plugin fails to work appropriately.
Guys, I would like to add another perspective on this. The main reason for this suggestion (sticking with *.aar files) is that our team is too small to "fight" with gradle build system. Also, don't get it wrong. We don't throw the first random solution to the problem. Quite on contrary, we consider it carefully and we think it is a very good compromise of all parties involved. Once we acknowledge that our suggestion is a "compromise" there is a plenty of room to discuss other, better approaches. Just keep in mind that our team is very resource constrained and if you come up with a better idea you guys should be the leading part and of course we will help you as much as we can.
@slavchev considering this is breaking change and since as you already noted this is a compromise for all parties involved why haven't you involved all those parties in a bigger discussion to find a better compromise (if possible). I think many people in the community would have contributed in finding/implementing a better solution and helping your small team. Yet a full blog post announcement was written that resources and manifest are going away and that we need to build .aar if we want plugins to be PnP. This looks like the decision was already made and we were just "pinged" to know that we need to change our plugins.
And there are already couple of possible solutions given here:
ns1, ns2, ....aar packaging of plugin XML/res during tns build@PeterStaev Nothing is set in stone yet. That's why we have this discussion here :smile: Think about the blog post as another way, besides GitHub, to make you guys familiar with our plans.
Now, let's continue the discussion.
Shorten plugin names during build (from @NathanaelA) - it does not have to be a meaningful abbreviation, it could be as simple as ns1, ns2, ...
Obviously, this does not solve the problem. This is just a temporary remedy.
Add automatic .aar packaging of plugin XML/res during tns build
We could go this way and indeed we could provide a working solution for the most basic scenarios with relatively small effort. However, right now our team does not have enough resources to provide a solution that cover any corner case. If you guys want to go this way then we will help you as much as we can.
Create a separate tool/provide alternative way for merging XML file changes
Again, this is a matter of resources. I encourage you to make a proposal with a clear scope so we can decide whether we can implement it or not.
Hi all,
To help this discussion I update one of my plugins. The AndroidManifest.xml is now part of a 'library project' that's built into an .aar. Check the readme on how to update the manifest in this case.
An .npmignore will make sure it's not pushed to npm, so it won't be fetched when doing a tns plugin add nativescript-calendar.
This structure works fine (tested with tns 1.6) and as an experienced Java/Android dev it's not too hard for me to do this, but I'm sure it's a PITA for novice devs that want to create their first plugin.
@PeterStaev I didn't say it wasn't overkill. I still fully think it is a total overkill to create a aar for a simple manifest change. ;-) I just wanted to know if I can see how it works today. I'm not any happier about it than you are.
Shortened include.gradle names actually only works in some of the cases; it does NOT work in the case the plugin has a manifest, so it is pretty hacky hack. ;-(
@NathanaelA The shortened paths do not work probably because you only shortened the flavors/dimensions. From what I see the plugin name is also used on other spots - like subfolder in the configurations directory. So the whole build script will have to be changed to account for those short names.
@slavchev I dont see why this solution does not solve the problem. The whole thing comes from the fact that the path is limited on Win (when will you change this MS?!?!?!). So the idea is to shorten that path as much as possible. True that it won't work in all cases, but even the proposed .aar solution will fail if I put my project deep inside some folder structure. So to me this solution will fit perfectly and will require least amount of changes (from both {N} and plugin dev side)
You can provide those corning cases for the automatic .aar you are talking about and then we can see what we can do about those :)
@EddyVerbruggen Thanks for putting this! At least now it is clear what an overkill this is ;)
@PeterStaev Using shorten names doesn't scale. It is only a matter of how many plugins you use and the path length of your project folder. We will just postpone the problem.
I guess it might seem tempting to stay on this way but we all know where it leads, don't we? :wink: I think we should focus on what we all have in common - the desire to improve {N} as a platform. Using *.aar files will provide sustainable model for grow. It works for the whole Android community. So it makes sense to use the same approach. Also once we lay the solid foundation we will have time to improve the tooling and maybe come up with a solution to automatically package AndroidManifest.xml file.
Let's keep the discussion and hear other suggestions.
EDIT: Here is how we could be creating *.aar file that contains AndroidManifest.xml file (tested)
apply plugin: 'com.android.library'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
}
}
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
minSdkVersion 17
targetSdkVersion 23
versionCode 1
versionName "1.0.0"
}
buildTypes {
release {
}
}
}
I guess we can integrate something similar in tns so you guys can generate *.aar files without much hassle.
Using *.aar files will provide sustainable model for grow. It works for the whole Android community. So it makes sense to use the same approach.
You know this sounds really awkward when seen on a repo for cross platform framework...
Let's stick to constructive comments :smile:
@slavchev I have a separate question, sorta related if I grab a plugin that has compileSDK & TargeSDK at 23; but my project is limited to 22; will it work with it? At this moment the only way to avoid the dreaded Android 6 perm issues (that won't be fixed until 1.8?) is to use Target of 22. So what happens in this case?
@NathanaelA I guess it will work as long as it uses API level 22 or lower. I have to test it to confirm though.
@slavchev that was my guess; I was hoping you guys had already ran into this and had a ready answer. :grinning:
The team gave a lot of thought on this discussion and one of the main problems we saw was the case when you would need to create an .aar file for the soul purpose of putting an AndroidManifest.xml in it.
We tried out testing the scenario where we build .aar file, instead of the plugin developers, as the you all suggested. What we tried doing is, introduce a build script that takes care of the specific permission issue. If we try to build every plugin that has only an AndroidManifest.xml file in its platforms/android folder we would add 4s per plugin, but that doesn't seem like a good solution.
The second approach we tried is pushing the AndroidManifest.xml file in a pre-build .aar file. This was considerably faster, but it caused another issues. The newly generated .aar files were invalid for gradle and it failed on the dexing phase, because the BuildConfig in the classes.jar file is the same for all plugins generated this way.
In conclusion, plugins made at build-time take a lot of time. A future solution that we can suggest is using CLI to help build your plugins. Nativescript CLI already has this as a story: https://github.com/NativeScript/nativescript-cli/issues/586
Hey guys, @Plamen5kov , @mslavchev ,
I'm wondering how we'll support plugin variables in case this suggestion is implemented. Currently you can define plugin variables in plugin's package.json and use them later in your AndroidManifest.xml (with 1.7.1 of CLI, which is just around the corner, you can use them in strings.xml as well). This is really important when you want to use the value of the variable in your plugin's native code. What will be the expected workflow in case we decide to drop separate files and require .aar file from plugin. How we'll replace the plugin variables values from project to plugin's .aar file?
I'd like to do a summary on this issue and how we are going to proceed in the short term. Let me begin with the engineering reasons behind the proposed breaking change with the .aar files.
Me and the team believe this is the most sustainable engineering-wise solution in the long run. Our thinking is that we should stick with the underlying native platform tools instead of making our own fork (implementation) on top of it for the sake of hiding some of the native paradigms behind an assumingly easier to digest abstraction. So far our practical experience proved that fighting with Gradle is a battle already lost. Instead, we decided to embrace Gradle and walk our path together. With that said, and because .AAR files are the organic library format in the native Android World, we suggested the aforementioned breaking change.
Besides the concrete bug with the long paths on Windows, the suggested change would have also fixed several issues related with merging resources through flavors. It would also make the Gradle build script less complicated and more straightforward.
We heard some valid concerns against the change:
AndroidManifest.xml in their platforms/android folder it would be an overhead to prepare a full-blown .AAR file to just embed the manifest..AAR file itself requires knowledge of Gradle and Gradle's project structure.App_Resources/Android/AndroidManifest.xml file.After we gathered this feedback we tried to extend the solution to mitigate the concerns. What we did was:
.AAR file upon tns plugin add. While this seemed a viable solution at first, it ended up to the cloud builds and the lack of cache there.AndroidManifest.xml in a pre-built temporary .AAR file but this turned not working at all.None of the workarounds worked for us. While we continue to believe that the originally suggested solution with .AAR files is the only viable engineering-wise solution, sustainable in the long run, we agreed that we will try to provide a temporary fix to the long paths issue on Windows by manually minifying the names (suggested by @NathanaelA). This approach may turn error-prone but for the time being this is the only solution that fixes the issue and seems to be working in all scenarios.
@atanasovg - Awesome summary; I was under the impression that my technique that I came up with does not work in the cases the plugin actually has a AndroidManifest.xml -- apparently the gradle script won't be able to find and merge it... Did you find some way to mitigate this issue?
As to your workarounds issues -- here are a couple possible mitigation strategies:
1 & 2. I don't know how beefy your cloud building devices are are; but if you have the android sdk and tns tools on a ssd drive and make the actual builds be ran on ram disks; I would venture a guess that would pretty much eliminate any speed hit you would normally be taking, I could be wrong here as I'm not sure if the hit is caused by disk access speed or something inside gradle (i.e. processing); but it is a theory that could be easily tested and might allow Peter's workaround to be used as otherwise it seems to be a worthwhile solution choice other than your cloud build issues.
2 (only). The other choice would be to add some smarts to your own internal build scripts and start caching the pre-compiled plugins -- then during the installation of the plugins you add a step your build scripts to automatically pull the already pre-built aar files from your cache. At end of build, you add a step that runs through all the built aar files and checks to see if any of them aren't in your cache and then sticks them in the cache. Or as a stop gap measure you can simply take a nightly cron job and do what we do on the NS.Rocks site and pull a updated list of all the plugins and then nightly pre-build every single new plugin version, but I'm not sure how sustainable that will be if the eco system grows massively; but this could get you way way down the road before you have to worry about changing anything again (if ever)
\4. So in effect to solve that issue you would need a custom tool; which could cause more support issues and maintenance; could be done but not the ideal situation.
All of this is getting beyond what I know so when is all of this going into effect? What are the exact steps I need to take for all of my plugins to continue working properly? If this is going to cause version issues, is there a grace period? I have several plugins and if it involves a lot of work that is going to just suck. Sooner I know what I need to actually do I can start preparing/learning about .aar files and everything else. Just wanting to get ahead of whatever is going to be established. I might not fully understand the entire process, just don't want my plugins to stop working when the changes happen :smile:
@bradmartin Plugin authors shouldn't change anything (probably that didn't become clear from my comment). We will do some dynamic name minification which should solve the issue with the long paths for now.
@NathanaelA @blagoev has found a solution (https://github.com/NativeScript/android-runtime/pull/419/files). We are still to run it through our CI infrastructure and plugin verification mechanism but it does seem working.
@atanasovg - I think both @bradmartin and I got the impression that leaving things with the shortened name hack was still a temporary solution and that in the near future the official method would be finally decided.
That is why I suggested a couple ways that might help narrow the field down because at this moment we appear to have a couple options but each of them has some downside.
Option 0 (original proposal) alone appears to be a non starter because of the added plugin developer work and appbuilder/plugin cli variables issues. However with option 4 in place (AndroidManifest merging , option 0 because valid as this eliminates the majority of the work for almost all plugins and allows you the Appbuilder/plugin cli variables to work. However, this requires building and mainating a new tool/scripts.
Options 1 & 2 seems like great solutions; but since they don't work for your build farm, I tossed out some suggestions that might allow them to work properly on your build servers in a fast method.
But I echo Brad's message; at the point the final solicitation is decided let us know so that we can get our plugins properly formatted...
@Plamen5kov Please push out that automatic .aar builder, even if we have to add a --auto-build-aar to the prepare/run/build/emulate command to activate it, so there's a simple solution for us.
The extra 4 seconds is not a showstopper for everyone. It would be excellent if it just took the manifest and any .java files in that folder and built the .aar if that flag was provided.
Hi @vbresults,
Currently we don't have the resources to build such a tool, but we accept contributions from the community.
Most helpful comment
Hi all,
To help this discussion I update one of my plugins. The
AndroidManifest.xmlis now part of a 'library project' that's built into an.aar. Check the readme on how to update the manifest in this case.An .npmignore will make sure it's not pushed to npm, so it won't be fetched when doing a
tns plugin add nativescript-calendar.This structure works fine (tested with tns 1.6) and as an experienced Java/Android dev it's not too hard for me to do this, but I'm sure it's a PITA for novice devs that want to create their first plugin.