2016-09-30 118 views
1

我正在開發一個web應用程序,我可以導入java代碼,編譯然後執行它。 這個類可能有一些從另一個庫中導入,我添加到了我的類路徑中。 運行它作爲桌面應用程序,它的工作原理,但運行在wildfly 9.0.2它沒有找到我的類路徑庫,所以,我有錯誤編譯我的代碼。編譯動態java類web項目

我是否必須更改野蠅配置上的任何設置?我嘗試使用和不使用maven的代碼。

我使用這個LIB編譯我的代碼,就像我說的,它使用像桌面應用程序的工作:https://github.com/trung/InMemoryJavaCompiler

錯誤:

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:

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-inf/lib文件夾下,添加我的庫並右鍵單擊,添加到構建路徑。

編輯2: 類負責創建的代碼,並得到結果:

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和改變使用父類加載器類:

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:

<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> 

我測試通過父類加載器,因爲你suge sted,但也沒有工作。

從main方法執行的第一個類「TestController」工作。

編輯:

我已經添加了下面的代碼,我可以用我的庫設置類路徑:

// 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應用程序,它返回:

[-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;] 

執行作爲web應用:

[-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;] 

我怎麼能得到相同的結果?

+0

你應該說明你如何將他們添加到您的類路徑 –

+0

@NicolasFilotto,編輯在運行時JAR。我像往常一樣添加。右鍵單擊添加構建路徑。我也嘗試使用maven。這些庫被導出到war項目中,但是在動態地嘗試編譯時找不到。 –

+0

請同時顯示您用於編譯 –

回答

1

讓它工作。

我必須做出@ @icolasFilotto提到的改變,以便在使用webapp時使用父類加載器。 之後,對於JavaCompiler的工作,因爲我使用外部庫,所以有必要像我上次編輯時提到的那樣傳遞我的類路徑。 基本上代碼更改爲:

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; 
    } 

使用wildfly我不得不改變URLClassLoader urlClassLoader = (URLClassLoader) parent;Enumeration<URL> resources = parent.getResources("/");

+0

這個解決方案對我來說就像一個魅力!謝謝!!我正在使用Apache Tomcat 8.我唯一需要修改的是刪除感嘆號「!」在每個類路徑的末尾。我不知道爲什麼,但在我的類加載器中排除了所有路徑。我做到了這一點:'url.replaceAll(「!」,「」);'追加到sb之前的字符串,它工作正常! – elfrasco

0

@VictorBello我已經在Dynamic Loader實現這些功能。即使您可以在Dynamic Loader

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

謝謝你的回答@Hammad,但是我無法使用你的庫得到這個工作。我只是改變了我的例子的「addSource」和「sourceCode」,我得到錯誤:'[{kind = ERROR,line = 4,message = package org.junit does not exist},{kind = ERROR,line = 9 ,message =找不到符號 symbol:方法assertEquals(java.lang.String,java.lang.String) location:class br.com.project.webtest.service.CompileClass}]'。我也嘗試添加我的lib文件夾內的jar,但無法工作。 –

+0

看到這一行 package'org.junit'不存在意思是找不到junit依賴關係 在你的構建路徑中包含junit依賴關係或者使用add jar從庫中添加jar – Hammad

+0

我明白錯誤,問題在於junit lib是包括在我的buildbath中,我得到了這個錯誤。 –