Unity-Technologies / GooglePlayLicenseVerification

Unity Android plugin example on how to interface the Google Play License Verification (LVL) servers
MIT License
84 stars 26 forks source link

Not working on device when built with Unity 2019.1 #9

Open sph0001 opened 5 years ago

sph0001 commented 5 years ago

Hi. Scratching my head here because the code works fine on device when built with 2018.4 but fails to run on device with the following error when built with 2019.1.

05-10 18:35:20.731 26973 26993 E Unity : java.lang.ClassNotFoundException: Didn't find class "com.unity3d.plugin.lvl.ServiceBinder" on path: DexPathList[[zip file "/data/user/0/com.mycompany.mygame/cache/com.mycompany.mygame/classes.jar"],nativeLibraryDirectories=[/system/lib64]] 05-10 18:35:20.731 26973 26993 E Unity : at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134) 05-10 18:35:20.731 26973 26993 E Unity : at com.unity3d.player.UnityPlayer.nativeRender(Native Method) 05-10 18:35:20.731 26973 26993 E Unity : at com.unity3d.player.UnityPlayer.c(Unknown Source:0) 05-10 18:35:20.731 26973 26993 E Unity : at com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:88) 05-10 18:35:20.731 26973 26993 E Unity : at android.os.Handler.dispatchMessage(Handler.java:102) 05-10 18:35:20.731 26973 26993 E Unity : at android.os.Looper.loop(Looper.java:193) 05-10 18:35:20.731 26973 26993 E Unity : at com.unity3d.player.UnityPlayer$e.run(Unknown Source:20) 05-10 18:35:20.731 26973 26993 E Unity : Suppressed: java.io.IOException: No original dex files found

Any ideas?

michaelclockstone commented 5 years ago

I can confirm the issue. Unity seems to have removed the com.unity3d.plugin.lvl.ServiceBinder plugin. Maybe we need to add that ourselves? The source code is in the repository. I'll investigate further.

michaelclockstone commented 5 years ago

I figered out that the compiled plugin is in the classes_jar.txt file and should be loaded at runtime. It seems that since Unity 2019 this does not work anymore. See the LoadServiceBinder() function in CheckLVLButton.cs. Not sure why it's not working anymore

MigrantP commented 5 years ago

I'm running into this too. Anyone have a solution yet?

MigrantP commented 5 years ago

I added some logging into LoadServiceBinder() and it's failing when trying to use findClass() on Unity's AndroidJavaObject. The JAR being written properly as far as I can tell, but I'm not 100% sure about that.

MigrantP commented 5 years ago

I've reported a bug to Unity, case 1170590.

MigrantP commented 5 years ago

Unity QA responded and said they could not reproduce it on 2019.1.10f1. I upgraded to that (and also replaced the classes_jar.txt with the latest on this repo to make sure), and still have the problem.

I'm seeing it on both Android 6.0.1 and Android 5.1.1 devices.

sph0001 commented 5 years ago

Did you submit the bug with a project that you've confirmed breaks in the way it's breaking right now? If you just gave QA information about how it's breaking without a sample that they can just open and see break then they may not have replicated the issue exactly. If they can't "reproduce" the issue then they will not submit it to an actual engineer to take a look so the bug will not even get looked at for real...

MigrantP commented 5 years ago

No, I did not attach our multi-gigabyte project =) sometimes they can reproduce and dig into a problem without that. If needed I'll make a sample project to reproduce the issue and send to them.

MigrantP commented 5 years ago

@sph0001 Did you get anywhere with the problem, by the way?

sph0001 commented 5 years ago

I did submit a sample project but I was under the impression that the class_jar.txt wasn't being written at all due to what seems to be an unrelated bug in 2018 they fixed in 2019 so ended up sending them something that is not broken without realizing it. I eventually got feedback saying that an engineer at Unity took a look at it and said it was not a bug which it wasn't because as you pointed out the class_jar file is being written. Anyway, at least an actual engineer at Unity took a look at it after two weeks so that's why I asked if you sent in a sample project. I hope you fare better than I did. :)

MigrantP commented 5 years ago

I used adb to see that the jar file is being written, but I wasn't able to download it to make sure the contents are exactly correct.

das-etwas commented 5 years ago

Anything new on this? Cant find the Ticket "1170590" in issue-tracker btw. I've already tried to rebuild the .jar lib in Android Studio. Afterwards I've .dex-ed it with android tools - same result - same error.

As a workaround I put the .jar itself to the project and load the "com.unity3d.plugin.lvl.ServiceBinder" with classLoader instead of dexClassLoader. This works like intended but is not as safe as the other approach where the dexed source lies within the build.

After digging a little bit deeper into our previous build-logs I've also found out that we were using NDK r13b prior to our Unity 2019 builds. But since Unity 2019 we are forced into using the built-in NDK (which was btw upgraded to r19b two weeks ago and then reverted to r16b internally by unity because noone could make IL2CPP builds for Android anymore). Unity 2019 offers to choose a NDK by yourself - but does only allow r16b and newer. -> NOT SURE if it has something to do with the error. -> Saw the exact same error with another Plugin in one of our recent logs.

MigrantP commented 5 years ago

Nothing new yet, I haven't sent a sample project or anything as other priorities have come up.

Great idea on using the jar itself, but indeed it's not the best solution.

I'm not sure about the NDK thing - when I built the game with Unity 2019 it wanted me to locate NDK r16b so I installed that. I wasn't aware it had its own version?

MigrantP commented 5 years ago

Unity got back to me and I sent them steps to reproduce. The issue isn't in their public tracker, though. The problem actually reproduces really easily with the exact project in this repository:

Download the project from https://github.com/Unity-Technologies/GooglePlayLicenseVerification and open in Unity 2019.1.10f1. Add the RSA key info needed in CheckLVLButton.cs. Set the Android package name. Set Install Location to Automatic. Build and run to a device. adb logcat will show the exception.

You can also wrap the code in LoadServiceBinder() with a try/catch and look at the exception in more detail.

One thing this shows is that the problem occurs both with Mono and IL2CPP runtimes.

MigrantP commented 5 years ago

This problem is still occurring with Unity 2019.2.2f1.

MigrantP commented 5 years ago

@das-etwas Can you provide more details and a code sample for the workaround you used? ClassLoader is an abstract class, not sure how you used it directly.

MigrantP commented 4 years ago

Unity got back to me asking how to reproduce it, after I had already sent them a sample project.. so I improved it to use Unity UI instead of OnGui() and sent it again. Hopefully that gets things moving!

MigrantP commented 4 years ago

Also I haven't had any success working around it. If I include classes.jar by itself as a plugin then I get an exception on launch and the activity won't run. Fun times..

java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.handelabra.LVLExample/com.unity3d.player.UnityPlayerActivity}: java.lang.ClassNotFoundException: Didn't find class "com.unity3d.player.UnityPlayerActivity" on path: DexPathList[[zip file "/data/app/com.handelabra.LVLExample-1/base.apk"],nativeLibraryDirectories=[/data/app/com.handelabra.LVLExample-1/lib/arm, /vendor/lib, /system/lib]]

MigrantP commented 4 years ago

Got a new response from Unity: "We successfully reproduced this issue and have sent it for resolution with our developers."

Progress!

KyryloKuzyk commented 4 years ago

The issue is still not fixed in Unity 2019.2.9f1

albert-pixel commented 4 years ago

This issues is still not fixed, so the problem occurs on all version of 2019.1 & 2019.2. Anyone has a solution? @das-etwas can you explain how you fixed it? Can you share the code?

Thanks!

Spierek commented 4 years ago

I've also encountered the exact same issue in 2019.2.17f1.

ddalacu commented 4 years ago

We want to migrate to unity 2019.2 but this bug is stopping us from doing it, any news form the unity team?

Aakashh94DP commented 4 years ago

I was able to solve this for myself in Unity 2019.1. Although I have a modified plugin (a few things added in the C# classes/cleanup), I think the solution should work for you guys or at least guide you in some direction. Basically the ServiceBinder is removed in Unity 2019. I attached the Java file for the ServiceBinder, just add it to your project and enable it for Android.

The code changes should be very minimal. Based on the CheckLVLButton.cs class, I added the following line at the end of Start()

m_LVLCheckType = new AndroidJavaObject("com.unity3d.plugin.lvl.ServiceBinder", m_Activity);

and in the LoadServiceBinder(), you can remove the following lines of code

AndroidJavaObject dcl = new AndroidJavaObject("dalvik.system.DexClassLoader", cachePath + "/classes.jar", cachePath + "/odex", null, m_Activity.Call<AndroidJavaObject>("getClassLoader"));

m_LVLCheckType = dcl.Call<AndroidJavaObject>("findClass", com.unity3d.plugin.lvl.ServiceBinder");

I took/ rewrote a lot of the Code from CheckLVLButton for my own version GooglePlayLicenseVerification so my solution above has not been tested in this repository but I hope this can help you guys.

ServiceBinder.java.zip

Spierek commented 4 years ago

@Aakashh94DP - thanks for chipping in - using your feedback I've been able to get a little bit further.

I was able to get rid of the initial error:

AndroidJavaException: java.lang.ClassNotFoundException: Didn't find class "com.unity3d.plugin.lvl.ServiceBinder" on path: DexPathList...

by replacing the following line: m_LVLCheckType = dcl.Call<AndroidJavaObject>("findClass", "com.unity3d.plugin.lvl.ServiceBinder"); for the new constructor: m_LVLCheckType = new AndroidJavaObject("com.unity3d.plugin.lvl.ServiceBinder", m_Activity);

However, after this you get the following error:

AndroidJavaException: java.lang.NoSuchMethodError: no non-static method with name='getConstructors' signature='()[Ljava/lang/Object;' in class Ljava.lang.Object;...

from this code in OnGUI(): AndroidJavaObject[] ctors = m_LVLCheckType.Call<AndroidJavaObject[]>("getConstructors"); m_LVLCheck = ctors[0].Call<AndroidJavaObject>("newInstance", param); m_LVLCheck.Call("create", m_Nonce, new AndroidJavaRunnable(Process));

After replacing it with: m_LVLCheck = new AndroidJavaObject("com.unity3d.plugin.lvl.ServiceBinder", m_Activity); m_LVLCheck.Call("create", m_Nonce, new AndroidJavaRunnable(Process)); the exceptions were gone, and the GUI initialized properly.

Unfortunately, the information received on device after pressing the button is invalid - although the m_LVLCheck object is not null, the resulting message is

Response code = 0 Package name = < Failed >

which suggests that the service call must be failing on the Java side?

Aakashh94DP commented 4 years ago

@Spierek Good to hear that you progressed with it, as for the response you are getting, I have no idea unfortunately. Maybe you'll have to jump into the Java side to see how it tries to get the package name and what could be wrong/missing from your side.

KyryloKuzyk commented 4 years ago

@Spierek Your solution worked for me in Unity 2019.2.17!!! Thank you so much!

Please check that license validation actually works for you in the older versions of Unity (2018.4 for example), maybe it's not the issue with new Unity version but with license validation itself. There are a some prerequisites for license check to work properly, here are some of them I can remember:

  1. You should have your project uploaded at least once to Alpha or Beta track.
  2. Add your account to testers list on Google Play Dev Console => Settings => Developer Account => Account Details => License Testing
  3. Make sure Package Name is correct
  4. Sign your app with correct keystore while making a build.
  5. Add CHECK_LICENSE permission to AndroidManifest.
Spierek commented 4 years ago

@tobeglad - thank you so much for your feedback, I also got it working now :)

Indeed, I was missing the CHECK_LICENSE permission in the AndroidManifest - despite the plugin adding a separate Assets\Plugins\Android\GooglePlayLicenseVerification\AndroidManifest.xml file, the required permission was not added to the final manifest.

I solved it by grabbing the AndroidManifest.xml generated after building Android from [project_directory]\Temp\StagingArea, copying the file to Assets\Plugins\Android, and adding a new line: <uses-permission android:name="com.android.vending.CHECK_LICENSE" />.

However, the example was still failing until I uploaded the build with the updated manifest to the Google Play Console (using an Internal release track). Immediately after doing that and propagating the new version, the build I had on my test phone started working as intended.

albert-pixel commented 4 years ago

@Spierek Your solution works! Unity 2019.2.17!!! Thank you so much!

sph0001 commented 4 years ago

@Spierek Hi. Do you know if your fix works in 2019.4? What about 2020? Also, would it be possible to upload the fix in its entirety? Thanks.

Spierek commented 4 years ago

@sph0001 We've only tried it in 2019.3. The solution we used in our title is very similar to this one - https://github.com/grapefrukt/GooglePlayLicenseVerification so it should serve as a starting point. However, we're not sure if the LVL API hasn't changed since then.

KyryloKuzyk commented 4 years ago

@sph0001 I can confirm that it works in Unity 2019.4.1LTS.

rthery commented 3 years ago

I've forked the repo (here) so that it works on recent Unity versions such as 2019.4. I've also switched to uGUI to display the results, since it was impossible to read them on my device.

Also if it's not working despite doing everything said in this issue, make sure that it's not proguard that's stripping ServiceBinder.java, by adding the following to your proguard-user.txt file: -keep class com.unity3d.plugin.lvl.ServiceBinder { *; }

@erique If you want me to setup a PR, let me know

erique commented 3 years ago

@rthery I think we would appreciate a PR!

(Full disclosure - I'm no longer involved in the Unity Android development, and as such not actively maintaining this repo either. I've pinged the internal development team about this thread tho.)

rthery commented 3 years ago

Thanks for for your reply @erique

I've setup a PR (#13) with what I did on my branch then :)