dev@glassfish.java.net

Sniffer.getAnnotationTypes API

From: Hong Zhang <Hong.Zhang_at_Sun.COM>
Date: Tue, 15 Jul 2008 13:28:24 -0400

As this topic seems to generate some interest in today's v3 engineering
meeting, I am starting a thread to collect comments/feedback on this.

GlassFish v3 uses a Sniffer concept to study deployment request's
artifacts and elect the associated container that handle the application
type the user is trying to deploy. Such sniffer code can be as simple as
looking for a specific file in the application's archive (presence of
WEB-INF/web.xml), or as complicated as running some annotation scanner
to determine an XML-less archive (for example, EJB component annotations
in a .jar file).
For more details, see the container SPI document:
http://wiki.glassfish.java.net/Wiki.jsp?page=ContainerSPI.

So far we have implemented the simple mechanisms to looking for a
specific file in the archive through the Sniffer.handles method. We also
need to implement the more complicated mechanism of looking for certain
annotations. The Sniffer.getAnnotationTypes implementation will provide
a list of the annotations that this Sniffer is interested in. For
example, EJB Sniffer's implementation for this API will return
{Stateless.class, Stateful.class, MessageDriven.class, Singleton.class}.

    /**
     * Returns the list of annotations types that this sniffer is
interested in.
     * If an application bundle contains at least one class annotated with
     * one of the returned annotations, the deployment process will not
     * call the handles method but will invoke the containers deployers
as if
     * the handles method had been called and returned true.
     *
     * @return list of annotations this sniffer is interested in or an
empty array
     */
    public Class<? extends Annotation>[] getAnnotationTypes();


And then in the SnifferManager code where we decide which sniffers we
should retrieve for this application archive, we would scan the archive
for all annotations types registered through the available sniffers and
return the applicable sniffers. The current SnifferManager only calls
the handles method. It will also need to take consideration of the
annotations.

    /**
     * Returns a collection of sniffers that recognized some parts of the
     * passed archive as components their container handle.
     *
     * If no sniffer recognize the passed archive, an empty collection is
     * returned.
     *
     * @param archive source archive abstraction
     * @param cloader is a class loader capable of loading classes and
resources
     * from the passed archive.
     * @return possibly empty collection of sniffers that handle the passed
     * archive.
     */
    public Collection<Sniffer> getSniffers(ReadableArchive archive,
ClassLoader cloader) {

        List<Sniffer> appSniffers = new ArrayList<Sniffer>();
        for (Sniffer sniffer : getSniffers()) {
            if (sniffer.handles(archive, cloader )) {
                appSniffers.add(sniffer);
            }
        }
        return appSniffers;
   }

The current plan is to use the open source ASM tool to the scan the
archive for the registered annotations. Please let us know if you have
any comments/feedback on this.

Thanks,

- Hong