Mark Thomas wrote: > Ate Douma wrote: > > When Pluto needs to "aggregate" the content of this TestPortlet, it > > invokes it render(PortletRequest, PortletResponse) method using a > > "cross-context" call from the Pluto web application to the "test" web > > application. > > The TestPortlet.render method receives the PortletRequest object (as > > loaded from the Pluto WEB-INF/lib) and invokes its > > PortletRequest.getPortletPreferences() method. If the PortletPreferences > > class hasn't been accessed yet before, this will cause the ClassLoader > > of PortletRequest, being the Pluto webapp ClassLoader, to now load the > > PortletPreferences class. > > But, because the current ContextClassLoader is the "test" webapp > > ClassLoader, LogFactory will lookup the logger implementation from the > > "test" webapp... > > With as result that logging output for the PortletPreferences class will > > end up in the target as specified by the "test" webapp, not in the one > > (as expected) as configured for the Pluto webapp.
So, basically, the PortletRequest needs to see the ClassLoader for the context in which it was created, rather than the one for the context in which it is used? I think this can be achieved without changing the behavior of LogFactory, and in a way that provides the same benefit to any other classes that depend on the context ClassLoader to find resources. (See below and attached.) > I have seen similar issues in Tomcat's internal logging with > java.util.logging, log4j and commons-logging. Why will this be any > different with slf4j? > > > The only possible workaround I could come up with was extending > > LogFactory itself and temporarily switching/enforcing the current > > ContextClassLoader to that of the class itself, but obviously we didn't > > even consider that as a real option. > > In Tomcat, the issue was (mainly) log objects for internal components > being created and loaded by a web application class loader. This was a > particular issue for Jasper, the JSP engine, as it interacts quite > closely with web apps. We solved this by ensuring that the logs were > created during Tomcat start. I think the case of the server's internal classes is a bit different from the cross-context case, in part because the a web application's (portlet application's) expectations of its environment are largely defined by the servlet (and portlet) spec, whereas the server's internal classes are whatever the server needs. That doesn't necessarily mean they need different solutions, but there are some solutions that are viable for the server that the server may not be reasonably demand of webapps. I think there is a better solution for cross-context, which may also have some use for internal server classes: instead of subclassing LogFactory or any class of an external component, wrap the servlet / portlet spec objects in dynamic proxies that manage the context switch on method invocation and return. As long as the wrapped objects are specified by Java interfaces, the java.lang.reflect.Proxy class makes this pretty easy -- you don't even need different methods or classes to handle it for different interfaces. As long as the cross-context invocation is mediated by the server, web / portlet applications would not need to do anything special -- the server could ensure that the objects belonging to one webapp would always see the appropriate context classloader for that context. See attached sample code for a class that would support this behavior. John
--------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org