Eclipse编译器(ecj)与javac编译器
发布日期:2021-07-20 20:53:41 浏览次数:61 分类:技术文章

本文共 3929 字,大约阅读时间需要 13 分钟。

两者区别 

Eclipse已经实现了自己的编译器,命名为 Eclipse编译器for Java (ECJ)。

它不同于javac,Sun JDK附带的编译器。一个显着的区别是,Eclipse编译器允许您运行实际上没有正确编译的代码。如果错误的代码块从未运行,您的程序将运行良好。
另一个不同之处在于Eclipse编译器允许在Eclipse中进行增量构建IDE,也就是所有的代码一旦你完成输入就编译。
Eclipse自带的编译器也是很明显的,因为你可以编写,并且在Eclipse中运行Java代码,甚至不安装Java SDK。

在ant或maven中使用ecj

为什么要换ecj呢? JDK自带的java不够好吗? 是的, 尤其是debug信息. 那两种兼容吗? 完全兼容, ecj和javac一样是经过认证的哦, 事实上,如果你正在使用Eclipse,那么,你的java源码, 100%是ecj编译的呢(当然,是你自己写的那部分)

Ant换用ecj 1. 在build.xml中加入:

  1. 下载独立的ecj.jar

  2. 将ecj-3.7.2.jar放入ant的lib文件夹中

  3. 如果是eclipse中跑ant,那么,需要设置一下, Run As – Ant Build … – ClassPath ,加入ecj.jar

Maven换用ecj 1. 官网文档: 2. 设置为plexus-compiler-eclipse即可

带来的好处: []() 事实证明, 只有ecj编译的class文件的debug信息会原样遵循方法参数的声明顺序, 悲催啊…

 

关于ECJ

Java是一个开放的平台,对于除发布编译器/解释器/基础类库之外,该语言的负责机构更多的是制定一系列标准,任何符合标准的厂商产品均可用于市场投放。甚至包括其编译器及解释器。

  (比如Hibernate提供了JPA实现;Tomcat实现了Java EE服务器标准,其Servlet容器通过了Java认证;各数据库或中间件厂商也根据JDBC接口开发驱动。说白了,Java基本就是都提供接口,然后让厂商开发实现,因此有时候我会骂,边骂边编码!)

  GCC有java编译器,可以看看。

  我们主要主要介绍Eclipse自己开发和使用的针对Java的编译器:(ecj) the Eclipse Compiler for Java。Eclipse没有使用JDK自带的编译器,而是自己开发的,ecj也通过了java的验证。

 

  除了Eclipse之外,Tomcat也用到了Ecj,用于动态编译jsp文件。我们安装Tomcat后可在lib文件夹下找到ecj:

  

  现在问题来了:怎么取得ecj源码呢?

  别急,我们从tomcat源码中查看一下:

  

  

  虽然我不熟ant,但我也能知道,Tomcat6.0.37中使用的ecj下载路径是:

  

  这个还是class文件,刚开始我也没辙,不过后来我灵机一动:在ecj后面加个src竟然成了!-_-

  

  下面是我下载好后倒入项目文件后截图:

  

  

  这个文件报错,不过可以把他删除了看,我先没有删除,因为这个文件是ecj与ant的桥梁。从源码可以看出这个JDTCompilerAdapter是继承自ant的DefaultCompilerAdapter,用于ant的编译器适配器。个人感觉ecj从代码(技术)上并没有耦合任何一个调用者,这里的ant也只是一个适配器,你删除或者留着没有任何影响。Tomcat里也没有使用ant。

  我从这里主要是想看看高层怎么调用ecj来编译代码,我们看看关键代码:

private static String compilerClass = "org.eclipse.jdt.internal.compiler.batch.Main"; //$NON-NLS-1$/**     * Performs a compile using the JDT batch compiler     * @throws BuildException if anything wrong happen during the compilation     * @return boolean true if the compilation is ok, false otherwise     */    public boolean execute() throws BuildException {        this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.info.usingJDTCompiler"), Project.MSG_VERBOSE); //$NON-NLS-1$        Commandline cmd = setupJavacCommand();        try {            Class c = Class.forName(compilerClass);            Constructor batchCompilerConstructor =                     c.getConstructor(new Class[] {                             PrintWriter.class,                             PrintWriter.class,                             Boolean.TYPE,                             Map.class});            Object batchCompilerInstance =                     batchCompilerConstructor.newInstance(new Object[] {                            new PrintWriter(System.out),                             new PrintWriter(System.err),                             Boolean.TRUE,                             this.customDefaultOptions});            Method compile =                     c.getMethod("compile", new Class[] {String[].class}); //$NON-NLS-1$            Object result =                     compile.invoke(batchCompilerInstance, new Object[] {                             cmd.getArguments()});            final boolean resultValue = ((Boolean) result).booleanValue();            if (!resultValue && this.logFileName != null) {                this.attributes.log(AntAdapterMessages.getString("ant.jdtadapter.error.compilationFailed", this.logFileName)); //$NON-NLS-1$            }            return resultValue;        } catch (ClassNotFoundException cnfe) {            throw new BuildException(AntAdapterMessages.getString("ant.jdtadapter.error.cannotFindJDTCompiler")); //$NON-NLS-1$        } catch (Exception ex) {            throw new BuildException(ex);        }    }

 

  我把代码换了下行,大家看13和26行,可以看出这里使用了

  org.eclipse.jdt.internal.compiler.batch.Main#compile(String[])方法来进行编译,我们可以稍微看看:

  从源码上来看1664是配置,1684可能是编译,不过我们先不细看。

  我们再看看Tomcat怎么使用ecj的,我们查看org.apache.jasper.compiler.JDTCompiler源码(我贴出了源码,不过有点长):

  

TomcatAdapter

  

  从427可以知道,Tomcat使用了org.eclipse.jdt.internal.compiler.Compiler#compile(ICompilationUnit[])

  当然,在这之前使用了很多代码来进行配置。

转载地址:https://blog.csdn.net/liao0801_123/article/details/85501154 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:阿里开源工具 TProfiler --在海量业务代码中精确定位性能代码
下一篇:支付宝调用返回notify_url(异步)与return_url(同步)

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年03月11日 07时31分14秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

视频提取音频php,如何提取视频中的音频,从视频文件中提取出音频输出成MP3格式... 2019-04-21
diy.php添加验证码,织梦dedecms自定义表单中加入验证码 2019-04-21
在php脚本中 通过可以获取,在PHP中,可以使用Unix时间戳获取精确的脚本执行时间。... 2019-04-21
s2-045 php exp,S2-045-EXP.py --Struts2任意代码执行漏洞 (S2-045,CVE-2017-5638) 2019-04-21
linux sdk 窗口句柄,Venus: 针对Linux平台上,对常用的系统API进行面向对象的封装SDK。... 2019-04-21
c语言程序设计 科学出版社习题答案,C语言程序设计(科学出版社)第4章 课后习题参考答案.doc... 2019-04-21
c语言 无错 但只运行一半,求哈夫曼编码时程序运行到一半就终止了,编译无错... 2019-04-21
deepin linux 2014安装,2014.2版本的Deepin虚拟机安装浅谈(就是深度Linux) 2019-04-21
android 限速工具,Android下载器之限速篇 2019-04-21
html刷新ajax实现原理,AJAX的原理—如何做到异步和局部刷新 2019-04-21
html中列表菜单加文字请选择,html中下拉菜单 2019-04-21
读书郎平板中android,读书郎学生平板电脑怎么用 使用方法详解【图文】 2019-04-21
html5 调用摄像头 支持IE,JS调用本地摄像头拍照(兼容各大浏览器及IE8+) 2019-04-21
rust和gta5哪个吃配置_盘点4款Steam“自由度”很高的游戏,GTA5众所周知,目前最热门... 2019-04-21
es审计日志_elasticsearch 事务日志translog 2019-04-21
dw1510_超低温种子储存柜 2019-04-21
文件未找到mathpage.wll_解决MathPage.wll文件找不到的问题(找了好久的良心之作)... 2019-04-21
java 使用或覆盖了已过时的api_JAVA使用或覆盖了已过时的 API 2019-04-21
java 图片旋转保存_Java 对图片90度旋转 2019-04-21
用java实现文学研究助手_数据结构文学研究助手 C语言代码实现(带源码+解析)... 2019-04-21