zoukankan      html  css  js  c++  java
  • Java Web部署到tomcat后,使用动态编译无法找到相关类的解决方案

    一、问题

      动态编译java文件时(这个java文件虽引用了第三方jar包),如果这个过程发生在java命令行程序中,则正常编译。如果发生在JavaWeb中,然后此Java部署到Tomcat之后,执行动态编译时,就会提示找不到相关类或者Jar。

    二、解决方案

      将所依赖到的Jar文件,复制到%JAVA_Home%jrelibext目录下。 例如:C:Program FilesJavajdk1.8.0_161jrelibext 再重启Tomcat。

    三、解决方法二:

      编译时,添加classPath参数,即可,DEMO代码很乱,参考如下:

      

    package servlets;
    
    import com.github.henryhuang.dynamiccompiler.ClassGenerator;
    import domain.MyJavaSourceFromString;
    import org.apache.commons.io.FileUtils;
    
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    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.Arrays;
    import java.util.List;
    
    public class MyServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
            try {
    
                String buildOutput = MyServlet.class.getProtectionDomain().getCodeSource().getLocation().getPath();
                File f = new File("D:\Project\JavaProject\dynamicompileInWeb\out\artifacts\web_war_exploded", "WEB-INF\TestCode.java");
                String code = FileUtils.readFileToString(f, "UTF-8");
                resp.getWriter().write(code);
    
                // instantiate the Java compiler
                JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
                JavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    
                // load the uploaded files into the compiler
                List<JavaFileObject> files = new ArrayList<JavaFileObject>();
                //files.add(new ByteArrayJavaFileObject(fullName, patchFile.getBytes()));
    
                files.add(new MyJavaSourceFromString("TestCode", code));
                // set the classpath
                List<String> options = new ArrayList<String>();
    
                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();
                System.out.println(isok);
                File root = new File(buildOutput);
                if (!root.exists()) root.mkdirs();
                URL[] urls = new URL[]{root.toURI().toURL()};
                URLClassLoader classLoader = URLClassLoader.newInstance(urls);
                Class<?> clazz2 = Class.forName("TestCode", true, classLoader);
    
                // instantiate the class (FAILS HERE)
                //Object instance = fileManager.getClassLoader(null).loadClass("TestCode").newInstance();
    
                // close the file manager
                fileManager.close();
    
                //
                //if (clazz != null) {
                //    resp.getWriter().write("
    " + clazz + ":compile success.");
                //} else {
                //    resp.getWriter().write("
    " + clazz + ":compile failed.");
                //}
    
            } catch (Exception ex) {
                resp.getWriter().write(ex.getMessage());
            }
    
        }
    }

     简单封装

    package com.test.utils.compile;
    
    import org.apache.commons.io.FileUtils;
    import com.test.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;
            }
        }
    }
  • 相关阅读:
    Lightoj 1082【RMQ】
    hrbust1444 逃脱 【BFS】
    萌新学习笔记之哈夫曼树
    lightoj 1085【离散化+树状数组】
    CodeForces 586D【BFS】
    lightoj 1089 【离散化+线段树】
    lightoj 1088【树状数组+离散化】
    《算法导论》笔记 第6章 6.2保持堆的性质
    《算法导论》笔记 第6章 6.1堆
    【python】__all__
  • 原文地址:https://www.cnblogs.com/songxingzhu/p/8980409.html
Copyright © 2011-2022 走看看