web应用程序中的动态Java编译

web应用程序中的动态Java编译,java,dynamic,controller,compilation,Java,Dynamic,Controller,Compilation,我有一个不寻常的问题(嗯,我认为这是不寻常的)。我需要能够通过web接口上传未编译的Java源文件,并让接收控制器编译它,并在编译后的类上执行方法 我已经找到了一些方法-我可以上传文件,并成功编译它。但是,无论我尝试什么,我都无法加载(新)类定义并实例化它。我一直在抛出java.lang.ClassNotFoundException异常 这是我的密码 String fileName = patchFile.getFileItem().getName(); String f

我有一个不寻常的问题(嗯,我认为这是不寻常的)。我需要能够通过web接口上传未编译的Java源文件,并让接收控制器编译它,并在编译后的类上执行方法

我已经找到了一些方法-我可以上传文件,并成功编译它。但是,无论我尝试什么,我都无法加载(新)类定义并实例化它。我一直在抛出java.lang.ClassNotFoundException异常

这是我的密码

        String fileName = patchFile.getFileItem().getName();
    String fullName = "<package name>" + fileName.substring(0, fileName.indexOf("."));

    // instantiate the Java compiler
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    JavaFileManager fileManager = new ClassFileManager(compiler.getStandardFileManager(null, null, null));

    // load the uploaded files into the compiler
    List<JavaFileObject> files = new ArrayList<JavaFileObject>();
    files.add(new ByteArrayJavaFileObject(fullName, patchFile.getBytes()));

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

    options.add("-classpath");
    StringBuilder sb = new StringBuilder();
    URLClassLoader urlClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
    for (URL url : urlClassLoader.getURLs()) {
        sb.append(url.getFile()).append(File.pathSeparator);            
    }
    options.add(sb.toString());

    // execute the compiler
    compiler.getTask(null, fileManager, null, options, null, files).call();

    // instantiate the class (FAILS HERE)
    Object instance = fileManager.getClassLoader(null).loadClass(fullName).newInstance();

    // close the file manager
    fileManager.close();
但是没有运气

有人能解释一下吗

提前感谢,, 本

根据要求,这里是stacktrace

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ClassNotFoundException: com.sifourteen.papyrus.fabricators.patches.TestFormFabricator
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:119)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:109)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
root cause

java.lang.ClassNotFoundException: com.sifourteen.papyrus.fabricators.patches.TestFormFabricator
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1680)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1526)
    java.lang.Class.forName0(Native Method)
    java.lang.Class.forName(Class.java:247)
    com.sifourteen.papyrus.controllers.AdminController.patch(AdminController.java:152)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    java.lang.reflect.Method.invoke(Method.java:597)
    org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:119)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:109)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)

不确定它是否有效,但无论如何值得一试。试试这个:

Object instance = fileManager.getClassLoader(javax.tools.StandardLocation.CLASS_PATH).loadClass(fullName).newInstance();

类文件需要位于类路径中。(例如,-d WEB-INF/classes)

您有可以附加的类加载器失败的堆栈跟踪吗?“我一直在抛出java.lang.ClassNotFoundException异常。”发布异常堆栈跟踪会有所帮助。发布stacktrace。我自己应该想到的。谢谢。:)您似乎在暗示它在非webapp环境中运行良好。例如,只是一个带有
main()
方法的普通Java客户端应用程序。这是真的吗?如果没有,您是否对其进行了测试?毕竟,这绝对是一个类路径问题。无论如何,您可能会发现这个问题中的示例作为起点很有用:不,我没有将其作为客户端应用程序进行测试。如果我在这里找不到解决办法,这将是我的下一步。我之所以回避这一点,是因为在托管web环境中,类加载问题可能有点棘手,我想确保我是在“以此类推”地进行测试。这种事情在web应用程序环境中可能发生吗?我想我可能在某一点上遇到了安全问题……好吧,只是尝试了一下,得到了这个错误“处理程序处理失败;嵌套的异常为java.lang.NoClassDefFoundError:com/sifourteen/papyrus/factors/AbstractFactors(错误名称:com/sifourteen/papyrus/factors/patchers/TestFormFactors)”。很抱歉那没用。。。不过绝对值得一试。您试图编译的类的名称是
com.sifourteen.papyrus.factors.AbstractFactors吗?不,很抱歉,这也不起作用。虽然加载的类确实必须在类路径中(显然),但这是一个“内存中”编译。我甚至不知道编译后的类“要去哪里”。我只是假设我的自定义文件管理器能够找到它。所以你从internet复制了一些东西,但它不起作用。我不得不用谷歌搜索那个东西来理解你说的话,它是。。。不适合严重使用。它的玩具类加载器只适用于一个简单的类,而不依赖于任何其他类。是的,你抓住了我-多么尴尬。对我来说,复制和粘贴太自由了,真是罪有应得!当我回到这里检查是否有任何更新时,我刚刚追踪到了这个确切的问题。所以现在的问题是-我如何让我的FileManager使用一个类加载器,它将我的“标准”URL类加载器作为其父级?现在正在处理这个问题…我刚刚修复了这个问题-将URLClassLoader设置为由我的FileManager创建的类加载器的父级-瞧,修复了!我真是活该,复制粘贴,然后问一个愚蠢的问题。我将为你的答案打分。非常感谢您抽出时间回复。
Object instance = fileManager.getClassLoader(javax.tools.StandardLocation.CLASS_PATH).loadClass(fullName).newInstance();