首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ant构建时VerifyError,从Eclipse构建时确定

使用ant构建时VerifyError,从Eclipse构建时确定
EN

Stack Overflow用户
提问于 2013-03-01 11:56:06
回答 1查看 865关注 0票数 1

我的Android java项目有几种配置。在此之前,我手动切换了它们并从eclipse构建apk,但是最近我开发了几个ant任务来使我的生活变得更简单:我启动cmd文件,它构建所有的配置(每次更改配置vars、移动资源、修改清单等等)。

,但是今天,我发现android (我的build.xml包含${sdk.dir}/tools/ ant /build.xml)编译的代码与Eclipse工具生成的代码不同,和difference是致命的。

在编译阶段,javac声称有些文件包含BOM,其中一个类太大(对许多静态数组来说)。我已经将所有文件转换为utf8 w/o bom,将大类拆分为两个,并且javac没有更多问题。这很简单。

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

代码语言:javascript
复制
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制作的apk在4.0.x上工作得很好!此外,我从未见过adt声称在编译时使用utf bom或类大小。

所以我想我们应该在ant构建中使用比javac更重要的东西。但谷歌在其build.xml中确实使用了javac。如何在使用ant构建时使用ADT编译器而不是javac?

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

提前感谢!

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

UPDT1:不,我已经删除了所有jdk,然后安装了jdk 1.6.0_41 x86和x64,用1.6.0_41 x64设置了eclipse工作,并将JAVA_PATH设置为jdk 1.6.0_41 x86。VerifyError说,在eclipse中编译的apk (Android >Export)也是一样的,蚂蚁编译的apk也能工作。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-02 00:12:41

我想我已经解决了这个问题。

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

然后我阅读了eclipse和Android文档,发现当我们在Eclipse中构建apk时,ADT使用Eclipse的JDT ()代替javac将java代码编译成类,然后使用dx工具来生成dalvik代码。所以我们需要启动JDT,而不是普通的-compile蚂蚁任务,对吗?不,实际上一切都比较简单。正如经常发生的那样,我从结尾开始,但是一旦我理解了我需要这个编译工具,我就走对了路。

(JDT )比实际的javac要聪明得多。对于我来说,它是一个新的工具,有很多参数,但是JDT提供了非常酷的蚂蚁javac适配器,我们可以在javac ant任务集"build.compiler“属性中使用它,然后启动普通的android -compile任务:

代码语言:javascript
复制
<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中没有这样的文件!我发现可以是作为独立下载。要完成这项工作,需要将此jar复制到ant/lib文件夹中。但奇怪的是,ECJ4.2.2编译的代码也存在相同的验证问题。幸运的是,我已经尝试了ecj 3.5.1 -而且它成功了!然而,我并不满意--我仍然不能解释为什么ecj 4.2.2没有帮助,而3.5.1起作用。如果我升级了eclipse并且它会编译坏的类,该怎么办?我比较了字节码--它有很小的不同(由jd解压缩),所以我假设问题在产生的类文件中。我想知道到底是怎么回事,但我甚至无法想象要找什么。

不管怎样,还有更多。当您查看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文件中添加以下内容:
代码语言:javascript
复制
- java.target=1.6
- java.source=1.6
- build.compiler=org.eclipse.jdt.core.JDTCompilerAdapter

就这样!

,但是如果您知道为什么eclipse (4.2.2)中的ecj不能编译正确的代码,我想听一听!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15157185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档