简体   繁体   English

启用proguard时androidTest中没有静态方法deleteRecursively(Ljava/io/File;)

[英]No static method deleteRecursively(Ljava/io/File;) in androidTest when enabling proguard

I am trying to enable proguard on my android tests.我正在尝试在我的 android 测试中启用 proguard。 But I am facing a strange problem:但我面临一个奇怪的问题:

java.lang.NoSuchMethodError: No static method deleteRecursively(Ljava/io/File;)Z in class Lkotlin/io/FilesKt; or its super classes (declaration of 'kotlin.io.FilesKt' appears in /data/app/org.walleth.offline-BAciL8erjxU-sHGjQe6uQg==/base.apk!classes2.dex)
at org.ligi.trulesk.RulesKt.doBefore(Rules.kt:82)
at org.ligi.trulesk.RulesKt.access$doBefore(Rules.kt:1)
at org.ligi.trulesk.TruleskIntentRule.beforeActivityLaunched(Rules.kt:58)
at android.support.test.rule.ActivityTestRule.launchActivity(ActivityTestRule.java:351)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:525)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:384)
at org.ligi.trulesk.AppReplacingRunnerBase.onStart(AppReplacingRunnerBase.kt:19)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2145)

Proguard on the release build works - not sure why it is so aggressive on android tests.发布版本的Proguard有效 - 不知道为什么它在 android 测试中如此激进。 Ideally the instrumentation classes would not be removed at all.理想情况下,仪器类根本不会被删除。

I think core issue is that androidTest is a different compilation unit.我认为核心问题是androidTest是一个不同的编译单元。 app/src/androidTest is assembled into app-debug-androidTest.apk while app/src/main is assembled into app-debug.apk . app/src/androidTest被组装到app-debug-androidTest.apkapp/src/main被组装到app-debug.apk And so Proguard during assembleDebug neither see no includes app/src/androidTest into building "tree shaking" usage graph because it is not available on the classpath.因此,在assembleDebug期间 Proguard 都看不到将app/src/androidTest到构建“摇树”使用图中,因为它在类路径上不可用。 Practically, it means that application code which is referenced in tests only is being stipped out.实际上,这意味着仅在测试中引用的应用程序代码将被剔除。

This topic correlates with "Should I change visibility from private to public just for the test access?"此主题与“我是否应该仅针对测试访问将可见性从私有更改为公开?” dilema.困境。 Depending on what kind of tests you are writing you may consider to:根据您正在编写的测试类型,您可能会考虑:

  • Always keep application extra entry points (used by tests) in shippable to users release.apk始终将应用程序额外的入口点(由测试使用)保存在可交付给用户的release.apk
  • Compile main apk differently when running the test and again accept the risk of shipping to users not exactly the same code which is being run by test运行测试时以不同的方式编译主 apk 并再次接受向用户发送与测试运行的代码不完全相同的风险

Unfortunately, I don't know any auto-magic solution at the moment (similar to all-open plugin).不幸的是,我目前不知道任何自动魔术解决方案(类似于all-open插件)。 But it is possible to resolve missing methods issue in a case-by-case way.但是可以根据具体情况解决缺少方法的问题。

buildTypes {
    debug {
        minifyEnabled true

        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt', 'proguard-project-ext.txt'
        testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-test-project.txt'
    }
}      
  • proguard-project.txt - configuration for app/src/main and it's implementation dependencies proguard-project.txt - app/src/main配置及其implementation依赖
  • proguard-project-ext.txt - configuration for app/src/main which contains -keep instructions for every method/field used in tests only which was "falsely" removed by proguard. proguard-project-ext.txt - app/src/main配置,其中包含仅在测试中使用的每个方法/字段的-keep指令,这些方法/字段被 proguard “错误地”删除。 I prefer to keep it separately, to conditionally remove when publishing to google play我更喜欢单独保留,以便在发布到 google play 时有条件地删除
  • proguard-test-project.txt - configuration for app/src/androidTest and it's androidTestImplementation dependencies. proguard-test-project.txt - app/src/androidTest配置及其androidTestImplementation依赖项。 Typically contains -dontwarn net.bytebuddy.** and etc. Although note, that test apk doesn't support multidex so it is possible to hit 65k limit method by including too many dependencies.通常包含-dontwarn net.bytebuddy.**等。尽管请注意,该测试 apk 不支持 multidex,因此通过包含太多依赖项可能会达到65k限制方法。

Check android/platform/tools/base/studio-master-dev/./build-system/integration-test/test-projects/minify for the implementation reference.检查android/platform/tools/base/studio-master-dev/./build-system/integration-test/test-projects/minify以获取实现参考。

test builds are by default always debug builds - even when setting a testBuildType , this has to have config initWith debug , which hints for a whole other mis-configuration. test构建 默认 总是debug构建 - 即使在设置testBuildType ,这也必须有 config initWith debug ,它暗示整个其他错误配置。 sorry for not providing the expected answer, but this mis-configuration is based upon a certain mis-conception.抱歉没有提供预期的答案,但这种错误配置是基于某种误解。 I'd suggest to disable the obfuscation, because it's rather pointless in this case, because this package won't ever be distributed.我建议禁用混淆,因为在这种情况下它毫无意义,因为这个包永远不会被分发。 it might not even be possible to define ProGuard rules for the test application (which is a package on it's own).甚至可能无法为测试应用程序定义 ProGuard 规则(它本身就是一个包)。 this behavior is "by design", caused by working against the test framework... because the test application will not know about the class/method obfuscation mapping of the other one application package - and therefore the chances are rather slim, that this could ever work out.这种行为是“设计使然”,由针对测试框架的工作引起...因为测试应用程序将不知道另一个应用程序包的类/方法混淆映射 - 因此可能性很小,这可能永远工作。

Firebase Test Lab Robo UX Test is the most similar to what is effectivly being demanded. Firebase 测试实验室Robo UX 测试与实际需求最相似。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 StandardTokenizer重写最终方法setReader。(Ljava / io / Reader;)V - StandardTokenizer overrides final method setReader.(Ljava/io/Reader;)V 如何强制ProGuard删除公共静态方法? - How to force ProGuard to remove public static method? 线程“主”中的异常java.lang.NoSuchMethodError:org.openqa.selenium.io.FileHandler.unzip(Ljava / io / InputStream;)Ljava / io / File; - Exception in thread “main” java.lang.NoSuchMethodError: org.openqa.selenium.io.FileHandler.unzip(Ljava/io/InputStream;)Ljava/io/File; java.lang.NoSuchMethodError: org.apache.commons.io.FileUtils.copyInputStreamToFile(Ljava/io/InputStream;Ljava/io/File;) - java.lang.NoSuchMethodError: org.apache.commons.io.FileUtils.copyInputStreamToFile(Ljava/io/InputStream;Ljava/io/File;) 没有名称=&#39;getMessage&#39;签名=&#39;()Ljava / lang / String;&#39;的静态方法 在类Ljava.lang.Object;中 - no static method with name='getMessage' signature='()Ljava/lang/String;' in class Ljava.lang.Object; Spring Tomcat启动问题setCatalinaBase(Ljava / io / File;) - Spring Tomcat Startup Issue setCatalinaBase(Ljava/io/File;) Android:NoSuchMethodError:没有静态方法zzy(Ljava / lang / Object; - Android: NoSuchMethodError: No static method zzy(Ljava/lang/Object; 在Android上启用Proguard失败 - enabling proguard on android failing 静态方法中的java.io.FileNotFoundException(访问被拒绝)来移动文件 - java.io.FileNotFoundException (Access is Denied) in a static method to move file 此处地图:产生者:java.lang.NoSuchMethodError:没有非静态方法“ Ljava / lang / AssertionError;。 <init> (Ljava / lang / String;)V” - HERE map:Caused by: java.lang.NoSuchMethodError: no non-static method “Ljava/lang/AssertionError;.<init>(Ljava/lang/String;)V”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM