The contents of this document are a work in progress
Creating a Component 'Role'
If you browse through the sources generated by the Plexus component archetype used for preparing and setting up our project, you will see that we have:
- an Interface "HelloWorld.java" , and
- a Class "DefaultHelloWorld.java" which implements the interface in (1) above.
- a Component Descriptor "components.xml" located under project-root/src/main/resources/META-INF/
Components are registered with Plexus Container based on "ROLE" they can play or implement. If you look at the interface sources you will notice the ROLE specified by that interface. The class DefaultHelloWorld is the provider or concrete implementation of the interface HelloWorld. It can reside within the same JAR as the inteface or a different one. Think of ROLE as a key that can be used to query the Plexus Container for an implementation. The component descriptor, as the name implies, describes our component. We will revisit it again in later chapters but for the moment, know that the descriptor holds:
- the ROLE that the component implements or acts a provider for.
- the configuration for the component implementation.
When Plexus Container starts up, it uses Classworlds (the library that handles the classloading) to discover any Plexus components. It does this by looking for component descriptors (More on Component Descriptor here ) under standard location - META-INF/plexus.
That's enough to start tinkering with your website monitor component, so let's get our hands dirty! Identify a Component Role
Delete the .java files from the sources (under src/main and src/test ) that were generated by the archetype. The first thing we need to do is to identify a ROLE for our component - WebsiteMonitor.
public interface WebsiteMonitor { /** * Role used to register component implementations with the container. */ String ROLE = WebsiteMonitor.class.getName (); /** * Monitor the specified website. * * @param website * Website URL to monitor * @throws Exception * error encountered while performing the monitoring request. */ public void monitor(String website) throws Exception; }
Create provider for the Role
Lets create a bare-bones implementation of a provider for the component Role that we identified above and gradually flesh it out.
public class DefaultWebsiteMonitor implements WebsiteMonitor {
/*
* (non-Javadoc)
*
* @see org.codehaus.plexus.tutorial.WebsiteMonitor#monitor(java.lang.String)
*/
public void monitor(String website) throws Exception {
// TODO implement
}
}
Create a Component descriptor
Locate the component descriptor for our component provider under project-root/src/main/resources/META-INF/plexus/component.xml. Edit its content to reflect as below:
<component-set>
<components>
<component>
<role>org.codehaus.plexus.tutorial.WebsiteMonitor</role>
<implementation>
org.codehaus.plexus.tutorial.DefaultWebsiteMonitor
</implementation>
<configuration/>
</component>
</components>
</component-set>
Before we implement the the provider, we need to update our project dependencies and include Jakarta Commons HttpClient library. To do this, locate pom.xml under project-root and edit it to reflect the dependencies section of our pom.xml as below:
<dependencies>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-container-default</artifactId>
<version>1.0-alpha-9</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
Update Eclipse project dependencies for new library that we added above, to do this:
- Open up a command prompt window
- Change directory to the Website Monitor project's folder, and
- Run the following command to update the Eclipse project dependencies.
mvn eclipse:clean eclipse:eclipse
Refresh the Eclipse project in the workspace to reflect the updated dependencies.
We are now ready to start writing some unit tests for our (yet empty) component and drilling some useful implementation details into it!