apache 编译java,动态编译java类Web项目

I'm developing a web application where I can import a java code, compile and then execute it.

This class might have some imports from another libraries, which I added to my classpath.

Running it as a desktop application, it works, but running under wildfly 9.0.2 it doesn't find my classpath libs and so, I have errors to compile my code.

Do I have to change any setting on wildfly configuration? I tried my code with and without maven.

I'm using this lib to compile my code, and like I said, it worked using the app like desktop: https://github.com/trung/InMemoryJavaCompiler

Errors:

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.*;

The error messages continues with all others import libs

and then, the 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

Edit:

I added using eclipse mars, under the Webcontent/web-inf/lib folder, added my libs and right click, add to build path.

Edit 2:

Class responsible for creating the code and get the result:

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();

}

}

I created a class which extends the lib and changed use parent classloader:

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:

I tested passing parent classloader as you sugested but also didnt work.

The first class "TestController" executing from main method it works.

Edit:

I have added the following code where I can set the classpath with my libs:

// set the classpath

List options = new ArrayList();

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());

Executing as a Java application it returns:

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

Executing as webapplication:

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

How could I get the same result?

解决方案

Get it working.

I have to make that change mentioned by @NicolasFilotto, to use parent classloader when using a webapp.

After that, for JavaCompiler works, as I'm using external libraries it's necessary to pass my classpath like mentioned on my last edit.

Basically the code changed to:

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 options = new ArrayList();

options.add("-classpath");

StringBuilder sb = new StringBuilder();

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

}

Using wildfly I had to change URLClassLoader urlClassLoader = (URLClassLoader) parent; to Enumeration resources = parent.getResources("/");

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值