动态编译,远端调用Windchill方法
2015-06-09 14:17
821 查看
import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.net.URI; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.tools.Diagnostic; import javax.tools.DiagnosticCollector; import javax.tools.FileObject; import javax.tools.ForwardingJavaFileManager; import javax.tools.JavaCompiler; import javax.tools.JavaFileObject; import javax.tools.SimpleJavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; import org.apache.log4j.Logger; import org.json.JSONArray; import wt.method.RemoteAccess; import wt.method.RemoteMethodServer; /** * 动态编译测试类. * @author wb_lixiang * @version V1.0 */ public class RemoteComplieUtil implements RemoteAccess{ private static Logger log = Logger.getLogger(RemoteComplieUtil.class); public static Object test(HttpServletRequest request) throws Exception { String classContent = StringUtil.notNull(request.getParameter("classContent")); String className = StringUtil.notNull(request.getParameter("className")); String methodName = StringUtil.notNull(request.getParameter("methodName")); String params = StringUtil.notNull(request.getParameter("params")); return remoteTest(classContent, className, methodName, params); } /** * 这里用一句话描述这个类的作用,简述. * <p> * 详细说明 * <p> * @param classContent * @param className * @param methodName * @param params * @return Object * @throws Exception */ public static Object remoteTest(String classContent, String className, String methodName, String params) throws Exception { if (!RemoteMethodServer.ServerFlag) { RemoteMethodServer r = RemoteMethodServer.getDefault(); Class[] cls = new Class[] {String.class, String.class, String.class, String.class}; Object[] obj = new Object[] {classContent, className, methodName, params}; Object result = r.invoke("remoteTest", "ext.higer.util.RemoteComplieUtil", null, cls, obj); return result; } else { return (new RemoteComplieUtil()).doTest(classContent, className, methodName, params); } } public Object doTest(String classContent, String className, String methodName, String params) { Class instanceClass = null; Object resultObj = null; if (!"".equals(classContent)) { try { DynamicEngine de = new DynamicEngine(); instanceClass = de.javaCodeToClass(className, classContent); } catch (Exception e) { e.printStackTrace(); log.error("", e); return e; } } if ("".equals(className) || "".equals(methodName)) { } else { try { Class[] classes = null; Object[] objs = null; ArrayList<Class> classesArray = new ArrayList<Class>(); ArrayList objsArray = new ArrayList(); try { JSONArray paramArrayJson = new JSONArray(params); if (paramArrayJson.length() > 0) { for (int i = 0; i < paramArrayJson.length(); i++) { String paramClassName = StringUtil.notNull(paramArrayJson.getJSONObject(i).getString("className")); if (paramClassName.endsWith("[]")) { paramClassName = paramClassName.substring(0, paramClassName.indexOf("[]")); Class paramClass = Class.forName(paramClassName); classesArray.add(Array.newInstance(paramClass, 1).getClass()); JSONArray o = (JSONArray) paramArrayJson.getJSONObject(i).get("value"); Object oo = Array.newInstance(paramClass, o.length()); for (int j = 0; j < o.length(); j++) { Array.set(oo, j, o.get(j)); } objsArray.add(oo); } else { classesArray.add(Class.forName(paramClassName)); objsArray.add(paramArrayJson.getJSONObject(i).get("value")); } } } } catch (Exception e) { e.printStackTrace(); log.error("", e); } if (classesArray.size() > 0) { classes = new Class[classesArray.size()]; for (int i = 0; i < classesArray.size(); i++) { classes[i] = classesArray.get(i); } } else { classes = new Class[] {}; } objs = objsArray.toArray(); try { if (null == instanceClass) { instanceClass = Class.forName(className); } Method method = instanceClass.getMethod(methodName, classes); resultObj = method.invoke(instanceClass.newInstance(), objs); } catch (Exception e) { e.printStackTrace(); e.printStackTrace(); log.error("", e); return e; } } catch (Exception e) { e.printStackTrace(); log.error("", e); return e; } } return resultObj; } public class ClassFileManager extends ForwardingJavaFileManager { public JavaClassObject getJavaClassObject() { return jclassObject; } private JavaClassObject jclassObject; public ClassFileManager(StandardJavaFileManager standardManager) { super(standardManager); } @Override public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) throws IOException { jclassObject = new JavaClassObject(className, kind); return jclassObject; } } public class DynamicClassLoader extends URLClassLoader { public DynamicClassLoader(ClassLoader parent) { super(new URL[0], parent); } public Class findClassByClassName(String className) throws ClassNotFoundException { return this.findClass(className); } public Class loadClass(String fullName, JavaClassObject jco) { byte[] classData = jco.getBytes(); return this.defineClass(fullName, classData, 0, classData.length); } } public class CharSequenceJavaFileObject extends SimpleJavaFileObject { private CharSequence content; public CharSequenceJavaFileObject(String className, CharSequence content) { super(URI.create("string:///" + className.replace('.', '/') + JavaFileObject.Kind.SOURCE.extension), JavaFileObject.Kind.SOURCE); this.content = content; } @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) { return content; } } public class JavaClassObject extends SimpleJavaFileObject { protected final ByteArrayOutputStream bos = new ByteArrayOutputStream(); public JavaClassObject(String name, JavaFileObject.Kind kind) { super(URI.create("string:///" + name.replace('.', '/') + kind.extension), kind); } public byte[] getBytes() { return bos.toByteArray(); } @Override public OutputStream openOutputStream() throws IOException { return bos; } } public class DynamicEngine { private URLClassLoader parentClassLoader; private String classpath; public DynamicEngine() { // 获取类加载器 this.parentClassLoader = (URLClassLoader) this.getClass().getClassLoader(); // 创建classpath this.buildClassPath(); } /** * @MethodName : 创建classpath * @Description : TODO */ private void buildClassPath() { this.classpath = null; StringBuilder sb = new StringBuilder(); for (URL url : this.parentClassLoader.getURLs()) { String p = url.getFile(); sb.append(p).append(File.pathSeparator); } this.classpath = sb.toString(); } private String compilePrint(Diagnostic diagnostic) { StringBuffer res = new StringBuffer(); res.append("Code:[" + diagnostic.getCode() + "]\n\r"); res.append("Kind:[" + diagnostic.getKind() + "]\n\r"); res.append("Position:[" + diagnostic.getPosition() + "]\n\r"); res.append("Start Position:[" + diagnostic.getStartPosition() + "]\n\r"); res.append("End Position:[" + diagnostic.getEndPosition() + "]\n\r"); res.append("Source:[" + diagnostic.getSource() + "]\n\r"); res.append("Message:[" + diagnostic.getMessage(null) + "]\n\r"); res.append("LineNumber:[" + diagnostic.getLineNumber() + "]\n\r"); res.append("ColumnNumber:[" + diagnostic.getColumnNumber() + "]\n\r"); return res.toString(); } public Class javaCodeToClass(String fullClassName, String javaCode) throws Exception { long start = System.currentTimeMillis(); // 记录开始编译时间 Class instanceClass = null; // 获取系统编译器 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); // 建立DiagnosticCollector对象 DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); // 建立用于保存被编译文件名的对象 // 每个文件被保存在一个从JavaFileObject继承的类中 ClassFileManager fileManager = new ClassFileManager(compiler.getStandardFileManager(diagnostics, null, null)); List<JavaFileObject> jfiles = new ArrayList<JavaFileObject>(); jfiles.add(new CharSequenceJavaFileObject(fullClassName, javaCode)); // 使用编译选项可以改变默认编译行为。编译选项是一个元素为String类型的Iterable集合 List<String> options = new ArrayList<String>(); options.add("-encoding"); options.add("UTF-8"); options.add("-classpath"); options.add(this.classpath); JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, options, null, jfiles); // 编译源程序 boolean success = task.call(); if (success) { // 如果编译成功,用类加载器加载该类 JavaClassObject jco = fileManager.getJavaClassObject(); DynamicClassLoader dynamicClassLoader = new DynamicClassLoader(this.parentClassLoader); instanceClass = dynamicClassLoader.loadClass(fullClassName, jco); } else { // 如果想得到具体的编译错误,可以对Diagnostics进行扫描 String error = ""; for (Diagnostic diagnostic : diagnostics.getDiagnostics()) { error = error + compilePrint(diagnostic); error = error.replaceAll("\n\r", "<br/>"); throw new Exception(error); } } return instanceClass; } } } 页面执行,调用JSP,直接调上边的方法
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <form target="result_iframe" action="remoteExcuteToolServlet.jsp" method="post" > <br> 内容:<textarea name="classContent" style="width:600;height:400;"></textarea> <br> 类名:<input name="className" style="width:600;"/> <br> 方法:<input name="methodName" style="width:600;"/> <br> 参数:<textarea name="params" style="width:600;"></textarea> <br> 参数格式:[{'className':'java.lang.String','value':'abc'},{'className':'java.lang.String[]','value':['a','b']}] <input type="submit" value="执行" /> </form> <br> <iframe id="result_iframe" name="result_iframe" style="width:800;height:400;" > </iframe> <br>
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统