AOSP PackageManagerService referencing Roboelectric and therefore does not compile - android

I built AOSP 5.1.0_r3 and imported into IntelliJ. And followed these steps.
But When I open for example PackageManagerService.java code its not able to compile and its referencing external/robolectric/lib/main/android.jar/android/os/Process. For example SHELL_UID is missing:
private static final int SHELL_UID = Process.SHELL_UID;
If I look in standard android.jar the SHELL_UID it's there.
There are many more cases like this. What could be wrong here?
Screen1:
Screen2:
-----> UPDATE 2 FIXED ISSUES:
Added excluded-paths also found out that I had to delete the dependencies in the Project structure:
In PackageManagerService.java it still cant resolve symbol:
-----> UPDATE 2 OPEN ISSUES:
And in this Manifest (and others) it cant resolve several symbols (related to Android):

This is not a common problem I'm aware of, so I'm not entirely certain why you are seeing this error specifically. Regardless, to avoid the IDE getting confused, you could add external/roboelectric to a custom excluded-paths file so Idegen will ignore it in the generated IDE classpath.
If you don't already have one of these files, it goes in the top-level directory of your AOSP tree, and contains directories to exclude during generation. You can see the built-in exclude file for example syntax.
Idegen is supposed to exclude all JAR files, but it may only do that for files in out/ and prebuilts/.

Related

Dependency missing but exists in APK, how?

I have a MyLocationService library, which has dependency from huawei_location_service.Inside I have HMSLocationService class which is the only one using huawei_location_service classes and I use relfection to access that class. Meaning is, if we run app on Huawei and if there is dependency from huawei_location_service, I will get location, otherwise will not. And application should run perfectly on non-hauwei devices without dependency from huawei_location_service.
So when I build MyLocationService.aar I removed huawei_location_service dependency from it's pom file. After that I created a new application and added dependency from MyLocationService.aar. When I check dependencies with command gradlew app:dependencies I don't see any dependency from huawei, but when I create an apk and analyze it, in classes.dex there are classes from huawei_location_service.
Question: How it is possible? And is there any other way to achieve what I want?
P.S. I analyzed also MyLocationService.aar, didn't find any huawei dependency. Is there another way to check dependencies of *.aar files instead of pom or analyzing tool of android studio?
So if someone will be mistaken as me, this answer will help.
The repositories and classes I saw in classes.dex were not coming from hms libraries. As I have imports in my custom classes, that imports' texts were the reason I was seeing huawei folder in classes.dex. Also take attention on the size, and you can see that they are kind of 20 bytes.
So I removed the imports, generate my library again, created apk and analyzed it and woala, no huawei folder is visible.
P.S. *.aars doesn't contain any library if you not put transitive=true. And you need to add dependencies required by your lib in your own applicaiton.
P.S.S. If you have locally or globally publishing your library, maven(Gradle uses maven) creates metadata, so called POM file, as a helper to identify all dependencies that the library needs.

"Uses reserved file or directory name 'lib'" error when trying to build android app bundle

I'm trying to build an app bundle but I'm getting the following error:
File 'root/lib/x86_64-MacOSX-gpp/jni/libjunixsocket-native-2.0.4.jnilib' uses reserved file or directory name 'lib'.
For what I've seen from similar questions, this issue is normally solved juggling dependencies or files in the project structure, but in this case it seems to point to a native library involved in app architecture if i'm not mistaken. Any ideas how to solve this?
It looks like you are adding a dependency as a jar instead of an aar.
The aar contains the information of what files should be considered as Android resources, native libraries, etc. in the app. A jar is just a plain list of files without Android concept. Because the jar you're depending on contains a directory lib, the files would normally end up being considered as native libraries, but because the files come from a jar instead of an aar, the build system warns that it's unlikely to be a native library and may have unintended consequences at runtime.
Try to package that library as an .aar instead of a .jar. See this documentation: https://developer.android.com/studio/projects/android-library
Edit:
Note that this file could not be loaded by the Android platform if it was included as is in the APK, so even though the previous build systems would allow you to put anything in an APK, the Android App Bundle is more restrictive to ensure that you don't accidentally put unnecessary files which would increase unnecessarily the size of your app.
Ok it is working now! Steps I used to found the problem (thanks for pointing me in the right direction #Pierre)
Run a gradle build --scan from your terminal or go to the Gradle tab in Android Studio, select :app, help , androidDependencies to see your dependency graph.
Search the dependency graph for the library name related to the problem ( in my case I searched for socket, there was no match for libjunixsocket for example).
Going upwards on the dependency tree I realized it was caused by the 'io.voucherify.android.client:voucherify-android-sdk:2.1.0' dependency.
I just added #aar at the end of the dependency implementation, and I managed to build the app bundle.
implementation 'io.voucherify.android.client:voucherify-android-sdk:2.1.0#aar'

An error after adding a library to the Android project (More than one file was found with OS independent path 'META-INF/kotlinx-io.kotlin_module')

I've been playing with the "Hello World" project created in Android Studio 3.3 (New Empty Project) and decided to add a library (ktor) to the project. I followed the README instructions and simply added the required things to the gradle file. As I worked with the websockets, the following lines have been added to the app's gradle build file:
implementation "io.ktor:ktor-client-websocket:$ktor_version"
implementation "io.ktor:ktor-client-cio:$ktor_version"
implementation "io.ktor:ktor-client-android:$ktor_version"
implementation "io.ktor:ktor-client-cio:$ktor_version"
Right after adding these the project stopped to compile and I received the following error:
More than one file was found with OS independent path 'META-INF/kotlinx-io.kotlin_module'
Could someone please explain why do I get this error? I did not do anything illegal, I just added library to the simple, standard empty project created in Android Studio and somehow after adding a new dependency, things stopped to work well.
I found some similar questions on StackOverflow and GitHub Issues, but I did not find a good explanation why does it happen and how to prevent such errors. I just found a bunch of quick and short answers / solutions, written in a manner "Add this to your project configuration and it'll work, trust me, I'm an expert", but I'm not satisfied with it as I think that as a developer I must understand what am I doing and why it works this way and IMO it's not professional just to add things the one does not fully understand, hoping that it'll solve the issue.
So, I tried my best to understand the issue. As far as I understood based on other answers, the issue arises from the fact that I somehow ended up having 2 instances of one library inside my project (?), and so Gradle cannot understand which one to pick. But then I have cannot understand how? (I did not add any other "external dependencies")
As for the solution, the most common answer was adding the 'META-INF/kotlinx-io.kotlin_module' to the excludePath packaging options, but I don't understand why is it supposed to be correct. For me it sounds like I'm telling the build system "please exclude these paths from my project / don't scan them for libraries". But I'm not sure if it's a correct approach, because in this case I effectively exclude several libraries / dependencies from my project which might lead to the runtime exceptions NoClassDefFoundError or something similar in future.
The second most common answer was adding the pickFirst 'META-INF/kotlinx-io.kotlin_module' to the packaging options, which looks a bit better as it tells the build system "when you have multiple entries of some library, please take the first one you've found", i.e. the library will be included into my project and so I'm on the safe side, but still I have a concern about this solution as a person coming from C/C++/Rust/System_Programming world: in terms of C (simplified) let's imagine that I ended up having 2 libraries of 2 different versions (1.1, 1.2) and I have a header file which expects that I'm linked against v.1.2 of the library, if I picked up a wrong version library (1.1), but use the header from the newer one and expect that it works, well... it obviously won't work and I assume that the same issue might happen on Android (but I'm not sure about that as I'm not an expert), i.e. the pickFirst seems to be a good solution as long as we can guarantee that "multiple entries" of the library we're using, have the same version.
So I tried to use a pickFirst approach for now and ended up having an additional section in my gradle build file:
packagingOptions {
pickFirst 'META-INF/kotlinx-io.kotlin_module'
pickFirst 'META-INF/atomicfu.kotlin_module'
pickFirst 'META-INF/kotlinx-coroutines-io.kotlin_module'
}
which did the job, but I'm still not sure if it's the best solution. I think the proper approach would be to understand why the error occurs and combat the root cause of it instead of trying to workaround it with additional packaging options.
Android does not require any of these files in the META-INF directory of the APK package.
and these duplicate files in the META-INF directory originate from referenced libraries -
there is nothing else to do about, except to use packagingOptions.
also see: What is the purpose of META-INF? (Android APK != Java JAR).
these are indeed similar package formats, but still not exactly the same.

Android Studio - Gradle build compiling unversioned class files

I've recently ran into this problem, and would like to know, if possible, whether there's a solution for it.
Basically in the project I'm currently working, there used to be some legacy class files that were deleted in a past commit, but sometimes I need to look them up for quick reference, so I just reverted them back to my local changelist and set them as unversioned.
Now, the problem is that due to the legacy nature of these files, some of them don't compile anymore, but the gradle build attempts to compile them although they're unversioned.
So, my question here is: Is there a way to make gradle ignore unversioned files, just stop contemplating them for the build?
No, there is no such way. Gradle cannot exclude files from build based on their version control status. If you only need to use those classes for reference, move them to a directory outside of your project root directory.

Android Studio Compilation Error from Trying to Create Dependencies

I've been trying to fix this problem for an entire day, and it's probably just something ridiculous. I'm running Android Studio 0.2.5. I needed a library to work on my application (GrepCode internal stuff), so I went and downloaded the jar file and the jar files it depends on. I followed instructions from other SO answers on how to include these dependencies into my project and now I'm getting an error.
1) I first added the jars to the 'libs' folder that I created in the Module
2) I right clicked and hit Add to Library..., named the Library, tried adding it at different levels and still get this error.
3) I went into the Modules section of the settings and made sure that library was selected under the Dependencies tab.
4) I run gradlew clean in the Project directory.
Now at this point, if I don't do step 5 here, I simply get an error saying the packages I'm trying to import don't exist, even though the IDE doesn't SHOW an error when typing out the import statements or the classes from the libraries. Because of this, I tried step 5. According to all the guides, what I did up to this point should have worked.
5) In my build.gradle, the dependencies did not show up, so I typed them out and now this is what my dependency section looks like. If I do not type these out, I just get an error that says the packages don't exist when I try to import them.
dependencies {
compile 'com.android.support:support-v4:13.0.0'
compile files('libs/openjdk-6-b14.jar')
compile files('libs/junit-3.8.1.jar')
compile files('libs/logkit-1.0.1.jar')
compile files('libs/servlet-api-2.3.jar')
compile files('libs/httpcore-4.0.1.jar')
compile files('libs/commons-codec-1.3.jar')
compile files('libs/commons-logging.jar')
compile files('libs/httpclient-4.0.1.jar')
compile files('libs/json-20080701.jar')
compile files('libs/opengl-api-gl1.1-android-2.1_r1.jar')
compile files('libs/xpp3-1.1.4c.jar')
compile files('libs/android-4.2.2_r1.jar')
}
After this I get an error in the message box saying "Gradle: Execution failed for task ':SendPicTest:dexDebug'."
And in the idea.log I find this error: "java.lang.OutOfMemoryError: GC overhead limit exceeded"
So, I believe Step 5 is unnecessary, but I'm not sure. I've tried many different ways of importing these libraries and NOTHING has worked...I'm completed lost...anybody have any ideas? Thanks!
EDIT
After looking at your dependencies list, it seems obvious that the problem is there. I suggest you to try to:
1) understand why you choose to include each of those libs.
2) understand the android architecture and build process. (maybe read this)
Here are a few remarks:
openjdk-6-b14.jar MUST be removed. You are developing an Android app and so it will run against the Android SDK. The Android SDK already define most of the classes of the openjdk (so you will have conflicts when dexing this jar). Additionally lot of classes in this jar are simply not dexable (like javax.swing.*) because they use unsupported features and don't make sence on Android.
android-4.2.2_r1.jar is a stub jar (look at the code: all methods throw an exception). This artifact is only usable the build your android code with a standard javac compiler (and so producing *.class file). After that, all your *.class will be dexed (i.e. transformed into *.dex files) by android compiler. At runtime, the real android-api implementation will be used (instead of this artifact).
servlet-api : it's very uncommon to need this in an android-app. It only define an API (without implementation). The implementation is usually provided by the application server (tomcat, jboss,...) in standard J2EE developement. Android-sdk don't provide an implementation for this API.
junit : usually a dependency with scope test.
httpcore (and probably also httpclient) : a common mistake on android. An old implementation of this library is included in the android-sdk. If you keep it, you will have a top-level exception while building your app (this exception means that you try to override a class from the android-sdk : this is not possible)
opengl-api-gl1.1-android-2.1_r1.jar : I don't know exactly what it contains, but I guess the same remark as what I wrote about android-4.2.2_r1.jar applies here.
END EDIT
So, I believe Step 5 is unnecessary
No step 5 is necessary ! The build.gradle is where dependencies are defined... so if AndroidStudio don't update this file for you : do it by hand.
After that, you may need to reimport the project from gradle files (find the reimport button on top of the gradle view on the right edge of the window)
Regarding the error in the log file:
You can increase AndroidStudio memory settings from this file:
<ANDROID_STUDIO_INSTALL_DIR>/bin/studio.exe.vmoptions
or
<ANDROID_STUDIO_INSTALL_DIR>/bin/studio64.exe.vmoptions
if you run 64 bits version.
I suggest you to try to change the settings to avoid the "java.lang.OutOfMemoryError: GC overhead limit exceeded"
This error means that GC is running very long (98% of the time) and less than 2% of the heap is released. So you can try to increase the heap (and restart AndroidStudio):
-Xmx1024m
Another option, is to disable this check by adding this line in the *.vmoptions file:
-XX:-UseGCOverheadLimit
(note that since it is not a standard JVM args: it may not be supported by your JVM) Anyway I don't recommend this option, since the GC will run for a while with very poor results and your IDE will be very very unresponsive.
I also suggest you to read this regarding usage of AndroidStudio today.

Categories

Resources