一、问题

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

二、解决方案

  将所依赖到的Jar文件,复制到%JAVA_Home%\jre\lib\ext目录下。 例如:C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext 再重启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("\r\n" + clazz + ":compile success.");
//} else {
// resp.getWriter().write("\r\n" + 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;
}
}
}

Java Web部署到tomcat后,使用动态编译无法找到相关类的解决方案的更多相关文章

  1. Java Web 部署到Tomcat

    1.在conf目录中,新建Catalina(注意大小写)\localhost目录,在该目录中新建一个xml文件,名字可以随意取,只要和当前文件中的文件名不重复就行了,该xml文件的内容为: <C ...

  2. eclipse配置tomcat,并部署一个Java web项目到tomcat上

    引用链接:https://blog.csdn.net/cincoutcin/article/details/79408484 eclipse配置tomcat 1.windows——preference ...

  3. Java Project部署到Tomcat服务器上

    所有的JAVA程序员,在编写WEB程序时,一般都通过工具如 MyEclipse,编写一个WEB Project,通过工具让这个WEB程序和Tomcat关联.其实在我们可以通过JAVA程序部署到Tomc ...

  4. springboot打war包后部署到tomcat后访问返回404错误

    springboot打war包后部署到tomcat后访问返回404错误 1.正常情况下,修改打包方式为war <packaging>war</packaging> 2.启动类继 ...

  5. Java Web开发: Tomcat中部署项目的三种方法

    web开发,在tomcat中部署项目的方法: 可以参考http://m.blog.csdn.net/blog/u012516903/15741727 定义$CATALINA_HOME指的是Tomcat ...

  6. myeclipse中的web项目导入到eclipse中注意事项,项目部署到tomcat后无法访问jsp文件

    打开eclipse,点击空白处,右键可以看到import>general>existing projects into workspace>next>选择你的myeclipse ...

  7. Eclipse部署Java Web项目到Tomcat出错

    1.今天,我打开Eclipse,准备将一个Java Web项目部署到Tomcat中, 结果弹出提示错误窗口,具体如下: (1)出错详情 Could not publish server configu ...

  8. 使用Maven自动部署Java Web项目到Tomcat问题小记

    导读 首先说说自己为啥要用maven管理项目,一个直接的原因是:我在自己电脑上开发web项目,每次部署到服务器上时都要经历如下步骤: 首先在Eclipse里将项目打包成war包 将服务器上原来的项目文 ...

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

    很纳闷的一个问题,通过配置文件生成的java源码在本地动态编译没有问题,但是部署服务器后编译不通过,找不到依赖的jar包. 通过网上查资料,找到一个兄弟提供的方法,问题解决了:下面贴出代码以供参考: ...

随机推荐

  1. Orchard之Module升级

    在上一篇中,我们提到了 Migrations,这一篇稍微衍生一下. 1:Migrations 是什么 Orchard 提供了模块升级的功能,即,如果我们模块发布后,需要进行升级,我们可以通过编码来实现 ...

  2. Docker 常用命令与操作

    介绍 此命令集合版本为 1.11.1 及以上 基础类 查看docker信息 # 查看docker版本 docker version # 显示docker系统的信息 docker info # 日志信息 ...

  3. perf使用示例1

    perf使用示例1 perf - Performance analysis tools for Linux Performance counters for Linux are a new kerne ...

  4. CodeReview工具Gerrit的python库pygerrit2

    源代码: https://github.com/dpursehouse/pygerrit2

  5. 存储过程参数CHAR传过来null导致超时.

    调用的时候不要传NULL,可以传 '' ALTER PROCEDURE [dbo].[up_UC_GetUCExecuteEPList]          @Code VARCHAR(3) ,--ch ...

  6. AutoCppHeader AutoHeader 自动根据CPP 或C文件 来生成头文件。

    根据 cpp文件 生成相应的头文件 namespace 声明类定义声明 函数声明 extern 变量声明 选项--------------//[AutoHeader Public] //[AutoHe ...

  7. GROUP BY中ROLLUP/CUBE/GROUPING/GROUPING SETS使用示例

    oracle group by中rollup和cube的区别: Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句.CUBE ROLLUP 是用于统计数据的. 实验 ...

  8. iOS开发-简单抽奖

    路过商场,看过抽奖感觉挺有意思的,商场进行抽奖活动,三个奖项,一等奖的概率1/10,二等奖的概率的3/10,三等奖的概率是6/10,具体奖品我没仔细看,回来随便练手了一下,思考了一下,奖品分为10份, ...

  9. Android -- Annotation

    Override Annotation @Override public void onCreate(Bundle savedInstanceState){}; 概念 An annotation is ...

  10. PHP 自定义方法实现数组合并

    在PHP中提供了强大的数组功能,对于数组的合并也提供了两个方法:array_merge 和 array_merge_recursive 但对于我们千变万化的业务来说这些内置的方法并不完全能满足我们的要 ...