专注Java教育14年 全国咨询/投诉热线:444-1124-454
星辉LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 Java编译器eclipse的主要分析

Java编译器eclipse的主要分析

更新时间:2021-05-25 15:24:55 来源:星辉 浏览763次

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:

java编译器eclipse

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

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

java编译器eclipse

java编译器eclipse

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

java编译器eclipse

这个文件报错,不过可以把他删除了看,我先没有删除,因为这个文件是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[])方法来进行编译,我们可以稍微看看:

java编译器eclipse

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

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

java编译器eclipse

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

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

以上就是星辉小编介绍的"Java编译器eclipse的主要分析",希望对大家有帮助,如有疑问,请在线咨询,有专业老师随时为您服务。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>