动态编译,远端调用Windchill方法

本文深入探讨了一种动态编译测试类,通过远程调用实现复杂功能的执行,包括类加载、方法调用及参数解析,旨在简化跨平台应用的开发流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值