All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.tac.engine.compile.JdkCompilerImpl Maven / Gradle / Ivy

/*
 *   MIT License
 *
 *   Copyright (c) 2016 Alibaba Group
 *
 *   Permission is hereby granted, free of charge, to any person obtaining a copy
 *   of this software and associated documentation files (the "Software"), to deal
 *   in the Software without restriction, including without limitation the rights
 *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *   copies of the Software, and to permit persons to whom the Software is
 *   furnished to do so, subject to the following conditions:
 *
 *   The above copyright notice and this permission notice shall be included in all
 *   copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 *   SOFTWARE.
 */

package com.alibaba.tac.engine.compile;

import com.alibaba.tac.engine.bootlaucher.BootJarLaucherUtils;
import com.alibaba.tac.engine.properties.TacDataPathProperties;
import com.alibaba.tac.engine.service.TacFileService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileFilter;
import java.io.StringWriter;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class JdkCompilerImpl implements IJdkCompiler, InitializingBean {

    private static final Logger LOG = LoggerFactory.getLogger(JdkCompilerImpl.class);

    private static final List OPTIONS = new ArrayList();

    private static final List CLASSPATH = new ArrayList();

    static {
        OPTIONS.add("-target");
        OPTIONS.add("1.8");
    }

    @Resource
    private TacDataPathProperties tacDataPathProperties;

    @Resource
    private TacFileService tacFileService;

    public String sourcePathPrefix;
    public String outputPathPrefix;
    public String classLoadPathPrefix;
    public String pkgPrefix;

    @PostConstruct
    public void init() {

        this.sourcePathPrefix = tacDataPathProperties.getSourcePathPrefix();
        this.outputPathPrefix = tacDataPathProperties.getOutputPathPrefix();
        this.classLoadPathPrefix = tacDataPathProperties.getClassLoadPathPrefix();
        this.pkgPrefix = tacDataPathProperties.getPkgPrefix();
    }

    @Override
    public synchronized boolean compile(InstCodeInfo codeInfo, StringWriter compileInfo) throws Exception {

        return this.compile(codeInfo, compileInfo, String.valueOf(codeInfo.getInstId()));
    }

    @Override
    public synchronized boolean compileWithMsCode(InstCodeInfo codeInfo, StringWriter compileInfo) throws Exception {

        return this.compile(codeInfo, compileInfo, codeInfo.getName());
    }

    @Override
    public void addClassPath(File file) {
        CLASSPATH.add(file);
        LOG.debug("add compile class path:{}", file.getAbsolutePath());
    }

    private boolean compile(InstCodeInfo codeInfo, StringWriter compileInfo, String outputName) throws Exception {
        long start = 0;
        if (LOG.isInfoEnabled()) {
            start = System.currentTimeMillis();
        }
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);

        File[] outputs = new File[] {new File(tacFileService.getClassFileOutputPath(outputName))};
        for (File file : outputs) {
            if (!file.exists()) {
                file.mkdirs();
            } else {
                TacFileService.deleteRecursively(file);
                file.mkdirs();
            }
        }

        LOG.debug("compile classpath.  size:{}  CLASS-PATH:{}", CLASSPATH.size(), CLASSPATH);

        fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(outputs));
        fileManager.setLocation(StandardLocation.CLASS_PATH, CLASSPATH);
        List fileObjects = new ArrayList();
        for (JavaSourceCode unit : codeInfo.getJavaSourceCodes()) {
            TacJavaFileObject sourceObject = new TacJavaFileObject(unit.getFullClassName(), unit.getSource());
            fileObjects.add(sourceObject);
        }
        CompilationTask task = compiler.getTask(compileInfo, fileManager, null, OPTIONS, null, fileObjects);
        Boolean resultSuccess = task.call();
        if (resultSuccess == null || !resultSuccess) {
            return false;
        }
        fileManager.close();
        if (LOG.isInfoEnabled()) {
            LOG.info("compile complete . name :{}  instClassName:{} cost: {} resultSucess:{} ", codeInfo.getName(),
                codeInfo.getInstClassName(), (System.currentTimeMillis() - start), resultSuccess);
        }
        return true;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        initTacDict();

        LOG.debug("init class path:\n");
        ClassLoader classLoader = this.getClass().getClassLoader();
        while (classLoader != null) {
            this.addClassLoaderClassPath(classLoader);
            classLoader = classLoader.getParent();
        }

        addBootLibJars();
    }

    /**
     * add boot lib jars to the compile classpath
     */
    private void addBootLibJars() {

        File tempUnpackFolder = BootJarLaucherUtils.getTempUnpackFolder();
        if (tempUnpackFolder != null && tempUnpackFolder.isDirectory() && tempUnpackFolder.exists()) {

            File[] files = tempUnpackFolder.listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    return StringUtils.endsWith(pathname.getName(), ".jar");
                }
            });
            for (File file : files) {
                CLASSPATH.add(file);
                LOG.debug("add compile class path:{} ", file.getPath());
            }
        }
    }

    /**
     * @param classLoader
     */
    private void addClassLoaderClassPath(ClassLoader classLoader) {
        ClassLoader loader = classLoader;

        if (loader instanceof URLClassLoader) {
            URLClassLoader urlClassLoader = (URLClassLoader)loader;
            URL[] urls = urlClassLoader.getURLs();
            for (URL url : urls) {
                File file = new File(url.getFile());
                if (file.exists()) {
                    CLASSPATH.add(file);
                    LOG.debug("add compile class path:{} ", file.getPath());
                }

            }
        } else {
            LOG.error("need URLClassLoader!!");
        }
    }

    private void initTacDict() {


        // class compile output directory


        File outputPathDic = new File(this.outputPathPrefix);

        if (!outputPathDic.exists()) {
            outputPathDic.mkdirs();
        }
        /**
         * class load direcotry
         */
        File classLoadDic = new File(this.classLoadPathPrefix);
        if (!classLoadDic.exists()) {
            classLoadDic.mkdirs();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy