# Deployers module

With re-writing the new application server Kernel from JMX based to POJO oriented, we also re-wrote the whole Deployer architecture which was also based on the old JMX MBeans. Let's first look at the new concepts and then do an example of each new change.

## StructureDeployers

Combined with the previously mentioned new VFS implementation we introduced a new kind of Deployer, the Structure Deployer. The purpose of Structure Deployer is to recognise the deployment type and prepare this information for the actual Deployers. There are already default implementations for standard types such as JAR, WAR, EAR and specific files. You can simply implement your own StructureDeployer or extend the AbstractStructureDeployer. Or you can use the declarative approach by defining your structure with an XML file - META-INF/jboss-structure.xml. This file will be automatically picked up by DeclarativeStructureDeployer. Let's now look at how to use one of the existing StructureDeployer implementations, write our own or use the declarative one.

This is how we can add our own new file support. This one defines that -spring.xml files are also treated as metadata files.

This is a simple implementation for our own deployment structure which holds metadata information in mydata directory and has Java classes in myclasses directory.

Here we simply write a plain XML file defining where to look for ... TODO

## Deployers

With the old style of JBoss Deployers, a single deployer implementation would handle all the processing for the matching top level deployment unit. This behaviour was completely changed in the new Deployers architecture. Here we have a new way of handling deployment unit, we call it an aspectized deployment, meaning that each deployer implementation does just one thing. This way it is easier to control how much it gets done and even easier to swap out the behaviour. But what is that one thing? We are all familiar with parsing, creating ClassLoaders, installing services, etc. So, basically any part of the previous deployment process, can be seen as a separate process, parsing the jboss-service.xml file, creating ServiceMetaData, setting up RepositoryCL and finally registring MBeans into the MBeanServer instance.

Let's see this aspectization in the listing below. This is a real example from the current Microcontainer beans deployment.

- Parsing Deployers
  - Turns XML into metadata model
  - e.g. my-beans.xml -> KernelDeployment
- ClassLoading Deployers
  - Creates classloaders from metadata
  - e.g. Uses the information from StructureDeployers
- Component Deployers
  - Splits complicated deployments into units
  - e.g. KernelDeployment -> BeanMetaDatas
- Real Deployers
  - Does the real work of deployment
  - e.g. BeanMetaData -> controller.install()

## Attachments

Before we start coding the new Deployers there is another concept that we still need to have a look at. What is the way to store the information between different deployers? We keep this information in so-called Attachments. There are two types of attachments, predetermined and transient. e.g. predetermined can be set by the ProfileService, while we would get the transient one's from parsing the XML file. You must be aware that a predetermined attachment overriddes a transient attachment. This is a simple API to get a hold of the Attachments reference from the underlying DeploymentUnit instance.

     public interface DeploymentUnit extends MutableAttachments
     {
     /**
     * Get all the metadata for the expected type
     *
     * @param <T> the type to get
     * @param type the type
     * @return a set of metadata matching the type
     * @throws IllegalArgumentException if the type is null
     */
     <T> Set<? extends T> getAllMetaData(Class<T> type);

     /**
     * Get the transient managed objects
     *
     * @return the managed objects
     */
     MutableAttachments getTransientManagedObjects();

     ...
     }

     public interface MutableAttachments extends Attachments
     {
     /**
     * Add attachment
     *
     * @param name the name of the attachment
     * @param attachment the attachment
     * @return any previous attachment
     * @throws IllegalArgumentException for a null name or attachment
     * @throws UnsupportedOperationException when not supported by the implementation
     */
     Object addAttachment(String name, Object attachment);

     /**
     * Add attachment
     *
     * @param <T> the expected type
     * @param name the name of the attachment
     * @param attachment the attachment
     * @param expectedType the expected type
     * @return any previous attachment
     * @throws IllegalArgumentException for a null name, attachment or expectedType
     * @throws UnsupportedOperationException when not supported by the implementation
     */
     <T> T addAttachment(String name, T attachment, Class<T> expectedType);

     /**
     * Add attachment
     *
     * @param <T> the expected type
     * @param attachment the attachment
     * @param type the type
     * @return any previous attachment
     * @throws IllegalArgumentException for a null name, attachment or type
     * @throws UnsupportedOperationException when not supported by the implementation
     */
     <T> T addAttachment(Class<T> type, T attachment);

     /**
     * Remove attachment
     *
     * @param name the name of the attachment
     * @return the attachment or null if not present
     * @throws IllegalArgumentException for a null name
     * @throws UnsupportedOperationException when not supported by the implementation
     */
     Object removeAttachment(String name);

     /**
     * Remove attachment
     *
     * @param <T> the expected type
     * @param name the name of the attachment
     * @return the attachment or null if not present
     * @param expectedType the expected type
     * @throws IllegalArgumentException for a null name or expectedType
     * @throws UnsupportedOperationException when not supported by the implementation
     */
     <T> T removeAttachment(String name, Class<T> expectedType);

     /**
     * Remove attachment
     *
     * @param <T> the expected type
     * @return the attachment or null if not present
     * @param type the type
     * @throws IllegalArgumentException for a null name or type
     */
     <T> T removeAttachment(Class<T> type);

     /**
     * Set the attachments
     *
     * @param map the new attachments a map of names to attachments
     * @throws IllegalArgumentException for a null map
     */
     void setAttachments(Map<String, Object> map);

     /**
     * Clear the attachments
     *
     * @throws UnsupportedOperationException when not supported by the implementation
     */
     void clear();

     /**
     * Get the number of changes that have happened.
     *
     * @return number of adds/removes that have happened since creation or
     * clearChangeCount.
     */
     int getChangeCount();

     /**
     * Reset the change count to zero.
     */
     void clearChangeCount();
     }

     public interface Attachments extends Serializable
     {
     /**
     * Get all the attachments
     *
     * @return the unmodifiable attachments
     */
     Map<String, Object> getAttachments();

     /**
     * Get attachment
     *
     * @param name the name of the attachment
     * @return the attachment or null if not present
     * @throws IllegalArgumentException for a null name
     */
     Object getAttachment(String name);

     /**
     * Get attachment
     *
     * @param <T> the expected type
     * @param name the name of the attachment
     * @param expectedType the expected type
     * @return the attachment or null if not present
     * @throws IllegalArgumentException for a null name or expectedType
     */
     <T> T getAttachment(String name, Class<T> expectedType);

     /**
     * Get attachment
     *
     * @param <T> the expected type
     * @param type the type
     * @return the attachment or null if not present
     * @throws IllegalArgumentException for a null name or type
     */
     <T> T getAttachment(Class<T> type);

     /**
     * Is the attachment present
     *
     * @param name the name of the attachment
     * @return true when the attachment is present
     * @throws IllegalArgumentException for a null name
     */
     boolean isAttachmentPresent(String name);

     /**
     * Is the attachment present
     *
     * @param name the name of the attachment
     * @param expectedType the expected type
     * @return true when the attachment is present
     * @throws IllegalArgumentException for a null name or expectedType
     */
     boolean isAttachmentPresent(String name, Class<?> expectedType);

     /**
     * Is the attachment present
     *
     * @param type the type
     * @return true when the attachment is present
     * @throws IllegalArgumentException for a null name or type
     */
     boolean isAttachmentPresent(Class<?> type);

     /**
     * Are there any attachments
     *
     * @return true if there are any attachments, false otherwise.
     */
     boolean hasAttachments();
     }

## Ordering

Since we are now familiar with attachments we can talk about the order of our Deployers. What would be the natural order of our Deployers? Probably the first thing it comes to our mind is a plain number ordering. Old and proven way to do the ordering. But since we waited to introduce the attachments before we talked about ordering there must be something better. We can define the order by simply providing the information about Attachment requirements / demands (inputs) and supplies (outputs). Let's explain this in more detail on the actual example.

             public MyDeployer()
             {
             setInputs(SomeMetaData1.class, SomeMetaData2.class);
             setOutputs(MyOutput.class);
             }

Here we can see that our MyDeployer depends on SomeMetaData1 and SomeMetaData2 instance attachments, and provides a further MyOutput instance attachment for next deployers to use. So any deployer that provides SomeMetaData1 and SomeMetaData2 instance attachments should be before our MyDeployer and any one that uses MyOutput instance attachment should be after.