2011-12-07 60 views
0

这里是要求:Java EE应用程序的自定义类加载器编译

  1. 的Java EE Web应用程序(在Tomcat中)...
  2. 死的简单,只是JSP的,servlet和罐子 - 无框架...
  3. 没有什么需要重装,而不是服务器,没有背景,没有...

的想法,到目前为止,是延长WebappClassLoader(catalina.jar),以使自己的自定义类加载和它注册context.xml作为Loade r元素。通过一些代码,你可以很好地编写你的类加载器,如果需要,谁会知道在哪里可以找到Java源文件,然后将它们编译成类文件,然后在被要求时将它们加载到内存中。逻辑简单明了。

除外:

如何碧玉知道去哪里 - 自动地 - 找到你的班级,已经通过您的自定义类加载器生成的,所以它可以编译引用它们的JSP,甚至刷新它们(您类)在飞行?难以实现吗?

你觉得呢?

(请不要尝试通过指向那些照顾这样的事情对你无数的现有框架发散谈话的要求是非常特殊:没有框架,什么都没有)

+0

Jasper的文档规定:“**用于编译JSP页面的JDT ** - Eclipse JDT Java编译器现在用于执行JSP Java源代码编译,该编译器从容器类加载器中加载源依赖项,Ant和javac可以仍然被使用。“所以这个问题实际上涉及**“容器类加载器”**! –

+0

容器类加载器是“** org.apache.catalina.loader.StandardClassLoader **”的实例。它是**引擎的**类加载器。我没有看到任何明显的方式来覆盖/补充它以自动工作... –

回答

0

人们可以添加在当前的Web应用程序上下文类加载器(context.xml中):

<Context> 
    <Loader loaderClass = "gr.nevma.cccl.CompilingClassLoader"/> 
</Context> 

,然后创建一个类装载器:

package package gr.nevma.cccl; 

import ... 

public class CompilingClassLoader extends WebappClassLoader { 

    public CompilingClassLoader (ClassLoader parentClassLoader) { 

     super(parentClassLoader); 

    } 

    public Class<?> loadClass (String className, boolean resolve) throws ClassNotFoundException { 

     Class<?> theClass = null; 

     // Do you stuff here 
     return theClass; 

    } 

} 

但是,只有在想要通过调用ClassLoader :: loadClass(...)才能从类加载器本身显式加载类时,这只会有所帮助。这对Jasper的JSP编译没有帮助。这意味着,当Jasper尝试编译使用由该类加载器加载的类的JSP时,编译将失败,因为Jasper甚至不会要求该类加载器加载任何类。

因此,通过这种方式,可以实现类的自动加载和重新加载,但是可以通过手动方式实现。这些类可以在整个Web应用程序中统一使用,即JSP页面!

+0

似乎调用了WebappClassLoader的getResourceAsStream()方法来加载Jasper编译JSP页面所需的类。换句话说,当Jasper试图编译JSP页面时,它通过调用getResourceAsStream()来请求必要的类形成类加载器。所以这个方法需要被重写来动态加载任何需要加载的东西...... –

+0

为了能够加载并重新加载任何类(即“定义”它),必须删除并重新创建它的类加载器。换句话说,类加载器的一个实例只能加载(定义)一个类!如果类需要实际重新加载(再次定义),则必须为该作业创建新的类加载器,并删除旧类。 –

+0

当一个类加载器一次加载一个类时,似乎JVM再也不会从它那里请求这个类,至少不会像PermGen内存(类存储在RAM中)那样长。因此,为了能够重新加载类的定义,这使得不可避免地要删除并重新创建类加载器。这使得更加清楚的是,如果重载类的引用仍然悬而未决,那么加载它们的类加载器的实例将不会被垃圾回收。 –