Why Is Doppl Trying To Pull in ReactiveStreams? - doppl

I am attempting to convert parts of an Android app to iOS using Doppl, and I am getting a strange result: Doppl keeps trying to pull in android.arch.lifecycle:reactivestreams, even though I don't want it to.
Specifically, in app/build/j2objcSrcGenMain/android/arch/lifecycle/, there is a reactivestrams/ subdirectory with R.h and R.m files in it. This seems to make Xcode cranky and may explain why I had some oddities with pod install.
My app/build.gradle has compile "android.arch.lifecycle:reactivestreams:$archVer", because my activity is using LiveDataReactiveStreams.fromPublisher(). However:
The activity is not in the translatePattern (and since its code is not showing up in app/build/j2objcSrcGenMain/, I have to assume that the translatePattern is fine)
I do not have a doppl statement related to reactivestreams, because there does not appear to be a Doppl conversion of this library (nor should it be needed here)
AFAIK, nowhere else in this app am I referring to LiveDataReactiveStreams, which AFAIK is the one-and-only public class from the reactivestreams library
So, the questions:
What determines whether Doppl creates R.h and R.m files for some dependency? It's not the existence of a doppl statement, as I have doppl statements for a lot of other dependencies (RxJava, RxAndroid, Retrofit) and those do not get R.h and R.m files. It's not whether the dependency is referenced from generated code, as my repository definitely uses RxJava and Retrofit, yet there are no R files for those.
How can I figure out why Doppl generates R.h and R.m for reactivestreams?
Once I get this cleared up... do I re-run pod install, or is there some other pod command to refresh an existing pod with a new implementation?

Look into 'app/build/generated/source/r/debug' and confirm there's an R.java being created for the architecture component. It'll be under 'android/arch/lifecycle/reactivestrams'.
I think there are 2 problems here.
Problem 1
Somehow Doppl/J2objc is of the opinion that this file should be transpiled. It could be either that 'translatePattern' matches with it, or that something in the shared code is referencing it. If you can't figure out which, please post a comment and I'll try to help (or post in slack group).
Problem 2
Regardless of why that 'R.java' is being sucked into the translate step, because of how stock J2objc is configured, the code is being generated with package folders instead of creating One Big Name. That generated file should be called 'AndroidArchLifecycleReactivestramsR.h' (and AndroidArchLifecycleReactivestramsR.m). Xcode really doesn't like package folders. That's why there's a slightly custom J2ojbc being used with Doppl, so we can have files with big names instead of folders.
In cases where you intentionally use package names that match with what J2objc considers to be "system" classes, you need to provide a header mapping file to force long names. The 'androidbase' doppl library needs to add a lot of files that are in the 'android' package, which J2objc considers "system". We override those names in the mapping file.
build.gradle
https://github.com/doppllib/core-doppl/blob/master/androidbase/build.gradle#L19
mapping file
https://github.com/doppllib/core-doppl/blob/master/androidbase/src/main/java/androidbase.mappings

I screwed up.
In my dopplConfig, I have:
translatePattern {
include '**/api/**'
include '**/arch/**'
include '**/RepositoryTest.java'
}
In this case, **/arch/** not only matches my arch package, but also the arch package from the Architecture Components.
Ordinarily, this would not matter, because the Architecture Components source code is not in my project. But, R.java gets generated, due to resources, and the translatePattern includes generated source code in addition to lovingly hand-crafted source code. So, that's where my extraneous Objective-C was coming from.
Many thanks to Kevin Galligan for his assistance with this, out on the #newbiehelp Doppl Slack channel!

Related

Restrict Android Studio/Gradle resolving source paths (symlink problem)

This may be a bit of a XY problem in that it involves symlinking files into the source tree. I sometimes do this in development with libraries that are common to a number of application projects. More conventionally they would (and later will) be just .aar imports. Not doing that simplifies API tweaks on the library in the context of the application code -- an option would be to automate packing and importing the aar, but that is still more of a PITA and means I either run two projects in the IDE at the same time (untried) or else switch between them.
Generally the symlinks are just directories, but currently I am doing it with individual files, and a strange problem has blossomed trying to build the app involving "Redeclaration" errors. This occasionally happens with the directories, but it is usually resolved by a gradle re-sync or an invalidate-and-restart.
To be clear, the problem is one that should not exist and smells very much like a bug: The "redeclaration" refers to the symlinked locations which are not in the build tree or project folder -- ie., the redeclaration involves processing the same file twice with different paths.1
Frustratingly, invalidate-and-restart did not work with the individual files, so I removed the symlinks and just copied the files in. No more symlinks, but bizarrely the same problem happens:
./gradlew assemble
> Task :app:compileDebugKotlin FAILED
e: /home/devel/Android/lib/droidutil/src/cogware/droidutil/Plexus.kt: (5, 8): Redeclaration: Plexus
e: /home/devel/Android/template/FooDemo/app/src/main/java/cogware/droidutil/Plexus.kt: (5, 8): Redeclaration: Plexus
(Same thing using the IDE.) The project folder here is /home/devel/Android/template/FooDemo. /home/devel/Android/lib/droidutil/src/cogware/droidutil/ is not part of it -- although to be fair there are still other symlinks into it, all gradle needs to do is follow the explicit path set for it. What seems to be happening now is:
It resolves symlinked paths and uses them not instead of the symlink paths, but as well as.
It even searches around in the resolved paths for files that match names in the proper tree! To explain: After I removed the symlinked files, symlinked directories (which are working fine) remain, but not into the droidutil directory above. There is, eg. a /home/devel/Android/lib/listfilterstack linked in, and it still manages to find a "Redeclaration error" in /home/devel/Android/lib/droidutil/src/....
The only thing that would make less sense would be if it were searching around the whole filesystem at random.
Why does it retain this path and how do I get rid of it?
Invalidate-and-restart does not make any difference. I've tried adding this to app/build.gradle:
android {
...
sourceSets {
main {
java {
exclude '/home/devel/Android/lib/**'
srcDirs = [ 'app/src/main/java' ]
}
}
}
Which exclude apparently has no semantic value there -- same error. Invalidate-and-restart again -- same error.
Short of wiping my hard drive and starting the project again from scratch on another computer in a different time zone, the only thing that has worked is for me to literally move /home/devel/Android/lib to somewhere completely else so that the path no longer exists. I should not have to do this. I should be able to explicitly set where the build tool searches for sources, and not have it unravelling symlinks and prowling around hither-and-thither.
I miss include guards.
Seems like it is a bug, but unfortunately the kind that will probably never be completely fixed:
https://github.com/gradle/gradle/issues/3982
Not exactly the same context or symptoms, but the takeaway for me is that gradle was not implemented to deal with symlinks in an intelligent way, hence:
Don't use symlinks with gradle.

Scons command/explicit dependency

I have a code snippet similar to this:
# Compile protobuf headers
env.Protoc(...)
# Move headers to 'include' (compiled via protobuf)
env.Command([include headers...], [headers...], move_func)
# Compile program (depends on 'include' files)
out2 = SConscript('src/SConscript')
Depends(out2, [include headers...])
Basically, I have Protoc() compiling protobuf files, then the headers are moved to the 'include' directory by env.Command() and finally the program is compiled through a SConscript file in the 'src'.
Since these are header files that are being moved (that the src compilation depends on), they are not explicitly defined as a dependency by scons (as far as I understand). Thus, the compilation runs, but the header files haven't been moved so it fails. I have tried exposing the dependency via Depends() and Requires() without success.
I understand that in the usual case, scons should "figure-out" dependencies, but I don't know how it could do that here.
Thanks!
You seem to be thinking in "make" ways about your build process, which is the wrong approach when using SCons. You can't order single build steps by putting them in different SConscripts, and then including those in a special order. You have to define proper dependencies between your actual sources (C/CPP files for example) and a target like a program or PDF file. Then SCons is able to figure out the correct build order, and will traverse through the folder structure of your project automatically. If required, it will enter subfolders more than once when the dependency graph (DAG) dictates this. Defining this kind of dependencies between inputs and outputs is usually done, using a Builder...and in your case the Install() builder would be a good fit. Please also regard the hints for #2 in the list of "most frequently-asked FAQs" ( https://bitbucket.org/scons/scons/wiki/FrequentlyAskedQuestions).
Further, I can only recommend to read a little more in the UserGuide ( http://www.scons.org/doc/production/HTML/scons-user.html ) to get a better feeling for how to do things in a more "SConsy" way. If you get stuck, feel free to ask further questions on our mailing list at scons-users#scons.org (see http://www.scons.org/lists.php ).
Finally, if you have a lot of steps that you want to execute in serial, and that don't require any special input/output files, SCons is probably not the right tool for your current task. It's designed as a file-oriented build system with automatic parallelization in mind, a simple (Python?) script might be better at the mere serial stuff...

Gradle finished with non-zero exit value 1 (ic_launcher.png: error: Duplicate file)

I got this strange error with gradle, please help me!
/.../app/build/intermediates/res/debug/drawable-xxhdpi-v4/ic_launcher.png:
error: Duplicate file
/.../app/build/intermediates/res/debug/drawable-xxhdpi/ic_launcher.png:
Original is here. The version qualifier may be implied.
Error:Execution failed for task ':app:processDebugResources'.
com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException:
Process 'command '/.../sdk/build-tools/22.0.1/aapt'' finished with non-zero exit value 1
Before it was operating normally, but since I put classpath com.android.tools.build:gradle:1.2.2, this causes me errors
According to Xavier Durochet's explanation on G+, it's due to one of the libraries you use having it's own ic_launcher.png -- which they of course should not (more on that at the bottom).
Chances are the two icons mentioned in the log are different: one is yours and another one is most likely the generic android icon that someone forgot to remove from the library.
To see the offending dependency, hit Ctrl + Shift + N twice (for non-project matching) and type in ic_launcher.png (See the last line on the screenshot)
To work around the issue temporarily, add the -v4 qualifier to your drawable resouce folders (or move just ic_launcher.png to *dpi-v4 if you have your reasons) -- credits to Xavier Durochet for the solution. You can also just rename your icon into something else and make corresponding change to AndroidManifest.xml
The real issue is that the offending lib carries the useless icons. Libraries that have their own resources (like ActionBarSherlock or Google's own Support v7 library) use distinctive naming schemes to avoid collisions with your resource names (abs_, abc_).
Launcher icons have no business being in a library so I encourage you to notify the author of the lib you're using that they forgot to remove the redundant ic_launcher.png files.
Also worth mentioning, as Barry Carroll noted very precisely in the same discussion, this doesn't mean your resources should never overlap those in the library: there are a lot of legit reasons to override a lib's resources with your own (e.g. changing the looks of a library-provided activity) and gradle plugin's resource merging logic does allow this, on purpose.
It's just that in this particular case, the conflict occurs when the lib is behind on the android gradle plugin version (pre-1.2.2) in which case resources end up in two different *dpi folders -- with and without the -v4 qualifier; but they're actually in the same resource "bucket" so the system considers them to be duplicate.
This glitch does bring out the useless ic_launcher.png override (actually, a collision -- due to the glitch) but this situation is not universally bad for other kinds of resources.
I.e. sometimes you intentionally override a lib's resource and this glitch will still cause the error message to pop. This time there's no real problem with resource names, so the temporary solution above or holding back the plugin version are the way to go.
I had the same problem while using a third party library.(RomainPiel/Shimmer-android library on Github)
To solve it, I moved my ic_launcher.png files from drawable folder to mipmap folder. And problem solved.
Downgrading to com.android.tools.build:gradle:1.1.3 sloved my issue
Here is the general method to find the problem:
Run
./gradlew build --stacktrace --info
and You will find the details of errors.
I found my error : a duplicate class caused a TOP-Level error, and remove the duplicated one will solve the problem.
For me a simple "clean project" and "rebuild project" did the trick.
Upgrade to 1.2.3, but ensure that your gradle and buildToolsVersion are identically in your project and the used aars.
In case you use external libs where you can't control the gradle/build version:
Contact the author or check the sources by your own. Some libraries have unused launcher icons which will cause this conflict. Removing this icons will solve your problem. Identically named sources (e.g menu.xml) could also cause this issue in rare cases. An easy workaround would be to rename your ressource.
Just rename ic_launcher.png to something else (e.g ico_launcher.png)
In my case I have added apostrophe s ('s) to strings.xml file.
Do check guys for any such error and remove it will definitely help.
It's so annoying the IDE can't show the error properly rather makes all resources out of sync..
I know it's not the case which is asked in Question but error is quite same i.e. Gradle execution gets failed.
Simply Rename the Image (Rightclick on the Image, Select Refactor and select Rename). It will solve the issue as the Issue has arise as one of the library is also using the image with the same name.
I had the same problem and what follows worked for me:
rename your icon
add tools:replace="android:icon" to your <application> tag in the Manifest
You can try just the first step, but I still had problems when merging the manifest files. This way it should override whatever resource was used in the library.
Follow this link Here
Or
Make change like this.
repositories {
maven {url "https://clojars.org/repo/"}
}
dependencies {
compile 'frankiesardo:icepick:{{latest-version}}'
**provided** 'frankiesardo:icepick-processor:{{latest-version}}'
}
Update to newest gradle plugin 1.5.0 sloved this issue. Update following script in your root build.gradle file
buildscript {
...
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
}
...
}
I managed to trigger this problem by inconsistent capitalisation of filename extensions. I had a .jpg image in one drawable directory, but an image of the same filename but .JPG in a different drawable directory. The filenames and directories were right, but the extensions weren't.

Referencing the Extension Java files between dependencies

Working on the new android side of extensions with the changes. I have my separate extension as its own dependency.
In my code I require references to the Extension.Java class as well as the HaxeObject.
These are located in extensions-api, which is it's own separate dependency.
I've tried including these files in my own dependency, this causes top-level exceptions because a number of the Java files were included twice. I've also tried not including the extensions-api, this works to some extent, however If in the future I decide to use more extensions this won't work (less than ideal).
I need to find a way to reference these files from one dependency to another. so from: MyExtension.src.org.haxe.nme.MyExtension and extension-api.src.org.haxe.nme.Extension
So I guess the point I'm stuck at is how I make these two dependencies see each other whilst compiling so that when they merge to make the .dex file they don't cause top-level exceptions.
I could potentially hack it by placing my extension into the extension-api folder. Something like:
<dependency name="extension-api" path="dependencies/MyExtension" if="android"/>
The issue with this being that the androidManifest merging wouldn't work.
I found the answer here:
the gist is in the project.properties file you want to add the line:
android.library.reference.1=../extensions-api
http://www.openfl.org/community/general-discussion/native-extensions/

how to distribute a Flash component for use with MTASC?

I have a Flash component that's just a library of compiled code with some exposed API calls. Normally we distribute this as a SWC or MXP, and it works just fine. Recently I had a client express interest in using my component, but they do all their development in MTASC only. MTASC doesn't support SWC files, so ss there a good way to send precompiled code that would work in MTASC? I'm not able to send them the original source code, but if there's some other method I'd appreciate it. I do have access to the source, so I can recompile it however necessary. Thanks!
I did find an answer, and I'm not 100% sure if this is exactly the process since I'm no longer at that job and don't have the computer/process in front of me anymore. It was a bit of a hack.
What it involved basically was unzipping the SWC file and getting a .swf and a bunch of .asi files out.
The .asi files are really just ActionScript files, but they contain intrinsic definitions, or just prototypes or footprints of whats actually there. The real meat of it is still in the .swf.
So you rename all those .asi files to .as and then put them into your MTASC classpath. Since they contain definitions, you shouldn't be getting any more "undefined variable" or "undefined function" errors at compile time. Now you just need to pull in the SWF, where the actual function bodies are defined, using loadMovie. once the loadMovie is complete, you should be able to use all of the functions.
The only caveat of course is that you have to wait for that SWF to load before calling of any of the functions from the SWC.
so step-by-step, it looks like this:
1.) unzip the SWC file. this can be done using WinZip or OS X terminal unzip command
2.) Rename .asi files to .as
3.) add new .as files to MTASC classpath
4.) add AS code to load the .swf in and make sure none of the SWC functions are called before the SWF is loaded
5.) compile
I'm pretty sure this is what we did, but i'm not in a spot to try it out right now.,
Hope this helps, let me know if you have any other questions and I'll see if I can help figure it out any more.

Resources