首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态编译java类web项目

动态编译java类web项目
EN

Stack Overflow用户
提问于 2016-09-30 17:01:24
回答 3查看 1.2K关注 0票数 1

我正在开发一个web应用程序,在那里我可以导入一个java代码,编译并执行它。这个类可能有来自另一个库的一些导入,我将其添加到我的类路径中。将它作为桌面应用程序运行,它可以工作,但是在通配符9.0.2下运行,它找不到我的类路径库,所以我有错误要编译我的代码。

是否必须更改野蝇配置的任何设置?我尝试了我的代码与和不使用maven。

我使用这个库来编译我的代码,就像我说的,它使用像桌面这样的应用程序:https://github.com/trung/InMemoryJavaCompiler

错误:

代码语言:javascript
复制
13:44:57,686 ERROR [stderr] (default task-5) /br/com/project/webtest/service/CompileClass.java:2: error: package org.junit does not exist
13:44:57,686 ERROR [stderr] (default task-5) import static org.junit.Assert.*;
13:44:57,686 ERROR [stderr] (default task-5)                        ^
13:44:57,687 ERROR [stderr] (default task-5) /br/com/project/webtest/service/CompileClass.java:3: error: cannot find symbol
13:44:57,687 ERROR [stderr] (default task-5) import br.com.project.webtest.service.SeleniumService;
13:44:57,688 ERROR [stderr] (default task-5)                                               ^
13:44:57,688 ERROR [stderr] (default task-5)   symbol:   class SeleniumService
13:44:57,688 ERROR [stderr] (default task-5)   location: package br.com.project.webtest.service
13:44:57,689 ERROR [stderr] (default task-5) /br/com/project/webtest/service/CompileClass.java:4: error: package org.junit does not exist
13:44:57,689 ERROR [stderr] (default task-5) import org.junit.*;

错误消息将与所有其他导入库一起继续,然后是classformaterror:

代码语言:javascript
复制
13:44:57,751 WARNING [javax.enterprise.resource.webcontainer.jsf.lifecycle] (default task-5) #{testController.action()}: java.lang.ClassFormatError: Truncated class file: javax.faces.FacesException: #{testController.action()}: java.lang.ClassFormatError: Truncated class file

编辑:我添加了使用eclipse,在Webcontent/web/lib文件夹下,添加了我的库并右击,添加到构建路径。

编辑2:负责创建代码并获得结果的类:

代码语言:javascript
复制
package br.com.test;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class TestController {

    public void actionParent() {
        String javaCode = generateJavaCode();
        Class<?> compile = null;
        try {
            compile = InMemoryCompilerTest.compile(Thread.currentThread().getContextClassLoader(),
                    "br.com.project.webtest.service.CompileClass", javaCode);
            System.out.println("Worked: " + compile);
        } catch (Exception e) {
            e.printStackTrace();
        }           
    }

    public void actionClassLoader() {
        String javaCode = generateJavaCode();
        Class<?> compile = null;
        try {
            compile = InMemoryCompilerTest.compile("br.com.project.webtest.service.CompileClass", javaCode);
            System.out.println("Worked: " + compile);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static String readFile(String path, Charset encoding) throws IOException {
        byte[] encoded = Files.readAllBytes(Paths.get(path));
        return new String(encoded, encoding);
    }

    private static String generateJavaCode() {
        String java = "package br.com.project.webtest.service;\r\n" 
                    + "import static org.junit.Assert.*;\r\n"
                    + "public class CompileClass {\r\n" 
                    + " public CompileClass() {\r\n"
                    + "     System.out.println(\"Dynamically compiled\");\r\n"
                    + "     String text = \"Testing JUnit lib\";\r\n"
                    + "     assertEquals(\"Testing JUnit lib\", text);\r\n" 
                    + "     System.out.println(\"completed\");\r\n"
                    + " }\r\n" + "  public static void main(String[] args) {\r\n" 
                    + "     new CompileClass();\r\n"
                    + "     System.out.println(\"finish\");\r\n" 
                    + " }\r\n" 
                    + "}\r\n";

        return java;

    }

    public static void main(String[] args)  {
        TestController c = new TestController();
        c.actionClassLoader();
        c.actionParent();
    }

}

我创建了一个类,它扩展了lib并更改了:

代码语言:javascript
复制
public class InMemoryCompilerTest extends InMemoryJavaCompiler {
    static JavaCompiler javac = ToolProvider.getSystemJavaCompiler();

    public static Class<?> compile(ClassLoader parent, String className, String sourceCodeInText) throws Exception {
        SourceCode sourceCode = new SourceCode(className, sourceCodeInText);
        CompiledCode compiledCode = new CompiledCode(className);
        Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(sourceCode);
        DynamicClassLoader cl = new DynamicClassLoader(parent);
        ExtendedStandardJavaFileManager fileManager = new ExtendedStandardTest(
                javac.getStandardFileManager(null, null, null), compiledCode, cl);
        JavaCompiler.CompilationTask task = javac.getTask(null, fileManager, null, null, null, compilationUnits);
        boolean result = task.call();
        return cl.loadClass(className);
    }
}

public class ExtendedStandardTest extends ExtendedStandardJavaFileManager{

    protected ExtendedStandardTest(JavaFileManager fileManager, CompiledCode compiledCode, DynamicClassLoader cl) {
        super(fileManager, compiledCode, cl);
    }

}

xhtml:

代码语言:javascript
复制
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">

<h:head></h:head>
<h:body>

    <h:form>

        <h:commandButton action="#{testController.actionClassLoader()}" value="ClassLoader" />
        <h:commandButton action="#{testController.actionParent()}" value="Parent" />
    </h:form>
</h:body>
</html>

我测试了通过的家长类加载器,因为你认为,但也没有工作。

从main方法执行的第一个类"TestController“工作。

编辑:

我添加了以下代码,可以在其中使用我的库设置类路径:

代码语言:javascript
复制
// set the classpath
        List<String> options = new ArrayList<String>();

        options.add("-classpath");
        StringBuilder sb = new StringBuilder();
        URLClassLoader urlClassLoader = (URLClassLoader) parent;

        for (URL url : urlClassLoader.getURLs()) {
            sb.append(url.getFile()).append(File.pathSeparator);
        }
        options.add(sb.toString());

作为Java应用程序执行,它返回:

代码语言:javascript
复制
[-classpath, /C:/Users/dev/Automacao/workspace/test/build/classes/;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/InMemoryJavaCompiler-1.2.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/commons-io-2.5.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/client-combined-3.0.0-beta3-nodeps.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/commons-codec-1.10.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/commons-exec-1.3.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/commons-logging-1.2.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/gson-2.3.1.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/guava-19.0.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/hamcrest-core-1.3.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/hamcrest-library-1.3.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/httpclient-4.5.2.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/httpcore-4.4.4.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/httpmime-4.5.2.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/jna-4.1.0.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/jna-platform-4.1.0.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/junit-4.12.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/netty-3.5.7.Final.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/phantomjsdriver-1.3.0.jar;/C:/Users/dev/Automacao/workspace/test/WebContent/WEB-INF/lib/workspace_libs/cglib-nodep-3.2.4.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/annotations-api.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/catalina-ant.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/catalina-ha.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/catalina-storeconfig.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/catalina-tribes.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/catalina.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/ecj-4.3.1.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/el-api.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/jasper-el.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/jasper.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/jsp-api.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/servlet-api.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/tomcat-api.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/tomcat-coyote.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/tomcat-dbcp.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/tomcat-i18n-es.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/tomcat-i18n-fr.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/tomcat-i18n-ja.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/tomcat-jdbc.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/tomcat-jni.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/tomcat-spdy.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/tomcat-util-scan.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/tomcat-util.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/tomcat-websocket.jar;/C:/Program%20Files/Apache%20Software%20Foundation/Apache%20Tomcat%208.0.3/lib/websocket-api.jar;/C:/Users/dev/Automacao/workspace/libraries/JSF%202.2%20(Mojarra%202.2.0)/mojarra-2.2.0-FCS/lib/javax.faces.jar;]

作为webapplication应用程序执行:

代码语言:javascript
复制
[-classpath, /C:/Users/dev/Automacao/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/test/WEB-INF/classes/;/C:/Users/dev/Automacao/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/test/WEB-INF/lib/commons-io-2.5.jar;/C:/Users/dev/Automacao/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/test/WEB-INF/lib/InMemoryJavaCompiler-1.2.jar;/C:/Users/dev/Automacao/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/test/WEB-INF/lib/javax.faces.jar;]

我怎么能得到同样的结果?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-03 18:50:41

让它起作用。

我必须进行@NicolasFilotto提到的更改,以便在使用webapp时使用父类加载器。在此之后,对于JavaCompiler工作,由于我正在使用外部库,有必要像上次编辑时提到的那样传递我的类路径。基本上,代码更改为:

代码语言:javascript
复制
public static Class<?> compile(ClassLoader parent, String className, String sourceCodeInText) throws Exception {
        SourceCode sourceCode = new SourceCode(className, sourceCodeInText);
        CompiledCode compiledCode = new CompiledCode(className);
        Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(sourceCode);
        DynamicClassLoader cl = new DynamicClassLoader(parent);
        ExtendedStandardJavaFileManager fileManager = new ExtendedStandard(
                javac.getStandardFileManager(null, null, null), compiledCode, cl);

        // set the classpath
        List<String> options = new ArrayList<String>();

        options.add("-classpath");
        StringBuilder sb = new StringBuilder();
        Enumeration<URL> resources = parent.getResources("/");
        while (resources.hasMoreElements()) {
            URL url = resources.nextElement();
            sb.append(url.getFile()).append(File.pathSeparator);
        }

        options.add(sb.toString());

        // execute the compiler
        Boolean call = javac.getTask(null, fileManager, null, options, null, compilationUnits).call();
        if (call) {
            return cl.loadClass(className);
        }
        return null;
    }

使用通配符,我不得不将URLClassLoader urlClassLoader = (URLClassLoader) parent;更改为Enumeration<URL> resources = parent.getResources("/");

票数 1
EN

Stack Overflow用户

发布于 2016-10-03 19:47:52

@VictorBello我已经在动态装载机中实现了这些特性。甚至可以在运行时在动态装载机中包含Jar。

代码语言:javascript
复制
public void DynamicJarCodeTest() throws Exception {
    try {
        StringBuilder sourceCode = new StringBuilder();
        sourceCode.append("package org.dvare.dynamic;\n");
        sourceCode.append("import org.apache.commons.math3.Field;\n");
        sourceCode.append("public class SourceClass {\n");
        sourceCode.append("   public String test() { \n");
        sourceCode.append("   return \"inside test method\";\n");
        sourceCode.append("   }\n");
        sourceCode.append("}");


        DynamicCompiler dynamicCompiler = new DynamicCompiler();
        dynamicCompiler.setSeparateContext(true);
        dynamicCompiler.setUpdateContextClassLoader(false);

        dynamicCompiler.addJar(getClass().getClassLoader().getResource("commons-math3.jar"));
        dynamicCompiler.addSource("org.dvare.dynamic.SourceClass", sourceCode.toString());
        dynamicCompiler.build();

        Class aClass = Class.forName("org.apache.commons.math3.Field", false, dynamicCompiler.getClassLoader());
        Assert.assertNotNull(aClass);

        Class bClass = Class.forName("org.dvare.dynamic.SourceClass", false, dynamicCompiler.getClassLoader());
        Assert.assertNotNull(bClass);


    } catch (DynamicCompilerException e) {
        System.out.println(e.getErrorList());
    } catch (Exception e) {
        e.printStackTrace();
    }

}
票数 0
EN

Stack Overflow用户

发布于 2019-02-11 03:06:12

感谢@victor的伟大解决方案。我的解决方案如下:

  1. 需要将maven存储库中的所有jar复制到一个文件夹中,并使用应用程序分发该文件夹:

  1. 从它们中为javac生成类路径(愚蠢的方式):

  1. 从github复制InMemoryJavaCompiler代码源代码并重写: 公共类InMemoryCompilerTest扩展InMemoryJavaCompiler { 静态JavaCompiler javac = ToolProvider.getSystemJavaCompiler();公共静态Class编译(ClassLoader父、字符串className、字符串sourceCodeInText、字符串类路径)抛出异常{ SourceCode sourceCode =新SourceCode(className,sourceCodeInText);CompiledCode compiledCode =新CompiledCode(className);Iterable<?扩展ExtendedStandard(javac.getStandardFileManager(null,compilationUnits = Arrays.asList(sourceCode);DynamicClassLoader cl =新DynamicClassLoader(父级);ExtendedStandardJavaFileManager fileManager =新compilationUnits null,compiledCode,cl);//设置类路径列表选项=新ArrayList();options.add("-classpath");options.add(类路径);//执行编译器布尔调用= javac.getTask(null,fileManager,null,options,null,compilationUnits)fileManager();如果(调用){返回cl.loadClass(className);}返回null;} }
  2. 调用编译方法: 类testClass =testClass "com.namespace.here.ClassName",someCode,stringBuilder.toString();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39796527

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档