在使用JAVA6动态编译时遇到的一个问题,动态编译方法已经写就。通过main方法调用的动态编译时,编译通过,并可以使用编译生成的类。但是,在Tomcat下调用同样的方法进行动态编译时,编译无法通过。其原因是找不到对应的包。因为动态生成的类中import了其他的一些类。我猜是tomcat的某些加载机制影响了动态编译过程,导致动态编译找不引用的类。请问各位,是否有方法解决?
问题补充:
补充代码:
参数 files是一个JavaFile类型的数组,其中包含了Java类的源文件
Java代码
public static Class[] complie(JavaFile[] files) throws Exception { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); //ClassLoader clsLoader=ToolProvider.getSystemToolClassLoader(); DiagnosticCollector diagnostics = new DiagnosticCollector (); MemoryFileManager filemanage = new MemoryFileManager(compiler .getStandardFileManager(diagnostics, null, null)); //MemoryFileManager filemanage = new MemoryFileManager(compiler //.getStandardFileManager(diagnostics, null, null)); //Log.info("Location/t"+filemanage.) ArrayList clsFiles=new ArrayList (); for(JavaFile file:files) { JavaFileObject clsfile = MemoryFileManager.makeSource(file .getFileName(), file.toString()); clsFiles.add(clsfile); Log.info("compile:"+file.getFileName()+"/t"+clsfile.getName()+"/t"+clsfile.getKind()+"/t"+clsfile.toUri()); } Iterable compilationUnits=clsFiles; JavaCompiler.CompilationTask task = compiler.getTask(null, filemanage, diagnostics, null, options.getClassNames(), compilationUnits); boolean success=false; try { success = task.call(); } catch (Exception e) { e.printStackTrace(); } Class[] clazz=new Class[files.length]; if(success) { for(int i=0;i
问题补充:
TOMCAT下的编译诊断信息:Java代码
- Code: compiler.err.doesnt.exist
- Kind: ERROR
- Position: 0
- Start Position: 0
- End Position: 0
- Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString
- Message: mfm:///RuntimeEntitySysUser.java:1: 软件包 com.youngor.dboperator 不存在
- Code: compiler.err.doesnt.exist
- Kind: ERROR
- Position: 104
- Start Position: 78
- End Position: 112
- Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString
- Message: mfm:///RuntimeEntitySysUser.java:4: 软件包 com.youngor.webcore.entity 不存在
- Code: compiler.err.doesnt.exist
- Kind: ERROR
- Position: 146
- Start Position: 124
- End Position: 156
- Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString
- Message: mfm:///RuntimeEntitySysUser.java:6: 软件包 com.youngor.dboperator 不存在
- Code: compiler.err.doesnt.exist
- Kind: ERROR
- Position: 202
- Start Position: 180
- End Position: 212
- Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString
- Message: mfm:///RuntimeEntitySysUser.java:9: 软件包 com.youngor.dboperator 不存在
- Code: compiler.err.doesnt.exist
- Kind: ERROR
- Position: 239
- Start Position: 213
- End Position: 251
- Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString
- Message: mfm:///RuntimeEntitySysUser.java:9: 软件包 com.youngor.webcore.entity 不存在
- Code: compiler.err.doesnt.exist
- Kind: ERROR
- Position: 0
- Start Position: 0
- End Position: 0
- Source: mfm:///RuntimeEntitySysPosition.java from JavaSourceFromString
- Message: mfm:///RuntimeEntitySysPosition.java:1: 软件包 com.youngor.dboperator 不存在
- Code: compiler.err.doesnt.exist
- Kind: ERROR
- Position: 108
- Start Position: 82
- End Position: 120
- Source: mfm:///RuntimeEntitySysPosition.java from JavaSourceFromString
- Message: mfm:///RuntimeEntitySysPosition.java:4: 软件包 com.youngor.webcore.entity 不存在
- Code: compiler.err.cant.resolve.location
- Kind: ERROR
- Position: 328
- Start Position: 328
- End Position: 337
- Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString
- Message: mfm:///RuntimeEntitySysUser.java:14: 找不到符号
- 符号: 类 EntitySet
- 位置: 类 RuntimeEntitySysUser
- Code: compiler.err.cant.resolve.location
- Kind: ERROR
- Position: 383
- Start Position: 383
- End Position: 392
- Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString
- Message: mfm:///RuntimeEntitySysUser.java:14: 找不到符号
- 符号: 变量 DefaultDB
- 位置: 类 RuntimeEntitySysUser
- Code: compiler.err.doesnt.exist
- Kind: ERROR
- Position: 436
- Start Position: 410
- End Position: 448
- Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString
- Message: mfm:///RuntimeEntitySysUser.java:14: 软件包 com.youngor.webcore.entity 不存在
- Code: compiler.err.cant.resolve.location
- Kind: ERROR
- Position: 619
- Start Position: 619
- End Position: -1
- Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString
- Message: mfm:///RuntimeEntitySysUser.java:16: 找不到符号
- 符号: 变量 super
- 位置: 类 RuntimeEntitySysUser
- Code: compiler.err.cant.resolve.location
- Kind: ERROR
- Position: 667
- Start Position: 667
- End Position: -1
- Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString
- Message: mfm:///RuntimeEntitySysUser.java:18: 找不到符号
- 符号: 变量 super
- 位置: 类 RuntimeEntitySysUser
Code: compiler.err.doesnt.exist Kind: ERROR Position: 0 Start Position: 0 End Position: 0 Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString Message: mfm:///RuntimeEntitySysUser.java:1: 软件包 com.youngor.dboperator 不存在 Code: compiler.err.doesnt.exist Kind: ERROR Position: 104 Start Position: 78 End Position: 112 Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString Message: mfm:///RuntimeEntitySysUser.java:4: 软件包 com.youngor.webcore.entity 不存在 Code: compiler.err.doesnt.exist Kind: ERROR Position: 146 Start Position: 124 End Position: 156 Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString Message: mfm:///RuntimeEntitySysUser.java:6: 软件包 com.youngor.dboperator 不存在 Code: compiler.err.doesnt.exist Kind: ERROR Position: 202 Start Position: 180 End Position: 212 Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString Message: mfm:///RuntimeEntitySysUser.java:9: 软件包 com.youngor.dboperator 不存在 Code: compiler.err.doesnt.exist Kind: ERROR Position: 239 Start Position: 213 End Position: 251 Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString Message: mfm:///RuntimeEntitySysUser.java:9: 软件包 com.youngor.webcore.entity 不存在 Code: compiler.err.doesnt.exist Kind: ERROR Position: 0 Start Position: 0 End Position: 0 Source: mfm:///RuntimeEntitySysPosition.java from JavaSourceFromString Message: mfm:///RuntimeEntitySysPosition.java:1: 软件包 com.youngor.dboperator 不存在 Code: compiler.err.doesnt.exist Kind: ERROR Position: 108 Start Position: 82 End Position: 120 Source: mfm:///RuntimeEntitySysPosition.java from JavaSourceFromString Message: mfm:///RuntimeEntitySysPosition.java:4: 软件包 com.youngor.webcore.entity 不存在 Code: compiler.err.cant.resolve.location Kind: ERROR Position: 328 Start Position: 328 End Position: 337 Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString Message: mfm:///RuntimeEntitySysUser.java:14: 找不到符号 符号: 类 EntitySet 位置: 类 RuntimeEntitySysUser Code: compiler.err.cant.resolve.location Kind: ERROR Position: 383 Start Position: 383 End Position: 392 Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString Message: mfm:///RuntimeEntitySysUser.java:14: 找不到符号 符号: 变量 DefaultDB 位置: 类 RuntimeEntitySysUser Code: compiler.err.doesnt.exist Kind: ERROR Position: 436 Start Position: 410 End Position: 448 Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString Message: mfm:///RuntimeEntitySysUser.java:14: 软件包 com.youngor.webcore.entity 不存在 Code: compiler.err.cant.resolve.location Kind: ERROR Position: 619 Start Position: 619 End Position: -1 Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString Message: mfm:///RuntimeEntitySysUser.java:16: 找不到符号 符号: 变量 super 位置: 类 RuntimeEntitySysUser Code: compiler.err.cant.resolve.location Kind: ERROR Position: 667 Start Position: 667 End Position: -1 Source: mfm:///RuntimeEntitySysUser.java from JavaSourceFromString Message: mfm:///RuntimeEntitySysUser.java:18: 找不到符号 符号: 变量 super 位置: 类 RuntimeEntitySysUser
Tomcat输出的异常信息:Java代码
- java.lang.NullPointerException
- at com.youngor.dboperator.EntityUtil.getInstance(EntityUtil.java:36)
- at com.youngor.dboperator.Entity.getInstance(Entity.java:103)
- at com.youngor.dboperator.SQLServer2000Adaptor.getEntitySetBySQL(SQLServer2000Adaptor.java:283)
- at com.youngor.dboperator.SQLServer2000Adaptor.getEntitySet(SQLServer2000Adaptor.java:220)
- at com.youngor.dboperator.InnerDBOperator.getEntitySet(InnerDBOperator.java:451)
- at com.youngor.dboperator.DBOperator.getEntitySet(DBOperator.java:350)
- at com.youngor.dboperator.DefaultDB.getEntitySet(DefaultDB.java:147)
- at com.youngor.dboperator.DefaultDB.getEntitySet(DefaultDB.java:213)
- at com.youngor.webcore.entity.SysUser.getEntitySet(SysUser.java:501)
- at com.youngor.webcore.entity.SysUser.doTest(SysUser.java:610)
- at org.apache.jsp.login_jsp._jspService(login_jsp.java:66)
- at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
- at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
- at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
- at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
- at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
- at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
- at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
- at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
- at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
- at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
- at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
- at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
- at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
- at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
- at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:857)
- at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:565)
- at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1509)
- at java.lang.Thread.run(Thread.java:619)
- java.lang.NullPointerException
- at com.youngor.dboperator.SQLServer2000Adaptor.getEntitySetBySQL(SQLServer2000Adaptor.java:284)
- at com.youngor.dboperator.SQLServer2000Adaptor.getEntitySet(SQLServer2000Adaptor.java:220)
- at com.youngor.dboperator.InnerDBOperator.getEntitySet(InnerDBOperator.java:451)
- at com.youngor.dboperator.DBOperator.getEntitySet(DBOperator.java:350)
- at com.youngor.dboperator.DefaultDB.getEntitySet(DefaultDB.java:147)
- at com.youngor.dboperator.DefaultDB.getEntitySet(DefaultDB.java:213)
- at com.youngor.webcore.entity.SysUser.getEntitySet(SysUser.java:501)
- at com.youngor.webcore.entity.SysUser.doTest(SysUser.java:610)
- at org.apache.jsp.login_jsp._jspService(login_jsp.java:66)
- at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
- at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
- at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
- at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
- at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
- at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
- at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
- at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
- at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
- at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
- at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
- at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
- at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
- at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
- at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:857)
- at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:565)
- at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1509)
- at java.lang.Thread.run(Thread.java:619)
java.lang.NullPointerException at com.youngor.dboperator.EntityUtil.getInstance(EntityUtil.java:36) at com.youngor.dboperator.Entity.getInstance(Entity.java:103) at com.youngor.dboperator.SQLServer2000Adaptor.getEntitySetBySQL(SQLServer2000Adaptor.java:283) at com.youngor.dboperator.SQLServer2000Adaptor.getEntitySet(SQLServer2000Adaptor.java:220) at com.youngor.dboperator.InnerDBOperator.getEntitySet(InnerDBOperator.java:451) at com.youngor.dboperator.DBOperator.getEntitySet(DBOperator.java:350) at com.youngor.dboperator.DefaultDB.getEntitySet(DefaultDB.java:147) at com.youngor.dboperator.DefaultDB.getEntitySet(DefaultDB.java:213) at com.youngor.webcore.entity.SysUser.getEntitySet(SysUser.java:501) at com.youngor.webcore.entity.SysUser.doTest(SysUser.java:610) at org.apache.jsp.login_jsp._jspService(login_jsp.java:66) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286) at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:857) at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:565) at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1509) at java.lang.Thread.run(Thread.java:619) java.lang.NullPointerException at com.youngor.dboperator.SQLServer2000Adaptor.getEntitySetBySQL(SQLServer2000Adaptor.java:284) at com.youngor.dboperator.SQLServer2000Adaptor.getEntitySet(SQLServer2000Adaptor.java:220) at com.youngor.dboperator.InnerDBOperator.getEntitySet(InnerDBOperator.java:451) at com.youngor.dboperator.DBOperator.getEntitySet(DBOperator.java:350) at com.youngor.dboperator.DefaultDB.getEntitySet(DefaultDB.java:147) at com.youngor.dboperator.DefaultDB.getEntitySet(DefaultDB.java:213) at com.youngor.webcore.entity.SysUser.getEntitySet(SysUser.java:501) at com.youngor.webcore.entity.SysUser.doTest(SysUser.java:610) at org.apache.jsp.login_jsp._jspService(login_jsp.java:66) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286) at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:857) at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:565) at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1509) at java.lang.Thread.run(Thread.java:619)
问题补充:
public static Class[] complie(JavaFile[] files) throws Exception 这个方法是用main(String[] args)方法测试成功。放到JSP页面中调用输错。错误信息已经在上面给出。
问题补充:
把com.youngor.*之类的类文件,放到tomcat下的common或shared下对应的classes或lib下,应该就不会报这个异常 或许可以解决问题。但是这不太符合Web应用部署的常规做法,不知“lovewhzlq”是否还有其他可行方法,不吝赐教。
问题补充:
问题基本解决,需要为编译过程指定编译的类路径;Java代码
- C:/myproject>javac -help
- 用法:javac <选项> <源文件>
- 其中,可能的选项包括:
- -g 生成所有调试信息
- -g:none 不生成任何调试信息
- -g:{lines,vars,source} 只生成某些调试信息
- -nowarn 不生成任何警告
- -verbose 输出有关编译器正在执行的操作的消息
- -deprecation 输出使用已过时的 API 的源位置
- -classpath <路径> 指定查找用户类文件的位置
- -cp <路径> 指定查找用户类文件的位置
- -sourcepath <路径> 指定查找输入源文件的位置
- -bootclasspath <路径> 覆盖引导类文件的位置
- -extdirs <目录> 覆盖安装的扩展目录的位置
- -endorseddirs <目录> 覆盖签名的标准路径的位置
- -d <目录> 指定存放生成的类文件的位置
- -encoding <编码> 指定源文件使用的字符编码
- -source <版本> 提供与指定版本的源兼容性
- -target <版本> 生成特定 VM 版本的类文件
- -version 版本信息
- -help 输出标准选项的提要
- -X 输出非标准选项的提要
- -J<标志> 直接将 <标志> 传递给运行时系统
C:/myproject>javac -help 用法:javac <选项> <源文件> 其中,可能的选项包括: -g 生成所有调试信息 -g:none 不生成任何调试信息 -g:{lines,vars,source} 只生成某些调试信息 -nowarn 不生成任何警告 -verbose 输出有关编译器正在执行的操作的消息 -deprecation 输出使用已过时的 API 的源位置 -classpath <路径> 指定查找用户类文件的位置 -cp <路径> 指定查找用户类文件的位置 -sourcepath <路径> 指定查找输入源文件的位置 -bootclasspath <路径> 覆盖引导类文件的位置 -extdirs <目录> 覆盖安装的扩展目录的位置 -endorseddirs <目录> 覆盖签名的标准路径的位置 -d <目录> 指定存放生成的类文件的位置 -encoding <编码> 指定源文件使用的字符编码 -source <版本> 提供与指定版本的源兼容性 -target <版本> 生成特定 VM 版本的类文件 -version 版本信息 -help 输出标准选项的提要 -X 输出非标准选项的提要 -J<标志> 直接将 <标志> 传递给运行时系统
修改部分代码如下:Java代码
- String cp=PathTool.get(AdvancedCompilerAPIDemo.class);
- Log.info(cp);
- int i=cp.indexOf("/WEB-INF/classes/");
- cp=cp.substring(0, i+17);
- Log.info(cp);
- Iterable options = Arrays.asList("-d", cp,"-cp",cp); // 编译选项,将编译产生的类文件放在当前目录下
- CompilationTask task = compiler.getTask(null, fileManager,
- diagnostics, options, null, sourcefiles);
String cp=PathTool.get(AdvancedCompilerAPIDemo.class); Log.info(cp); int i=cp.indexOf("/WEB-INF/classes/"); cp=cp.substring(0, i+17); Log.info(cp); Iterable options = Arrays.asList("-d", cp,"-cp",cp); // 编译选项,将编译产生的类文件放在当前目录下 CompilationTask task = compiler.getTask(null, fileManager, diagnostics, options, null, sourcefiles);
这里找到了WEb应用的classes目录并设置为编译输出目录和类路径。编译通过并可以使用了。那就得自己定义类加载器去加载com.youngor.*里面的类文件,而不是用tomcat默认的加载器去加载类,因为父加载器是不能加载子加载器下面的类文件的,