zoukankan      html  css  js  c++  java
  • 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 类文件
  • 相关阅读:
    动态调用web服务
    组件设计实战--组件之间的关系 (Event、依赖倒置、Bridge)
    .NET平台下可复用的Tcp通信层实现
    推荐所有的.NET开发人员阅读《J2EE Development without EJB》
    关于跨程序集的反射(续)
    IoC与DI (转载)
    某公司的一道机考题的解答
    使用 EmptyClass 避免条件判断
    EsbAOP应用--权限管理
    企业(分布式)计算十大谬误
  • 原文地址:https://www.cnblogs.com/xxjcai/p/10881873.html
Copyright © 2011-2022 走看看