Using the NetBeans Platform on the Server with Wicket on the Client
Ads by DZone
This is the Servlet Decorator:package it.tidalwave.netbeans.servlet;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.openide.util.Lookup;
public class NetBeansPlatformDecoratorServlet implements Servlet
{
private ServletConfig config;
private Servlet delegate;
public void init (final ServletConfig config)
throws ServletException
{
try
{
NetBeansPlatformUtils.boot(config.getServletContext());
}
catch (Exception e)
{
throw new ServletException(e);
}
final ClassLoader classLoaderSave = NetBeansPlatformUtils.installPlatformClassLoader();
try
{
this.config = config;
final String className = config.getInitParameter("netbeans.servlet.delegate");
final Class delegateClass = Thread.currentThread().getContextClassLoader().loadClass(className);
delegate = (Servlet)Lookup.getDefault().lookup(delegateClass);
if (delegate == null)
{
throw new RuntimeException("Can't lookup " + className);
}
delegate.init(config);
}
catch (Exception e)
{
throw new ServletException(e);
}
finally
{
Thread.currentThread().setContextClassLoader(classLoaderSave);
}
}
public ServletConfig getServletConfig()
{
return delegate.getServletConfig();
}
public void service (final ServletRequest req, final ServletResponse res)
throws ServletException, IOException
{
final ClassLoader classLoaderSave = NetBeansPlatformUtils.installPlatformClassLoader();
try
{
delegate.service(req, res);
}
catch (Exception e)
{
throw new ServletException(e);
}
finally
{
Thread.currentThread().setContextClassLoader(classLoaderSave);
}
}
public String getServletInfo()
{
return delegate.getServletInfo();
}
public void destroy()
{
final ClassLoader classLoaderSave = NetBeansPlatformUtils.installPlatformClassLoader();
try
{
delegate.destroy();
}
finally
{
Thread.currentThread().setContextClassLoader(classLoaderSave);
}
}
}
These are the main concepts:
- As usual for decorators, the behaviour is forwarded to a delegate.
- The decoration consists in setting the context class loader (Thread.currentThread().getClassLoader()) from the NetBeans Platform and restoring it at the end of the method call (taking care of using a finally block for safety). The details are implemented in the NetBeansPlatformUtils class, discussed below.
- The delegate instance is retrieved by asking it to the Lookup class, as usual for NetBeans Platform applications (this is why you had to declare all the relevant Servlets and Filters in META-INF/services as previously described). While the common idiom is to pass the class literal as argument (e.g. MyService s = Lookup.getDefault().lookup(MyService.class)), here we can't do that for two reasons: first, because we want the code to be universal, so the class name must be passed in a parameter ("netbeans.servlet.delegate"); and second, because we couldn't get the literal in any way, since it would be never available in the static compilation classpath (there are no good ways to have a .war statically include the Platform stuff; if you tried to extract the .jar files from the .nbm modules - which per se is a cumbersome approach - you would face possible ClassCastExceptions since you would have the same class available in both Tomcat and the Platform class loaders - remember that the same bytecode in two different classloaders is treated as two different classes).
- Last but not least, at the first invocation of a Servlet or Filter delegate you must initialize the Platform: that's the task of NetBeansPlatformUtils.boot().
Article Type:
How-to
- Login or register to post comments
- 10807 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)










Comments
harris goldstone replied on Fri, 2009/01/09 - 3:25pm
Fabrizio Giudici replied on Sun, 2009/01/11 - 7:12am
Hi Harris.
At the moment, the great advantage is for what concerns the tier of services and models, that is the business tier. It is something that can be best clarified by examples, and I'll post some in future here on DZone (also with other two "series" of posts about NetBeans Platform Idioms etc...); for the moment, take this small one: I have a Metadata infrastructure that allow to extract metadata from media (e.g. photos), eventually store them in a database, where they can be searched for. Every kind of metadata (EXIF, IPTC, whatever) is implemented by separate modules, as well as persistence in the database is enabled by just adding specific modules, without requiring any configuration. This means that I can easily satisfy different needs (blueMarine itself, blueOcean base, blueOcean as used by my customer, and hopefully other future customers) by just assembling different set of modules in specific custom platforms. This has been achieved mostly by means of the Lookup API (and in future I could use more the layer.xml facility). Most of this stuff could be used also by taking simple .jars as libraries out of the NetBeans Platform; but as the number of configurations increases, it is really important to have the capability of checking compatibilities and dependencies among modules. You could be always safe with a good testing, but in any case I appreciate when a static tool finds / prevents problems as early as possible. Furthermore, having the very same process for two different projects is a big time saver for me.
There are two different uses of the Platform that I'll evaluate soon. First is the "Event Bus" (based on "Central Lookup" by Wade Chandler) that I've talked about a few months ago; in blueMarine it introduces another great deal of decoupling that in the customer's project based on blueOcean I don't have yet. While the Event Bus as is works fine with a single user (it is a singleton), it must be adapted in the case of concurrency (it should be enough to write a variant based on ThreadLocal). Second is about the use of Nodes for a number of things, including dynamic generation of menus based on the functions that you have dynamically included in the current configuration. This is more sensible because of the cited potential problem with the AWT Thread, which would be a serious bottleneck on the server side.
aldobrucale replied on Mon, 2009/01/19 - 8:49am
org.netbeans.Mainfrom my module? It belongs to the Bootstrap module, but when I add this dependency and try to compile, the build system says that the module containing NetBeansPlatformUtils "is not a friend of<nb-platform-dir>/nbbuild/netbeans/platform9/lib/boot.jar".Fabrizio Giudici replied on Mon, 2009/01/19 - 9:08am
aldobrucale replied on Mon, 2009/01/19 - 11:22am
in response to: fabriziogiudici
Thank you Fabrizio, of course a module cannot boot the application that is supposed to load it!
I placed the servlet in a regular web project, now it works perfectly. Very interesting, thank you.