一、问题

  动态编译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. springMVC helloworld入门

    一.SpringMVC概述与基本原理 spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦 ...

  2. 怪奇物语第二季/全集Stranger Things迅雷下载

    Netflix的叫好叫座剧<怪奇物语 Stranger Things>第二季更新上线日期为美国时间10月27日,第二季讲述在1984年(相隔上季一年),印第安纳州的Hawkins镇市民仍然 ...

  3. Chocolatey 简介(软件自动化管理工具)

    一.Chocolatey 管理Windows软件的明智方法 1.建立在技术的无人值守安装和PowerShell.建立在技术的无人值守安装和PowerShell. 2.轻松管理Windows软件的所有方 ...

  4. Excel 2016 Power View选项卡不显示的问题

    https://zhuanlan.zhihu.com/p/43543442 PowerView是Excel中的Power系列插件之一,可以基于excel制作交互式仪表板. 初学者在使用Power Vi ...

  5. 聊一聊Spring中的线程安全性

    Spring作为一个IOC/DI容器,帮助我们管理了许许多多的“bean”.但其实,Spring并没有保证这些对象的线程安全,需要由开发者自己编写解决线程安全问题的代码. Spring对每个bean提 ...

  6. NLP的神经网络训练的新模式

    https://blog.csdn.net/jdbc/article/details/53292414 该模式分为:embed.encode.attend.predict四部分.

  7. Go语言之进阶篇http服务器获取客户端的一些信息

    1.http服务器获取客户端的一些信息 示例: package main import ( "fmt" "net/http" ) //w, 给客户端回复数据 / ...

  8. knockout 多值绑定

    knockout 这种东西现在已经很流行了,相信很多人对它的使用都已经很熟悉了,最近项目开发中发现knockout 绑定用的有些不怎么充分,发现整个page的code 有点累赘. 1.在绑定click ...

  9. Easyui1.3.4+IIS6.0+IE8兼容问题解决

    刚刚学习JQuery Easyui,就遇到了拦路虎,最新版本1.3.4下载下来部署到win2003 + IIS6.0中发现所有demo都不可以渲染,IE8提示错误如下: 详细内容如下: 用户代理: M ...

  10. 如何让我domain里的机器都跟domain controller的时间保持一致?

    貌似是应该先在PDC上设一个时间源服务器, 然后, 再让domain里所有的机器都去与PDC去sync时间即可. 可是笔者的环境里, 怎么都配不同, 我觉得可能是实验室的网络有什么特别的设置吧. 不管 ...