做法1:以Eclipse为启动点,将appserver做为一个应用启动。
做法:
在Launcher 当中启动Eclipse Platform。此处的ClassLoader 为系统的loader。
Eclipse Platform 会查找到Core Application,并且将其启动。
在Core Application 当中,ClassLoader 为 Eclipse 的 ClassLoader。
在Core Application 当中,我们启动Jetty,并处于等待状态。
当Servlet/JSP被调用时,Jetty 将Servlet/JSP初始化,并执行相应动作。
Servlet 的 ClassLoader 是 Context ClassLoader,符合Servlet 规范的。
曾经碰到的问题:
Core Application采用的是Eclipse ClassLoader,缺省情况下,该ClassLoader 的 parent 为 null。这样,在Servlet ClassLoader 当中,能够接触到System ClassLoader,但是Core Application 不能访问,它们相互间不可见。
解决办法:EclipseStarter 有个配置项叫做parent.Classloader,将其设置为app,即可解决该问题。
Servlet ClassLoader按照Servlet 2.3的规范,首先由Context ClassLoader去查找,如果找不到,再交由parent 去load。而当时我在webapp/WEB-INF/lib目录下放了一个runtime.jar文件。这样,runtime.jar当中的类都被Context ClassLoader给装载进来了,而对于EclipseStarter当中装载的runtime.jar中的类互相不可见,从而也出现问题。
解决办法:把lib目录下的runtime.jar删除就好了。
由于所有的与eclipse有关的内容,只能由Core Application 的ClassLoader才能装载,因而相互间是可见的。从而达到了利用eclipse核心的目的。
做法2:以app server 为启动点,以eclipse 核心为web app的核心:
和做法1一样,重点是将Core Application的ClassLoader设置为System的loader,这样,在其他的地方(例如Servlet当中)也同样可见了。
很重要:runtime.jar和osgi.jar一定要放在jetty的启动路径当中。这样才会用System的loader 首先找到这两个jar文件,从而保证大家都在这个基础上来互相看到。
做法3:以Eclipse为启动点,将appserver做为一个应用启动,appserver以dispatcher身份出现。
这个做法和做法1一致。区别在于,appserver 本身不做任何事情,只是做为一个 dispatcher 出现。它提供一个 extension point,其他插件扩展该 extension,相当于注册 servlet,以及mapping。当有http request 时,dispatcher根据 servlet 的注册和mapping,自动的分发给对应的servlet。此时,各个servlet的 class loader 还是 eclipse classloader,而 servlet 的 context classloader 在这种模式当中只是昙花一现,做了一个 dispatcher 之后,就将工作移交给了定义serlvet 的插件的那个 eclipse classloader。
这样,servlet 是可扩展的,再也不依赖于 web.xml了。
主站:
http://blogsite.3322.org/jspwiki/