一、问题

  动态编译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. 什么是K线?K线的详解!

    K线图这种图表源于日本德川幕府时代,被当时日本米市的商人用来记录米市的行情与价格波动,后因其细腻独到的标画方式而被引入到股市及期货市场.目前,这种图表分析法在我国乃至整个东南亚地区均尤为流行.由于绘制 ...

  2. CentOS 安装 nexus (maven 私服)

    原文:https://www.sunjianhua.cn/archives/centos-nexus.html 1.下载 wget http://download.sonatype.com/nexus ...

  3. Protocol Buffer Basics: C#

    Protocol Buffer 基础知识:c#    原文地址:https://developers.google.com/protocol-buffers/docs/csharptutorial   ...

  4. Mysql select语句设置默认值

    1.在没有设置默认值的情况下: SELECT userinfo.id, user_name, role, adm_regionid, region_name , create_time FROM us ...

  5. Quartz 2.3.0 升级感受

    Quartz 2.3.0 发布,Quartz是一个开源的作业调度框架,它完全由Java写成,并设计用于J2SE和J2EE应用中.它提供了巨大的灵 活性而不牺牲简单性.你能够用它来为执行一个作业而创建简 ...

  6. 拦截器通过Spring获取工厂类,注入bean对象

    // 这里需要注意一点,我们在拦截器内无法通过SpringBean的方式注入LoggerJPA,我只能通过另外一种形式. /** * 根据传入的类型获取spring管理的对应dao * @param ...

  7. [Web 前端] React高级教程(es6)——(2)对于Refs最新变动的理解

    cp : https://blog.csdn.net/liwusen/article/details/53384561 1.什么是ReactJS中的refs 在React中组件并不是真实的 DOM 节 ...

  8. LINUX CentOS7安装字体库

    LINUX CentOS7安装字体库 2017年12月26日 17:06:07 q260996583 阅读数:4866更多 个人分类: linux   JAVA画图时常用到Font 类对象 这样的对象 ...

  9. [转]Nginx+mysql+php-fpm负载均衡配置实例

    转 : http://www.jbxue.com/article/7923.html 介绍一个nginx.mysql.php-fpm环境下配置负载均衡的例子,有需要的朋友,可以参考下. 系统环境如下: ...

  10. Table does not have the identity property. Cannot perform SET operation.

    Table   does not have the identity property. Cannot perform SET operation. 解决:   set IDENTITY_INSERT ...