编译apktool_v2.2.1出错

按照这里的编译apktool的方法:
https://ibotpeaches.github.io/Apktool/build/
编译v2.2.2及后续版本都没有问题,但是对于v2.2.1的时候,就出现了错误。起初在我的macOs上是这样的:

brut.androlib.BuildAndDecodeTest > classMethod FAILED
    brut.androlib.AndrolibException: brut.common.BrutException: could not exec (exit code = 1): [/var/folders/cv/dg1rf__x7ygbp_dmd6r2snnw0000gn/T/brut_util_Jar_5701664016852435316.tmp, p, --version-code, 1, --version-name, 1.0, -F, /var/folders/cv/dg1rf__x7ygbp_dmd6r2snnw0000gn/T/BRUT728632478128516271.tmp/testapp.apk, -0, arsc, -A, /var/folders/cv/dg1rf__x7ygbp_dmd6r2snnw0000gn/T/BRUT728632478128516271.tmp/testapp-orig/assets, /var/folders/cv/dg1rf__x7ygbp_dmd6r2snnw0000gn/T/BRUT728632478128516271.tmp/testapp-orig/build/apk]
        at brut.androlib.res.AndrolibResources.aaptPackage(AndrolibResources.java:439)
        at brut.androlib.Androlib.buildApk(Androlib.java:675)
        at brut.androlib.Androlib.build(Androlib.java:315)
        at brut.androlib.BuildAndDecodeTest.beforeClass(BuildAndDecodeTest.java:56)

        Caused by:
        brut.common.BrutException: could not exec (exit code = 1): [/var/folders/cv/dg1rf__x7ygbp_dmd6r2snnw0000gn/T/brut_util_Jar_5701664016852435316.tmp, p, --version-code, 1, --version-name, 1.0, -F, /var/folders/cv/dg1rf__x7ygbp_dmd6r2snnw0000gn/T/BRUT728632478128516271.tmp/testapp.apk, -0, arsc, -A, /var/folders/cv/dg1rf__x7ygbp_dmd6r2snnw0000gn/T/BRUT728632478128516271.tmp/testapp-orig/assets, /var/folders/cv/dg1rf__x7ygbp_dmd6r2snnw0000gn/T/BRUT728632478128516271.tmp/testapp-orig/build/apk]
            at brut.util.OS.exec(OS.java:95)
            at brut.androlib.res.AndrolibResources.aaptPackage(AndrolibResources.java:433)
            ... 3 more

brut.androlib.DefaultBaksmaliVariableTest > classMethod FAILED
    java.lang.NoSuchMethodError: brut.androlib.Androlib.build(Lbrut/directory/ExtFile;Ljava/io/File;)V
        at brut.androlib.DefaultBaksmaliVariableTest.beforeClass(DefaultBaksmaliVariableTest.java:30)

brut.androlib.ExternalEntityTest > classMethod FAILED
    java.lang.NoSuchMethodError: brut.androlib.Androlib.build(Lbrut/directory/ExtFile;Ljava/io/File;)V
        at brut.androlib.ExternalEntityTest.beforeClass(ExternalEntityTest.java:46)

brut.androlib.ParentDirectoryTraversalTest > checkIfDrawableFileDecodesProperly FAILED
    brut.androlib.AndrolibException: brut.directory.DirectoryException: Error copying file: ../assets/0/logo.png
        at brut.androlib.Androlib.decodeUnknownFiles(Androlib.java:218)
        at brut.androlib.ApkDecoder.decode(ApkDecoder.java:158)
        at brut.androlib.ParentDirectoryTraversalTest.checkIfDrawableFileDecodesProperly(ParentDirectoryTraversalTest.java:54)

        Caused by:
        brut.directory.DirectoryException: Error copying file: ../assets/0/logo.png
            at brut.directory.DirUtil.copyToDir(DirUtil.java:88)
            at brut.directory.AbstractDirectory.copyToDir(AbstractDirectory.java:207)
            at brut.androlib.Androlib.decodeUnknownFiles(Androlib.java:211)
            ... 2 more

            Caused by:
            java.io.FileNotFoundException: /var/folders/cv/dg1rf__x7ygbp_dmd6r2snnw0000gn/T/BRUT5609822345258535982.tmp/issue1498.apk.out/unknown/../assets/0/logo.png (No such file or directory)
                at java.io.FileOutputStream.open0(Native Method)
                at java.io.FileOutputStream.open(FileOutputStream.java:270)
                at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
                at java.io.FileOutputStream.<init>(FileOutputStream.java:162)
                at brut.directory.DirUtil.copyToDir(DirUtil.java:84)
                ... 4 more

brut.androlib.PositionalEnumerationTest > threeArgumentsTest FAILED
    org.junit.ComparisonFailure: expected:<%1$s, %2$s, and %[3$]d other.> but was:<%1$s, %2$s, and %[]d other.>
        at org.junit.Assert.assertEquals(Assert.java:115)
        at org.junit.Assert.assertEquals(Assert.java:144)
        at brut.androlib.PositionalEnumerationTest.threeArgumentsTest(PositionalEnumerationTest.java:45)

brut.androlib.VectorDrawableTest > checkIfDrawableFileDecodesProperly FAILED
    java.lang.IllegalStateException: duplicated prefix 'android'
        at org.xmlpull.mxp1_serializer.MXSerializer.setPrefix(MXSerializer.java:444)
        at org.xmlpull.v1.wrapper.classic.StaticXmlSerializerWrapper.setPrefix(StaticXmlSerializerWrapper.java:132)
        at org.xmlpull.v1.wrapper.classic.StaticXmlSerializerWrapper.writeStartTag(StaticXmlSerializerWrapper.java:261)
        at org.xmlpull.v1.wrapper.classic.StaticXmlSerializerWrapper.event(StaticXmlSerializerWrapper.java:211)
        at brut.androlib.res.decoder.XmlPullStreamDecoder$1.event(XmlPullStreamDecoder.java:83)
        at brut.androlib.res.decoder.XmlPullStreamDecoder.decode(XmlPullStreamDecoder.java:141)
        at brut.androlib.res.decoder.ResStreamDecoderContainer.decode(ResStreamDecoderContainer.java:33)
        at brut.androlib.res.decoder.ResFileDecoder.decode(ResFileDecoder.java:120)
        at brut.androlib.res.decoder.ResFileDecoder.decode(ResFileDecoder.java:105)
        at brut.androlib.res.AndrolibResources.decode(AndrolibResources.java:262)
        at brut.androlib.Androlib.decodeResourcesFull(Androlib.java:132)
        at brut.androlib.ApkDecoder.decode(ApkDecoder.java:108)
        at brut.androlib.VectorDrawableTest.checkIfDrawableFileDecodesProperly(VectorDrawableTest.java:54)

24 tests completed, 6 failed
:brut.apktool:apktool-lib:test FAILED

FAILURE: Build failed with an exception.

都是编译的时候进行了Test,然后Test没有通过的导致的编译出错。然后我试试在我的ubuntu16.04上看看。开始由于是OpenJDK,我怕这个可能有影响,然后卸载了OpenJDK, 再重新下载oracle JDK,然而还是有问题:

brut.androlib.BuildAndDecodeTest > classMethod FAILED
    brut.androlib.AndrolibException: java.io.FileNotFoundException: /tmp/BRUT189745146216816624.tmp/testapp-orig/unknown/nonprintable.file (No such file or directory)
        at brut.androlib.Androlib.buildUnknownFiles(Androlib.java:603)
        at brut.androlib.Androlib.build(Androlib.java:319)
        at brut.androlib.BuildAndDecodeTest.beforeClass(BuildAndDecodeTest.java:56)

        Caused by:
        java.io.FileNotFoundException: /tmp/BRUT189745146216816624.tmp/testapp-orig/unknown/nonprintable.file (No such file or directory)
            at java.io.FileInputStream.open0(Native Method)
            at java.io.FileInputStream.open(FileInputStream.java:195)
            at java.io.FileInputStream.<init>(FileInputStream.java:138)
            at brut.util.BrutIO.copy(BrutIO.java:78)
            at brut.androlib.Androlib.copyUnknownFiles(Androlib.java:656)
            at brut.androlib.Androlib.buildUnknownFiles(Androlib.java:601)
            ... 2 more

15 tests completed, 1 failed
:brut.apktool:apktool-lib:test FAILED

FAILURE: Build failed with an exception.

这下就只有一个错误了,但是还是编译出错。然后这里的
https://network.informatica.com/thread/17212
回答给了我启示,即将java.io.tmpdir=<your specific location>。然后我就找一下可能是哪里用到了java.io.tmpdir
搜到了这个。

cqq@ubuntu:~/repos/apktool-dev/Apktool-2.2.1/Apktool-2.2.1$ grep -rn "java.io.tmpdir" *
brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java:726:                        parentPath.getAbsolutePath(), System.getProperty("java.io.tmpdir")));
brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java:730:                parentPath = new File(System.getProperty("java.io.tmpdir"));

然后傻不啦叽的把System.getProperty("java.io.tmpdir")改成了自己指定了目录,以为万事大吉了,结果重新编译还是一样的问题。
后来又再仔细看看出错的地方:brut.androlib.Androlib.buildUnknownFiles(Androlib.java:601),编译的时候应该是Test中的代码没有通过才对啊,为啥要去改源码。。。。
然后找到这里:brut.apktool/apktool-lib/src/test/java/brut/androlib/BuildAndDecodeTest.javabeforeClass方法:

sTmpDir = new ExtFile(OS.createTempDirectory());

使用brut.util.OS类的createTempDirectory()方法创建了一个tmp目录。
其中createTempDirectory()方法为:

    public static File createTempDirectory() throws BrutException {
        try {
            File tmp = File.createTempFile("BRUT", null);
            if (!tmp.delete()) {
                throw new BrutException("Could not delete tmp file: " + tmp.getAbsolutePath());
            }
            if (!tmp.mkdir()) {
                throw new BrutException("Could not create tmp dir: " + tmp.getAbsolutePath());
            }
            return tmp;
        } catch (IOException ex) {
            throw new BrutException("Could not create tmp dir", ex);
        }
    }

即使用File.createTempFile("BRUT", null);创建了/tmp/BRUTxxxxxx目录。
测试了一下这个方法的功能。

$ cat Test.java
import java.io.File;

public class Test{
    public static void main(String[] args){
        try{
            File.createTempFile("test_cqq", null);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
$ javac Test.java
$ java Test
$ ll /tmp|grep test_cqq
-rw-rw-r--  1 cqq  cqq     0 Dec 28 22:48 test_cqq5553827309620261131.tmp

可能在apktool的Test代码中生成的tmp目录在之后寻找的时候已经不存在了。于是这里试试换成自己自定义的目录”/home/cqq/tmp”吧。

….醉了,结果还是不行:

brut.androlib.BuildAndDecodeTest > classMethod FAILED
    brut.androlib.AndrolibException: java.io.FileNotFoundException: /home/cqq/tmp/testapp-orig/unknown/nonprintable.file (No such file or directory)

后来又用brut.androlib.BuildAndDecodeTest > classMethod FAILED关键词搜到了官方仓库的bug issue。
https://github.com/iBotPeaches/Apktool/issues/1394
官方给的答案是:可能是因为有空格导致的。
这里写图片描述
然后我根据错误信息brut.androlib.AndrolibException: java.io.FileNotFoundException: /home/cqq/tmp/testapp-orig/unknown/non printable.file (No such file or directory) 中的”printable.file”搜了一下,

cqq@ubuntu:~/repos/apktool-dev/Apktool-2.2.1/Apktool-2.2.1$ grep -rn "printable.file" *
brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/apktool.yml:15:  non\u007Fprintable.file: '8'
brut.apktool/apktool-lib/build/reports/tests/classes/brut.androlib.BuildAndDecodeTest.html:79:<pre>brut.androlib.AndrolibException: java.io.FileNotFoundException: /home/cqq/tmp/testapp-orig/unknown/non&#x7f;priversion: 2.0.0
ntable.file (No such file or directory)
brut.apktool/apktool-lib/build/reports/tests/classes/brut.androlib.BuildAndDecodeTest.html:118:Caused by: java.io.FileNotFoundException: /home/cqq/tmp/testapp-orig/unknown/non&#x7f;printable.file (No such file or directory)
Binary file brut.apktool/apktool-lib/build/test-results/binary/test/results.bin matches
brut.apktool/apktool-lib/build/test-results/TEST-brut.androlib.BuildAndDecodeTest.xml:5:    <failure message="brut.androlib.AndrolibException: java.io.FileNotFoundException: /home/cqq/tmp/testapp-orig/unknown/non&#x7f;printable.file (No such file or directory)" type="brut.androlib.AndrolibException">brut.androlib.AndrolibException: java.io.FileNotFoundException: /home/cqq/tmp/testapp-orig/unknown/non&#x7f;printable.file (No such file or directory)
brut.apktool/apktool-lib/build/test-results/TEST-brut.androlib.BuildAndDecodeTest.xml:44:Caused by: java.io.FileNotFoundException: /home/cqq/tmp/testapp-orig/unknown/non&#x7f;printable.file (No such file or directory)
brut.apktool/apktool-lib/build/resources/test/brut/apktool/testapp/apktool.yml:15:  non\u007Fprintable.file: '8'

然后看这个brut.apktool/apktool-lib/build/resources/test/brut/apktool/testapp/apktool.yml文件是很久之前建的,所以应该不是我手动改的,是官方自带的。

cqq@ubuntu:~/repos/apktool-dev/Apktool-2.2.1/Apktool-2.2.1$ ll brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/apktool.yml
-rw-rw-r-- 1 cqq cqq 344 Oct 18  2016 brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/apktool.yml

查看这个文件,原来这里面有\u007F这种操作!
这里写图片描述
然后把non\u007Fprintable.file改成nonprintable.file就编译成功了!
这里写图片描述
而作者是通过四个commits修改的。
https://github.com/iBotPeaches/Apktool/pull/1395/commits

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值