How can I remove a library from the aar using gradle? - unity3d

I'm currently building an android plugin for Unity. Because of that I need to include unity's classes.jar, which provides me with some methods in the com.unity3d.player package.
However when i do ./gradlew assemble it also packages the classes.jar into the .aar file under libs/classes.jar.
Now when I add this .aar to Unity and try to build, I get the following error:
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/a$1;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/a$2;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/a$a;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/a;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/b$1;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/b$2;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/b;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/c;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/unity3d/player/d$1;
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.RuntimeException: Translation has been interrupted
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:608)
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:311)
at com.android.dx.command.dexer.Main.run(Main.java:277)
at com.android.dx.command.dexer.Main.main(Main.java:245)
at com.android.dx.command.Main.main(Main.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at SDKMain.main(SDKMain.java:129)
Unity tries to add the classes.jar to it's android build again, but because the classes.jar is already in the .aar, this fails.
How can I exclude the classes.jar from the .aar?
EDIT
This is what I can do with the command line to remove the classes.jar
zip --delete tapfortapunity-release.aar "libs/*"
How do I call this with gradle?

UPDATE: I just found out that this problem solves itself if I just remove the unity.jar dependency from my build.gradle file:
//dependencies {
// compile files('src/main/libs/unity.jar')
//}
(the code compiles just fine, strangely, and no unity.jar in the .aar file...).
(just noticed that the code compiled because there was no reference to UnityPlayer* stuff...)
Same issue here. I browsed a bit and it seems like there is no clean way to solve the problem (yet!), so I guess it all boils down to this:
create a chain of tasks for the installation of your unity plugin (a task to create the Plugin/Android directory for instance, one to Copy the AAR file and native libraries, if any, etc)
remove the file from the zip using a task the previous one will dependsOn
Step 2 can be carried out in one of those following ways:
create an Exec task that will just execute the command you pointed out (this is probably what I'll end up doing, as I'm not really proficient with gradle...). Easy but not portable (relies on an extra utility).
create a JavaExectask and use Java7 support for zips to remove the entry (probably the best solution, but I don't really have much experience here).
try creating a new jar using the suggestion pointed out in this post: Post on gradle-user describing how to create a jar (or aar...) using gradle as Gradle supports zip files, but cannot change them in place (which implies it cannot remove stuff from them). Harder, but will not rely on external tools, so you'll get portability as a result.
It might not be an elegant solution and probably better ones exist, but it's a very simple, and works well
Hope this helps

Related

Groovy:General error during semantic analysis: java.lang.NoSuchMethodError:

Imported the gradle project from the "complete" folder and received the following error:
Groovy:General error during semantic analysis:
java.lang.NoSuchMethodError: 'org.codehaus.groovy.ast.expr.Expression org.codehaus.groovy.ast.tools.GeneralUtils.propX(org.codehaus.groovy.ast.expr.Expression, java.lang.String)'
I am using the latest version of Eclipse, 2020-12, with groovy tools installed.
From grails guide
https://guides.grails.org/gorm-without-grails/guide/index.html
Downloaded code sample from github
https://github.com/grails-guides/gorm-without-grails.git
It seems likely to be a version mismatch, but I cannot determine how to correct this problem.
I have tried to delete the offending file, src/main/groovy/demo/domain/Manufacturer.groovy, and the error appears on the file in this package on line 1.
The error does not appear in any other package. I have done the usual internet searches for resolutions that apply, but have thus far been unable to find a suitable solution. I am hopeful for a suggestion?
I think this error comes from an AST transform that references the older signature of GeneralUtils#propX. This method used to return Expression and was changed to return PropertyExpression.
The bridge method for binary compatibility was missing in groovy-eclipse. https://github.com/groovy/groovy-eclipse/commit/f6f448675d95f858b4ec65b6fc8e55f27ccaaa94

Google OR tools

I am learning to solve some optimisation programs using google or-tools.
I started with their example code and I an trying to run it in intellij.
But when I write the code and compile I get the following error.
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.google.ortools.linearsolver.operations_research_linear_solverJNI.MPSolver_CLP_LINEAR_PROGRAMMING_get()I
at com.google.ortools.linearsolver.operations_research_linear_solverJNI.MPSolver_CLP_LINEAR_PROGRAMMING_get(Native Method)
at com.google.ortools.linearsolver.MPSolver$OptimizationProblemType.<clinit>(MPSolver.java:221)
I searched for some answers and I found that it requires jniortools.dll .
But I am working with ubuntu. Hence i assume i need to load the libjniortools.so file , am I right?.
So I included the line
static {
System.loadLibrary("libjniortools");
}
and I have a lib folder wherein I have put both com.google.ortools.jar and protobuf.jar along with all the other lib files that were present when I extracted the zip file(basically copy pasted the lib folder from extracted zip file).
I have added the jar paths in intellij as shown in figure
enter image description here
*the last 2 line of dependency in image
Then I have also tried giving the lib path in VM-options:
-Djava.library.path=/home/surajvashistha/IdeaProjects/LPModel/lib
After all this, I get the following error
Exception in thread "main" java.lang.UnsatisfiedLinkError: no libjniortools in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1860)
at java.lang.Runtime.loadLibrary0(Runtime.java:871)
at java.lang.System.loadLibrary(System.java:1124)
at LP.<clinit>
I am stuck here and not able to move forward. Can anyone help?

How to remedy error caused by guava: Program type already present: com.google.common.util.concurrent.internal.InternalFutures

An AAR library already uses com.google.guava.
If an app includes the following in its build.gradle:
api 'com.google.guava:guava:27.0-android'
Building the app generates the following error:
Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'.
> com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: ...
Learn how to resolve the issue at https://developer.android.com/studio/build/dependencies#duplicate_classes.
Program type already present: com.google.common.util.concurrent.internal.InternalFutures
If I do not include "api 'com.google.guava:guava:27.0-android'", the app can be built, but it has runtime error of java.lang.NoClassDefFoundError when it reaches the point of using the Guava method: Iterables.find
I had to update to version 27.0.1, at the time of writing they still haven't updated the README with this new version.
implementation 'com.google.guava:guava:27.0.1-android'
Since Guava 27.0, ListenableFuture is located in separate artifact, see the announcement. You can try two things (one at a time):
Exclude "listenablefuture" module (group "com.google.guava") and build your project again.
I don't know the AAR specifics, but it could be that 27.0-android doesn't work with AAR, so you should try 26.0-android instead.

Unity Error: Unable to convert classes into dex format

I have created an Android Unity plugin (.aar file) which provides some custom positioning data to my Unity game. In my Unity script, I use,
var x = customClass.CallStatic<float>("getHeadX");
In order to get some location data. This method is called per frame to get the updated data (polling method) which makes it inefficient. Instead, I decided to call a C# method in my Unity script from my java code (plugin side) when the updated data is ready. To do this, in my java plugin, I wrote,
import com.unity3d.player.UnityPlayer;
...
UnityPlayer.UnitySendMessage("Manager", // gameObject name
"PluginCallback", // this is a callback in C#
"Hello from android plugin"); // msg which is not needed actually
However, the compiler complained that the package com.unity3d.player.UnityPlayer does not exist. So I copied classes.jar file from
C:\Program Files
(x86)\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes
\classes.jar
into the 'libs' folder of my android plugin's project. I built it successfully and copied the generated .aar file (mylibrary-release.aar) into Assets\Plugins\Android folder of my Unity project.
When I build the Unity project (Using 'Internal' build system), it gives me this error:
IOException: Failed to Move File / Directory from
'Temp/StagingArea\android-libraries\mylibrary-release\classes.jar' to
'Temp/StagingArea\android-libraries\mylibrary-release\libs\classes.jar'.
UnityEditor.Android.PostProcessor.Tasks.ProcessAAR.Execute
...
This error happens because the classes.jar dependency has name conflict with classes.jar (made by unity out of my plugin). So I changed the dependency name to unity_classes.jar and this resolved the issue but now I'm getting a new error when building my unity application:
CommandInvokationFailure: Unable to convert classes into dex format.
C:/Program Files/Java/jdk1.8.0_102\bin\java.exe -Xmx2048M
Dcom.android.sdkmanager.toolsdir="C:/Users/kamran.shamloo/AppData/Local/Android/Sdk\tools"
-Dfile.encoding=UTF8 -jar "C:\Program Files (x86)\Unity\Editor\Data\PlaybackEngines\AndroidPlayer/Tools\sdktools.jar"
stderr[ Uncaught translation error:
java.lang.IllegalArgumentException: already added:
Lbitter/jnibridge/JNIBridge; Uncaught translation error:
java.lang.IllegalArgumentException: already added:
Lbitter/jnibridge/JNIBridge$a; Uncaught translation error:
java.lang.IllegalArgumentException: already added:
Lcom/unity3d/player/NativeLoader; Uncaught translation error:
java.lang.IllegalArgumentException: already added:
Lcom/unity3d/player/ReflectionHelper; Uncaught translation error:
java.lang.IllegalArgumentException: already added:
Lcom/unity3d/player/ReflectionHelper$1; Uncaught translation error:
java.lang.IllegalArgumentException: already added:
Lcom/unity3d/player/ReflectionHelper$a; Uncaught translation error:
java.lang.IllegalArgumentException: already added:
Lcom/unity3d/player/UnityPlayer; Uncaught translation error:
java.lang.IllegalArgumentException: already added:
Lcom/unity3d/player/UnityPlayer$1; Uncaught translation error:
java.lang.IllegalArgumentException: already added:
Lcom/unity3d/player/UnityPlayer$10;
...
The classes.jar (which you later renamed it to 'unity_classes.jar') gets automatically included into the built .apk by Unity, so you shouldn't include it yourself again (in your Android plugin), even under a different name.
In other words, first your android plugin "embeds" this .jar file inside itself. Then, when Unity adds your plugin into the game project, it also adds its own copy of that .jar file (it does that for all android projects). Consequently, Unity essentially ends up having 2 copies of the same .jar file in the project and complains by saying 'unable to convert classes into dex format'.
So although you have to use this library (.jar file) in your project but you should not bundle this library with your project. How to do that? If you're using Android studio, you can achieve this by marking the .jar file as a dependency with the provided scope.
To do this, you can:
1) Go to 'build.gradle' of your module and change this:
compile files('libs/jars/unity_classes.jar')
to this:
provided files('libs/jars/unity_classes.jar')
Or
2) you can right-click on the module (in Android pane) and choose Open Module Settings. Then go to Dependencies tab. Find the Unity module (which I renamed it to unity_classes.jar) and change its scope to Provided.

Google.JarResolver.ResolutionException: Cannot resolve com.google.firebase:firebase-analytics-unity:1.0.0()

In my Unity project, I used some assets like FacebookSDK, OneSignal etc. Whenever I import OneSignal, this error will be shown.
Google.JarResolver.ResolutionException: Cannot resolve com.google.firebase:firebase-analytics-unity:1.0.0()
I had tried many things, these are what I remember:
Using 'Play Service Resolver' does not solve the problem.
Importing Unity Firebase.
When I import Firebase, the error turn into another error, which is building error called CommandInvokationFailure, related to Firebase.
I spent several days to fix it, but still I couldn't. If you need further information, tell me please.
EDIT: #nika Thanks for reply. I tried every combination of API 23-24-25 and build tools from 23 to 25. But, I can't fix 'CommandInvokationFailure' yet. I think sharing the full log of the error will be better:
CommandInvokationFailure: Unable to convert classes into dex format.
/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/bin/java -Xmx2048M -Dcom.android.sdkmanager.toolsdir="/Users/emre/Desktop/AndroidSDK/tools" -Dfile.encoding=UTF8 -jar "/Applications/Unity/PlaybackEngines/AndroidPlayer/Tools/sdktools.jar" -
stderr[
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/android/gms/internal/zzah;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/android/gms/internal/zzcn;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Landroid/support/v4/BuildConfig;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat$AccessibilityServiceInfoIcsImpl;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat$AccessibilityServiceInfoJellyBeanMr2;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat$AccessibilityServiceInfoStubImpl;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat$AccessibilityServiceInfoVersionImpl;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Landroid/support/v4/animation/AnimatorCompatHelper;
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.RuntimeException: Translation has been interrupted
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:608)
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:311)
at com.android.dx.command.dexer.Main.run(Main.java:277)
at com.android.dx.command.dexer.Main.main(Main.java:245)
at com.android.dx.command.Main.main(Main.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at SDKMain.main(SDKMain.java:129)
Caused by: java.lang.InterruptedException: Too many errors
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:600)
... 9 more
]
EDIT 2: #jkasten Thanks for reply. I can fix Android Support Library v4 Errors, however, for the second one is not easy because of resolvers.
There is no duplicated play-services files. This time, I improvised to solve it: removing play-services-ads-9.0.1 from android build by changing import settings(if other ads file is removed, the CommandInvokationFailure error continues.). I don't really know it is the right way to solve the problem, but it worked somehow. But it leads me another error when I tried to run game on my phone:
FATAL EXCEPTION: main
E/AndroidRuntime(18680): java.lang.NoSuchMethodError: No static method zzb(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; in class Lcom/google/android/gms/common/internal/zzaa; or its super classes (declaration of 'com.google.android.gms.common.internal.zzaa' appears in /data/app/***/base.apk)
E/AndroidRuntime(18680): at com.google.firebase.provider.FirebaseInitProvider.zza(Unknown Source)
E/AndroidRuntime(18680): at com.google.firebase.provider.FirebaseInitProvider.attachInfo(Unknown Source)
E/AndroidRuntime(18680): at android.app.ActivityThread.installProvider(ActivityThread.java:5159)
E/AndroidRuntime(18680): at android.app.ActivityThread.installContentProviders(ActivityThread.java:4754)
E/AndroidRuntime(18680): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4694)
E/AndroidRuntime(18680): at android.app.ActivityThread.access$1600(ActivityThread.java:150)
E/AndroidRuntime(18680): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405)
E/AndroidRuntime(18680): at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime(18680): at android.os.Looper.loop(Looper.java:148)
E/AndroidRuntime(18680): at android.app.ActivityThread.main(ActivityThread.java:5423)
E/AndroidRuntime(18680): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(18680): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
E/AndroidRuntime(18680): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
From the following two unique lines in your log:
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/google/android/gms/internal/zzcn;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Landroid/support/v4/BuildConfig;
This means there are 2 or more copies of the Google Play services library and the Android Support Library v4 in your project.
Fixing the Android Support Library v4 Errors (support/v4)
In order to use the OneSignal and Facebook SDKs together in the same Unity project you will need to delete the following duplicated libraries noted in the OneSignal troubleshooting guide.
FacebookSDK/plugins/android/libs/support-v4-23.4.0.aar
FacebookSDK/plugins/android/libs/support-annotations-23.4.0.aar
This will fix the already added: Landroid/support/v4 errors unless their is a 3rd plugin with this library as well in your project.
Fixing the Google Play services library Errors (gms)
I recommend deleting duplicate play-services-[library]-[version].aar files in your Unity project. There will be different [libraries] however there should only be a single version for all play-services-*.aar files. This should fix the already added: Lcom/google/android/gms errors.
If you get stuck update your question with a full list of plugins with version numbers. Also list all .aar and .jar files in your project. Additional you can create a new project and add one plugin at a time until you get the error to pin point the plugin combination creating the issue.
This question mentions a few different errors. All are eventually related to issues with native Android libraries (.jar or .aar) within the Unity project.
I'll try to address all of the issues you mentioned:
Cannot resolve (library name)
Google.JarResolver.ResolutionException: Cannot resolve
com.google.firebase:firebase-analytics-unity:1.0.0()
A lot of Android plugins use the Play Services Resolver - this is helper code that attempts to simplify things by automatically resolving the needed Google play services libraries (located under the Android SDK folder).
It works by setting the needed dependencies to a static instance of a class, which then attempts to resolve the needed libraries.
Sometimes, the operation of the resolver can fail, since it may become "out of sync" with its persisted data.
In this case, what probably happened is that the static object was still attempting to resolve the "firebase-analytics-unity" library, but this folder was removed from the project, so it failed to look it up.
Already Added Lxxx/xxx/xxx
Uncaught translation error:
java.lang.IllegalArgumentException: already added:
Lcom/google/android/gms/internal/zzah; Uncaught translation error:
java.lang.IllegalArgumentException: already added:
Lcom/google/android/gms/internal/zzcn; Uncaught translation error:
java.lang.IllegalArgumentException: already added:
Landroid/support/v4/BuildConfig; Uncaught translation error:
java.lang.IllegalArgumentException: already added:
Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat;
Uncaught translation error: java.lang.IllegalArgumentException:
already added:
Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat$AccessibilityServiceInfoIcsImpl;
Uncaught translation error: java.lang.IllegalArgumentException:
already added:
Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat$AccessibilityServiceInfoJellyBeanMr2;
Uncaught translation error: java.lang.IllegalArgumentException:
already added:
Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat$AccessibilityServiceInfoStubImpl;
Uncaught translation error: java.lang.IllegalArgumentException:
already added:
Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat$AccessibilityServiceInfoVersionImpl;
Uncaught translation error: java.lang.IllegalArgumentException:
already added: Landroid/support/v4/animation/AnimatorCompatHelper;
As was already answered by #jkasten, your project contains multiple plugins that contain the same compiled Java classes. The hint as to which library is duplicated can be found by the class names (not always helpful though). In this case, you can see that it's related to com.google.android.gms (google play services) and Android support library (android.support.v4.xxx).
No static method zzb
FATAL EXCEPTION: main E/AndroidRuntime(18680):
java.lang.NoSuchMethodError: No static method
zzb(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; in class
Lcom/google/android/gms/common/internal/zzaa; or its super classes
(declaration of 'com.google.android.gms.common.internal.zzaa' appears
in /data/app/***/base.apk) E/AndroidRuntime(18680): at
com.google.firebase.provider.FirebaseInitProvider.zza(Unknown Source)
E/AndroidRuntime(18680): at
com.google.firebase.provider.FirebaseInitProvider.attachInfo(Unknown
Source) E/AndroidRuntime(18680): at
android.app.ActivityThread.installProvider(ActivityThread.java:5159)
E/AndroidRuntime(18680): at
android.app.ActivityThread.installContentProviders(ActivityThread.java:4754)
E/AndroidRuntime(18680): at
android.app.ActivityThread.handleBindApplication(ActivityThread.java:4694)
E/AndroidRuntime(18680): at
android.app.ActivityThread.access$1600(ActivityThread.java:150)
E/AndroidRuntime(18680): at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405)
E/AndroidRuntime(18680): at
android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime(18680): at android.os.Looper.loop(Looper.java:148)
E/AndroidRuntime(18680): at
android.app.ActivityThread.main(ActivityThread.java:5423)
E/AndroidRuntime(18680): at java.lang.reflect.Method.invoke(Native
Method) E/AndroidRuntime(18680): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
This is a more subtle and tricky one. The game was built into an .apk, but crashes at runtime due to a class that is not found.
Judging by the method name (zzb) - this is an internal "obfuscated" method inside Google play services. This can happen if you mix multiple versions of google play services together (for example - Firebase at version 9.8.0 with Google play services at a different version).
It's vital to keep all these versions consistent with one another, a task that could sometimes get a bit tricky with the Resolver that does this automatically.
Final Note:
I offer a professional service to assist fixing such issues. Please feel free to contact me in case you run into a similar issue in the future.