Use of context class loader in AbstractApplicationServlet

Hi,

I would like to use vaadin as a shared lib, shared between different web apps - rather than copying the vaadin lib with every app.

That fails early, as the AbstractApplicationServlet on init tries to load the application class using (by default) its class loader rather than the Thread’s context class loader (which is the one of the web app that also holds the application class).

That said: Is there a lot of dangling dependencies in the vaadin lib. Dependencies to classes that may not be present, but if present will be loaded? Spring used that approach in the past. It means however that you can not really share it, as web apps may provide different actual dependencies (i.e. libs that the vaadin lib would bind to).

So, more specifically, has anybody tried using vaadin as a lib in, say, OSGi? Or as a shared lib in Tomcat?

Thanks,
Henning

To answer my own request:

It seems you can make it work using a custom class loader with Vaadin. In web.xml add


		<init-param>
			<param-name>ClassLoader</param-name>
			<param-value>test.ContextClassLoader</param-value>
		</init-param>

and create test.ContextClassLoader as a loader that delegates to the Thread’s context class loader:


public class ContextClassLoader extends ClassLoader {
	private ClassLoader targetLoader;
	
	public ContextClassLoader(ClassLoader p) {
		this.targetLoader = Thread.currentThread().getContextClassLoader();
		if (this.targetLoader==null) {
			throw new IllegalStateException("Cannot set up custom class loader: No context class loader set");
		}
	}

	public URL getResource(String name) {
		return targetLoader.getResource(name);
	}

	public InputStream getResourceAsStream(String name) {
		return targetLoader.getResourceAsStream(name);
	}

	public Enumeration<URL> getResources(String name) throws IOException {
		return targetLoader.getResources(name);
	}

	public Class<?> loadClass(String name) throws ClassNotFoundException {
		return targetLoader.loadClass(name);
	}
}

Of course, this class loader implementation has to on the same “class path” as the vaadin lib, not on the level of the application if that is in logical child loader (to where the vaadin lib resides).

It seems that Vaadin does not hold onto it though (for the application). And I didn’t test exhaustively.

As said, it would be the right thing to do to use the current thread’s context class loader anyway!

Thanks,
Henning

Which libraries are causing problems for you?

I believe the javax.servlet packages are the only ones that are always required, and they should be properly imported by the Vaadin OSGi manifest; at least some have been using Vaadin with OSGi. GWT is the other major dependency, but as the client side code has been compiled to JavaScript, I have not heard of it causing problems with OSGi.

Vaadin does in some cases load some other external classes:

  • if running as a portlet, some portlet API classes as well - and if on Liferay or GateIn, some Liferay/GateIn classes
  • if running the GAEApplicationServlet on Google App Engine, some GAE classes

However, these should not cause problems if you don’t use the parts of Vaadin that would require them, as long as your runtime environment is not too strict about checking dependencies of unused classes at startup time (I think some JBoss version is with the default settings).

For OSGi, there is also
this group
- looks dead to me now, but some of the older articles might be of interest. Then there is a wiki
tutorial
, a
list of links
as well as
this article
.

Just ran into this again. I think there is a misunderstanding here. I hope I made the case clearer in the bug description
http://dev.vaadin.com/ticket/9809
.

Thanks, Henning