gpt4 book ai didi

android - 使用 ant 构建时验证错误,从 Eclipse 构建时正常

转载 作者:行者123 更新时间:2023-11-30 03:44:49 26 4
gpt4 key购买 nike

我的 Android java 项目有几个配置。以前我切换它们并手动从 eclipse 构建 apk,但最近我开发了几个 ant 任务以使我的生活更轻松:我启动 cmd 文件并构建所有配置(每次更改配置变量、移动资源、修改 list ,等)。

但今天我发现用 ant(它使用 javac)和 android 工作流(我的 build.xml 包括 ${sdk.dir}/tools/ant/build.xml)编译的代码与代码不同由 Eclipse 中的 ADT 工具生成。 差异是致命的。

在编译阶段,javac 声称某些文件包含 BOM,并且一个类太大(对许多静态数组而言)。我已经将所有文件转换为 utf8 w/o bom,将大类分成两部分,javac 没有更多问题。很容易。

但是,如果我在 4.0.x 设备或模拟器上启动 ant-made apk(同时在 1.6、2.2、4.1、4.2 上工作),它会在运行时强制关闭并说:

03-01 09:15:16.247: W/dalvikvm(1993): VFY: register1 v3 type 17, wanted 18
03-01 09:15:16.247: W/dalvikvm(1993): VFY: rejecting opcode 0xc8 at 0x0023
03-01 09:15:16.247: W/dalvikvm(1993): VFY: rejected Lcom/myproj/MySomeClass;.doThing (I)V
03-01 09:15:16.247: W/dalvikvm(1993): Verifier rejected class Lcom/myproj/MySomeClass;
03-01 09:15:16.247: W/System.err(1993): java.lang.VerifyError: com/myproj/MySomeClass
...
<stack here>
...

但是 eclipse-adt-made apk 在 4.0.x 上工作得很好!此外 - 我从未在编译时看到关于 utf bom 或类大小的 adt 声明。

所以我认为我们应该在 ant build 中使用其他东西而不是 javac。但 Google 在其 build.xml 中使用的正是 javac。 在用ant构建时如何使用ADT编译器而不是javac?

当然我仍然可以在 eclipse 中构建,但是当我花费 20 分钟时 ant 脚本花费 1 分钟,并且它在更改 cfg vars 时永远不会犯愚蠢的错误(它们之间存在一些依赖关系)。

提前致谢!

更新:我怀疑它与我使用的 java 版本有某种联系。 Ant 使用 1.7 x86 jdk 执行,而 eclipse 使用 jdk1.6.0_26 x64。有人说 Dalvik dex 不理解某些 java 1.7 字节码,但我应该检查一下。

UPDT1:不,我删除了所有 jdk,然后安装了 jdk 1.6.0_41 x86 和 x64,设置 eclipse work with 1.6.0_41 x64 并将 JAVA_PATH 设置为 jdk 1.6.0_41 x86。同样的事情-在 eclipse 中编译的 apk(Android 工具->导出签名的 apk)有效,ant-compiled apk 说 VerifyError。

最佳答案

我认为我已经解决了这个问题。

我花了几个小时切换 java 版本,重新定义默认的 google ant 任务,尝试从几个 jdk 中启动不同的 javac 作为独立的来编译我的类。在过去的五年里,我从来没有用控制台工具编译过 java,所以这很困难而且很困惑。我对任何 javac 都没有运气,同样的验证错误。

然后我看了Eclipse和Android的文档,发现我们在eclipse中构建apk时,ADT使用Eclipse的JDT(Eclipse Compiler for Java)代替javac将java代码编译成类,然后dx工具制作dalvik代码。所以我们需要启动 JDT 而不是正常的 -compile ant 任务,对吗?不,实际上一切都更容易。正如经常发生的那样,我从头开始,但一旦我明白我需要这个编译工具,我就走上了正确的道路。

Eclipse Compiler for Java (JDT ECJ) 是比实际的 javac 更智能的工具。这对我来说是一个带有大量参数的新工具,但 JDT 提供了非常酷的 ant javac adapter ,我们可以在 javac ant 任务中使用它 - 设置“build.compiler”属性,然后启动正常的 android ant -compile 任务:

<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter" />

<javac encoding="${java.encoding}" source="1.6" target="1.6" debug="true" extdirs=""
includeantruntime="false" destdir="${out.classes.absolute.dir}"
bootclasspathref="project.target.class.path"
verbose="${verbose}" classpathref="project.javac.classpath"
fork="${need.javac.fork}" >
<src path="${source.absolute.dir}" />
<src path="${gen.absolute.dir}" />
<compilerarg line="${java.compilerargs}" />
</javac>

但是除非你有 ecj.jar,否则这将不起作用。而eclipse中是没有这个文件的!继续调查我发现 Eclipse Compiler for Java 可以是 downloaded as standalone .要完成这项工作,您需要将此 jar 复制到 ant/lib 文件夹。但奇怪的是 - ecj 4.2.2 编译的代码具有相同的验证问题。幸运的是,我已经尝试过 ecj 3.5.1 - 并且成功了!但是我不满意 - 我仍然不能说为什么 ecj 4.2.2 没有帮助而 3.5.1 有帮助。如果我升级 eclipse 并且它会编译错误的类怎么办?我已经比较了字节码——它的差别很小(由 jd-gui 反编译),所以我假设问题出在生成的类文件中。我想知道到底是什么,但我什至无法想象要寻找什么。

无论如何,还有更多。当您查看 eclipse/plugins 文件夹时,您会看到一个名为“org.eclipse.jdt.core_3.6.2.v_A76_R36x.jar”的文件。它在内部保存 jdtCompilerAdapter.jar 文件(因为 jar 是一个 zip 存档)。如果您将它复制到 ant/lib,然后复制 org.eclipse.jdt.core_xxxxxx.jar 文件本身,您将获得与当前 eclipse 版本完全相同的编译器!瞧!通过这种方式,您可以确定如果 eclipse 生成“好”代码 - ant 也会这样做。


所以最后一切都只需要两个简单的步骤:

  1. 将其中的 org.eclipse.jdt.core_xxxxxx.jar 和 jdtCompilerAdapter.jar 复制到您的 ant/lib 文件夹中。

  2. 将以下内容添加到您的 project.properties 文件中:

    • java.target=1.6
    • java.source=1.6
    • build.compiler=org.eclipse.jdt.core.JDTCompilerAdapter

就是这样!

但如果您知道为什么来自 eclipse juno 包 (4.2.2) 的 ecj 无法编译正确的代码,我想听听!

关于android - 使用 ant 构建时验证错误,从 Eclipse 构建时正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15157185/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com