From: Marc P. <ma...@an...> - 2005-05-24 15:42:29
|
I'm off home now from work but I just had an idea I need to get down... The problem with both the Spring view implementation for WM and the WM JSP Taglib is that they can only access the ServletContext, and all the methods to access individual servlets are deprecated. Therefore we cannot be sure we can get to the servlets' classloader. However... we can access context attributes. So we could define a special WM context attribute such as "webmacro.template.classloader" - and anybody who wants to use these the taglib or Spring view can just make their servlet set this context attribute at startup to the servlet's ClassLoader. I can then make ServletContextBroker look for this magic value and use it if it is found, or default to the classloader that loaded WM if not. What do you think? Cheers |
From: Keats K. <ke...@xa...> - 2005-05-24 16:00:56
|
I don't like the "smell" of this. Why do you need it anyway? If you need the Servlet instance you can just use: (Servlet)pageContext.getPage() Anyway, I thought you didn't need to use the Servlet instance if you use the new Broker -- wasn't that the point? Keats Marc Palmer wrote: >I'm off home now from work but I just had an idea I need to get down... > >The problem with both the Spring view implementation for WM and the WM JSP >Taglib is that they can only access the ServletContext, and all the >methods to access individual servlets are deprecated. Therefore we cannot >be sure we can get to the servlets' classloader. > >However... we can access context attributes. So we could define a special >WM context attribute such as "webmacro.template.classloader" - and anybody >who wants to use these the taglib or Spring view can just make their >servlet set this context attribute at startup to the servlet's ClassLoader. > >I can then make ServletContextBroker look for this magic value and use it >if it is found, or default to the classloader that loaded WM if not. > >What do you think? > >Cheers > > > > |
From: Marc P. <ma...@an...> - 2005-05-24 18:49:24
|
Keats Kirsch wrote: > I don't like the "smell" of this. Why do you need it anyway? If you > need the Servlet instance you can just use: > > (Servlet)pageContext.getPage() Well: 1. is that always guaranteed to be the case 2. will it definitely be the same classloader as a servlet in the same webapp, and the same for all JSPs that use the taglib in that webapp? 3. it doesn't work from Spring views. 4. it requires a lazy init of the single-instance of WM. I have added this to the taglib code already, so that it can use ServletContextBroker. > Anyway, I thought you didn't need to use the Servlet instance if you use > the new Broker -- wasn't that the point? True, but you were the one who said there should be an option to load things from the servlet classpath :) The problem is you can't get WM to load context tools etc from the webapp classpath if you don't have the servlet classpath. I think my solution is neat, in an ugly way :( It's a quick and easy way to solve the problem, without violating any particular rules I know of. The other option would be to put the Servlet or its ClassLoader into a predefined JNDI naming context. Do you like that less, or more ;-( -- Marc Palmer wj...@wa... Wangjammers - Java, J2ME and Web Consultants ~ http://www.wangjammers.org/ |
From: Keats K. <ke...@xa...> - 2005-05-24 21:08:56
|
Marc Palmer wrote: > Keats Kirsch wrote: > >> I don't like the "smell" of this. Why do you need it anyway? If you >> need the Servlet instance you can just use: >> >> (Servlet)pageContext.getPage() > > > Well: > > 1. is that always guaranteed to be the case That's what the Java docs say. (Although I admit I don't know why they return it as an Object.) > 2. will it definitely be the same classloader as a servlet in the same > webapp, and the same for all JSPs that use the taglib in that webapp? It is the servlet that the page gets compiled into, so it should be fine. > 3. it doesn't work from Spring views. I don't know Spring, but don't you have access to the pageContext anywhere? > 4. it requires a lazy init of the single-instance of WM. I have added > this to the taglib code already, so that it can use ServletContextBroker. Or we could add a new constructor to WM ... >> Anyway, I thought you didn't need to use the Servlet instance if you >> use the new Broker -- wasn't that the point? > > > True, but you were the one who said there should be an option to load > things from the servlet classpath :) > > The problem is you can't get WM to load context tools etc from the > webapp classpath if you don't have the servlet classpath. Unless you add a new getBroker method ... or a new Broker. > I think my solution is neat, in an ugly way :( > > It's a quick and easy way to solve the problem, without violating any > particular rules I know of. > > The other option would be to put the Servlet or its ClassLoader into a > predefined JNDI naming context. Do you like that less, or more ;-( > I don't like either, but I can't say exactly why. It just seems to violate the KISS principle. It's a kludge that doesn't seem necessary. Keats |
From: Marc P. <ma...@an...> - 2005-05-25 08:37:21
|
> > Well: > > > > 1. is that always guaranteed to be the case > > That's what the Java docs say. (Although I admit I don't know why they > return it as an Object.) Actually I was thinking, it may be that getRequestDispatcher( pageContext.getServletConfig().getServletName()) would give us a dispatcher for the JSP that is loaded on the webapps classloader. I've changed the JSP taglib code to use pageContext().getPage().getClass().getClassLoader() for now. > > 3. it doesn't work from Spring views. > > I don't know Spring, but don't you have access to the pageContext > anywhere? PageContext is a JSP thing. The Spring view I have is native WM for Spring, although you can also (and I have) use the WM JSP taglib with Spring using the default JSP view. > > 4. it requires a lazy init of the single-instance of WM. I have added > > this to the taglib code already, so that it can use > ServletContextBroker. > > Or we could add a new constructor to WM ... I'll do it. I'm also refactoring my changes to make it so we can retain the detection of Servlet20/22 and still have this functionality to specify the classloader instead of the servlet. > > The problem is you can't get WM to load context tools etc from the > > webapp classpath if you don't have the servlet classpath. > > Unless you add a new getBroker method ... or a new Broker. Well you still can't do that unless you can reference the webapp's ClassLoader from somewhere reliably. > I don't like either, but I can't say exactly why. It just seems to > violate the KISS principle. It's a kludge that doesn't seem necessary. Well we'll need to see how this pans out. I'm still not sure how we can get access to the webapp classloader reliably (even with shared WM and/or Spring JARs) in Spring. RequestDispatcher might do it but again I'm not confident because you typically use Spring's generic DispatcherServlet (which delegates to controller classes) which could be loaded from a shared JAR so you probably wouldn't get the right classloader from it. Unless anyone else has any insights I think a servletContext attribute for the classloader is about the only option. ...hmmm although it might be possible to get a known bean application from the Spring bean factory, or the classloader used by the bean factory. Ugh this is all so ugly! The trouble is there's big scope to break existing classloading mechanisms if this isn't done right. |