• web项目部署后动态编译无法找到依赖的jar包


    很纳闷的一个问题,通过配置文件生成的java源码在本地动态编译没有问题,但是部署服务器后编译不通过,找不到依赖的jar包。

    通过网上查资料,找到一个兄弟提供的方法,问题解决了;下面贴出代码以供参考:

    package com.songxingzhu.utils.compile;
    import org.apache.commons.io.FileUtils;
    import com.songxingzhu.utils.context.AppContext;
    import javax.tools.JavaCompiler;
    import javax.tools.JavaFileManager;
    import javax.tools.JavaFileObject;
    import javax.tools.ToolProvider;
    import java.io.File;
    import java.io.IOException;
    import java.net.URL;
    import java.net.URLClassLoader;
    import java.util.ArrayList;
    import java.util.List;

    public class ClassBuilder {
        public static Class<?> buildClass(String fullClassName, String codeFilePath) throws IOException, ClassNotFoundException {
            return buildClass(fullClassName, codeFilePath, "UTF-8", AppContext.baseDirectory());
        }
        public static Class<?> buildClass(String fullClassName, String codeFilePath, String charsetName, String buildOutput) throws IOException, ClassNotFoundException {
            try {
                String code = FileUtils.readFileToString(FileUtils.getFile(codeFilePath), charsetName);
                JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
                JavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
                List<JavaFileObject> files = new ArrayList<>();
                files.add(new JavaSourceFromCodeString(fullClassName, code));
                List<String> options = new ArrayList<>();
                options.add("-classpath");
                StringBuilder sb = new StringBuilder();
                URLClassLoader urlClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
                for (URL url : urlClassLoader.getURLs()) {
                    sb.append(url.getFile()).append(File.pathSeparator);
                }
                options.add(sb.toString());
                options.add("-d");
                options.add(buildOutput);
                // execute the compiler
                boolean isok = compiler.getTask(null, fileManager, null, options, null, files).call();
                if (isok) {
                    File root = new File(buildOutput);
                    if (!root.exists()) root.mkdirs();
                    URL[] urls = new URL[]{root.toURI().toURL()};
                    ClassLoader classLoader = ClassBuilder.class.getClassLoader();
                    Class<?> clazz = Class.forName(fullClassName, true, classLoader);
                    return clazz;
                }
                return null;
            } catch (Exception ex) {
                throw ex;
            }
        }
    }
     
    个人理解:部署后不像eclipse编译有.classpath指向依赖的所有的jar,需要自己组装类似classpath,指定jar包路劲。重点是设置option,不懂option的可以通过cmd命令查看javac的参数介绍。
    其中,option.add("-classpath");就是类似直接运行javac -classpath 类文件
  • 相关阅读:
    C#跨窗体操作
    搞IT的不如去养鸡养猪了
    C# 委托实例(跨窗体操作控件)
    FastReport 自定义页长
    SQL 根据一个表更新另一个表的内容
    Delphi中用ADOQuery实现主从表的例子(转)
    旅行的意义
    嘉州影院的网址
    纯粹的人
    Delphi中流的使用:压缩与解压缩(TCompressionStream、TDecompressionStream)
  • 原文地址:https://www.cnblogs.com/xxjcai/p/10881873.html
Copyright © 2020-2023  润新知