Putting it all together and sticking it on a noteboard
The noteboard application enables members of any Workplace application to
post simple notes to a board that are visible to other application users. The notes record
the identity of the poster, a note t
itle, the date posted, and the note itself. Notes may be
deleted by the poster of the note or the administrator of the Team Space. Each instance
of the noteboard has its own private data. The following two lists show features that the
will and will not have.
The component is a Workplace business component with instance
specific data and
the following requirements:
Create notes visible to all members of an application.
View any note in an application.
Allow the poster to delete his/h
er own notes and the application administrator to
delete all notes.
Use the Lotus Workplace API Toolkit sample application to shorten development
What this component will not do that is beyond the scope of the article:
Use a UI technology that wor
ks for all platforms and client
Persist to a database or any permanent backing storage. Our storage is in
Implement proper ACLs to protect the in
Localize all strings for UI resource.
Be used for JUnit testing.
simple mockup of what the main component may look like within a Team Space
is shown in Figure 1.
Figure 1. Sample view of the main component
When the user clicks the New Note button, he is brought to a new page to enter
the note title and details as shown in Figure 2.
Figure 2. Posting a New Note
This is simple and straightforward. Of course, applications are not always this
simple, but this application is sufficient to demonstrate the important concepts of the
Before reading any further, we recommend that you read
part 1 (
IBM Workplace application
development: IBM Workplace as a collaborative application framework
) and part 2 (
IBM Workplace application development: IBM
Workplace programming model
) if you haven't already. This article is intended for experienced
J2EE application developers.
Component design and IBM Workplace integration
First, we'll see how
the collaborative APIs apply to our business component. The
component diagram showing the four tiers recommended by the business component
reference architecture from part 2 of the series is illustrated in Figure 3. Notice how
Noteboard API appears twice i
n the diagram, which is intentional. The methods
available at the workspace and service layers are identical except that the delegate API
in the Workspace tier does not throw RemoteException even if, strictly speaking, this is
not perfect UML. Using identi
cal signatures for Delegate and Service tiers allows a
complete delegate to hide the difference between local and remote interfaces as
well as implement retry logic for RemoteExceptions if necessary. In our implementation,
we use remote interfaces
only for simplicity and not retrying after failures.
Figure 3. Component diagram of the simple noteboard
The class diagram, as you would
expect, is not very complex. (See Figure 4.)
Figure 4. Class diagram of the simple noteboard
Setting up the sample application
extend the sample application, import it into a clean Workspace in
WebSphere Studio Application Developer 5.1.2 with the Portlet Toolkit 18.104.22.168. We use
the Windows platform as a development platform, but you can use any supported
platform. We will keep t
he modifications as simple as possible while making the
application unique. The first step, of course, is to import the six projects of the existing
sample application, which on this developer's machine are stored in
Open the Java perspective.
Select the "Existing Project into Workspace" option.
Import one project from D:
Repeat steps 2
4 until all projects are imported.
After import, the packa
ge explorer pane should look like Figure 5.
Figure 5. Package explorer after sample application import
There are a number of compilation err
ors, which are related mainly to paths, that
must be fixed. The first is LWPAPI_HOME. Set the variable by following these steps:
Classpath Variables in the left pane.
Click New in the right panel.
Enter LWPAPI_HOME as the Name and D:/lwpapi10 as the Path as shown in
Figure 6. Entering a new Classpath variable
The second error is related to WAS_HOME which is the root directory to which
WebSphere and IBM Workplace are installed. If you have a server running
development machine, simply create a new variable like you did for LWPAPI_HOME
and point to it.
Running both IBM Workplace and WebSphere Studio Application Developer
on the same machine is very expensive for both CPU and memory usage, so it is
to copy required files to a local directory.
Here are the required contents as copied from a Workplace server:
After you copy the files, create a WAS_HOME variable and point it to
D:/Websphere as though the server was installed on the local machine. This brin
gs us to
the final errors: missing portlet JAR files. Different versions of Websphere Portal store
their JAR files in different locations, so the sample application includes all the possible
paths, resulting in build errors on a normal machine. We need to
delete the references to
the missing JAR files.
click CollabComponentPortlet and select properties.
Select Java Build path in the left pane and open the Libraries tab.
The three missing libraries will have a small exclamation point ( ! ) icon beside
them as seen in Figure 7.
Figure 7. Lib
raries with the three missing JARS included
Select the three missing JAR files and click Remove. The sample application will
now build fu
Extending the sample application
Now that the application builds correctly, it is time to extend it. We build this
from the Resource tier up.
The Resource tier
In the API sample application, a fake Resource tier is included in
re the collaboration API lifecycle takes place. To make the
division of the tiers clearer, we create a new project called CollabComponentResource.
The move also makes some classloader issues a bit easier to deal with and avoids our
beans depending upon eac
h other for code. When a large number of beans are involved,
beans depending upon each other for code can seem confusing and should be avoided.
When we are finished, the Resource tier stores notes in
memory using two HashMaps.
The first HashMap stores refe
rences to application instances. Each application instance
stores a HashMap of notes. Fortunately, the sample application is easily extended to
support that. However, there is an obvious downside. As our persistence is in
only, a server restart or a
n EAR restart purges all instance information from the server,
which means that the noteboard application has to behave correctly when all its data
In the sample API application, the class
implements the collaborative API and has an inner class called
BusinessComponentInstance that stores all the information specific to an instance such
as creation date, modification date, and the application data. Because we nee
instance data in more than one place, it is best to make BusinessComponentInstance a
alone class and to move CollabComponentResourceTierEmulation,
BusinessComponentInstance, and a required class TestConstants to a separate project.
To help pers
onalize, we rename the sample API classes to NoteboardInstance,
NoteboardResource, and NoteboardConstants respectively using the WebSphere Studio
Application Developer refactoring tool (right
click Class, select Refactor and Rename).
The steps to perform t
Create a new project called CollabComponentResource.
Create the package com.ibm.workplace.app.component.resource.
click TestConstants and CollabComponentResourceTierEmulation, then
select Refactor and Move. Move it to the CollabComp
This will fail to build, so edit the classpath properties for
CollabComponentResource and add the same LWPAPI_HOME and WAS_HOME
references from CollabComponentEJB to the project.
Edit the project references for CollabComponentE
JB and add
CollabComponentResource as a reference.
Edit the CollabComponentResourceTierEmulation and make the removeInstance()
click CollabComponentResourceTierEmulation, then select Refactor and
Rename. When renaming, make sure
all references are updated as shown in Figure 8.
Figure 8. Renaming a class
Rename TestConstants to NoteboardConstants.
Create a new p
ublic class called BusinessComponentInstance that extends
NoteboardConstants and uses the same imports as NoteboardResources. Use the code
from NoteboardResource's inner class, but make getContextData() public.
NoteboardResource should no longer use an inn
Rename BusinessComponentInstance to NoteboardInstance, making sure to update
all references in the refactoring tool. The project explorer should look like the view in
Figure 9. Project explorer after creating CollabComponentResource
Add CollabComponentResource as a project reference to CollabComponentEAR.
Without this, the EAR export later will not include the resource JAR fil
e and will result
in runtime exceptions related to classes not being found.
To represent the Notice class, we need Data Transfer Objects (DTO), our service
EJB tier APIs and exceptions to be in place in the CollabComponentEJBClient project.
As this job re
quires a few simple classes, it is not as involved as the setting up of the
Resource tier. The DTO and service interfaces were described in Figure 4, so only the
exceptions are of interest. Four exceptions are defined:
NoteboardException is the Noteboard
all exception. All other
exceptions inherit from this, so users of the API can catch all exceptions at once or
catch them in a fine
NoteboardSystemException is thrown when something fundamentally wrong like
failing to all
ocate a new note happens.
NoteboardAuthorizationException covers all permissions
related exceptions, such
as a user deleting a note that is not his.
NoteboardConcurrentException is in place as any server application must deal with
concurrency. In our app
lication, it would depend upon whether or not support for
editing notes is included. Right now, it is not, but concurrency issues remain part of
the design in case of future requirements.
All the classes are renamed in the same fashion as the Resource tie
r using the
refactoring tool. It's important that the "Update fully qualified name in non
option is used for all XML files or the ejb
jar.xml file will not be updated. When
finished, the EJBClient project should look like Figure 10.
CollabComponentServiceEJBClient after implementing DTO, service APIs, and
Once the DTO is in place, you can finish the Resource t
ier by implementing the
methods required by the Service tier in NoteboardInstance, such as updateNotice()
which adds a note to the instance's HashMap. Again, it is straightforward Java and is not
examined in detail, but the source code is heavily commented
to guide you. The final
task with the Resource tier is making sure the resource JAR file is found at runtime,
otherwise ClassNotFoundExceptions will be thrown even though the resource JAR file
is contained within the EAR.
click each EJB project a
nd select properties.
Select Java Jar Dependencies on the left and add the CollabComponentResource.jar
This will add the resource JAR file to the Class
Path in MANIFEST.MF on
export. This completes the implementation of our Resource tier, so we c
an move up one
tier to the Service tier.
The Service tier
The Service tier contains two beans that we are concerned with:
CollabComponentEJB and CollabComponentServiceEJB. The difference between the
two is simple. CollabComponentEJB, the majority of which
is implemented by the
sample application, is responsible for implementing the methods of the Collaborative
Application Component Interfaces, such as createInstance(), addMembers(), and
removeInstance(). The second bean CollabComponentServiceEJB is respons
implementing the business methods the noteboard application needs, such as
updateNotice(). We will begin with CollabComponentServiceEJB as it is the simplest,
and our business logic is relatively simple.
First, rename the classes in CollabComponen
tServiceEJB to keep the names
consistent. When finished, you should have NoteboardServiceBean,
NoteboardServiceConstants, and NoteboardService.properties. The properties file
change requires that you update the SERVICE_RESOURCES value in
nstants. Next, the business logic methods must be added, so first
remove getText() from NoteboardServiceBean because it is no longer required. Then
updateNotice(), deleteNotice(), getNoticesForBcId(), and getNotice() are implemented.
These methods are not
very interesting except for updateNotice(). The UI and
Workspace tiers cannot know in advance how a note is going to be stored and cannot
create a unique ID in a safe manner. Hence, the ID of the note is generated in the
updateNotice() method. For this app
lication, it is only an incrementing integer, but in a
real application, a truly global unique ID would need to be generated which is possible
with a number of RDBMS servers.
Next, CollabComponentEJB gets its classes renamed as always. However, this
it may also be necessary to update the ejb
jar.xml file in
CollabComponentAdapterEJB to update the new names as the refactoring tool may not
realize there is a connection. In case it is not clear, the Workplace infrastructure does
not talk directly to our
bean. Instead, it communicates with
CollabComponentAdapterEJB, which is a glue layer between IBM Workplace and the
public API. Other than the name changes, the bean implementation remains essentially
the same for our application as all the real work is in
the Resource tier classes
NoteboardResource and NoteboardInstance. At this point, the support for templatable
and points of variability was removed from the sample application. Totally removing
TemplatableLocal from the interfaces and implementation causes
nasty problems later
in runtime so, for now, the easiest way to remove support for variables is to have a
blank implementation of the NoteboardInstance#getVariables() method. Later versions
of the API will allow the implementation of TemplatableLocal to b
Now that the EJBs are in place, there is one additional consideration that must
be settled: the JNDI names. Without unique JNDI names, two developers using the
Workplace API would overwrite each others' bindings. The JNDI names are stored in
es called ejbModule/META
bnd.xmi which is best updated using
WebSphere Studio Application Developer. There are three JNDI names that must be set.
The Adapter JNDI name in CollabComponentAdapterEJB is the name used by the
cation infrastructure. For the infrastructure to find the JNDI, it must
also be copied in portlet.xml in CollabComponentPortlet so make sure they are matched.
The second JNDI name in CollabComponentEJB is the JNDI name of the bean called
by the Adapter Bea
n. The final JNDI name is in CollabComponentServiceEJB, which is
the name required by our Workspace tier to call the Service tier.
The first EJB we update is CollabComponentAdapterEJB. Double
jar.xml file, which opens the W
ebSphere Studio Application
Developer editor for deployment descriptors. Figure 11 shows how the EJB JNDI name
for the adapter itself is updated under the Beans tab.
Figure 11. Setting the Adapter EJB JNDI name
The adapter bean also has a reference to the service EJB bean, so you must
update it under the References tab as shown in Figure 12.
Figure 12. Updating the EJB reference in the Adapter
It is similar work for the other two EJB projects CollabComponentEJB and
CollabComponentServiceEJB where the CollabComponent part of t
heir JNDI names is
updated to the noteboard. Make a note of the JNDI names as they are needed later when
updating the Workspace and UI tiers.
At this stage, the beans can be used for an application that did not differentiate
between roles. However, our not
eboard protects notes by only allowing the note owner
or administrator to delete them. The application infrastructure communicates which role
users are in when it calls NoteboardBean#addMembers(), and it is up to the application
to treat the role data. The
method is passed a DataObjectList, which contains a list of
MemberRoles. Each MemberRole contains information on one user and the roles they
belong to. This information is passed to NoteboardResource, which records the user as a
member of the instance and
also adds him to the HashMap of administrators if he is one.
NoteboardInstance#deleteNotice() then only allows administrators or owners to delete a
note, otherwise a NoteboardAuthorizationException is thrown.
The Workspace tier
Coming closer to the end,
we reach the Workspace tier in
CollabComponentPortlet. In a normal application, the Workplace tier would be
responsible for implementing the Business Delegate and ServiceLocator patterns. In our
case, the NoteboardDelegate simply creates a remote reference
CollabComponentServiceEJB, delegates to the bean, and rethrows RemoteExceptions
as NoteboardSystemExceptions. Do not forget that the JNDI name used to look up the
home interface of the Service tier needs to be updated. Our Workspace tier is very
mple, but depending upon other component requirements, the decision may be made
to cache home interfaces and to retry calling the Service tier in the event of a
RemoteException, but it is beyond the scope of this article.
Lastly, we reach the
portlet where a large bulk of the work resides. The building of a
portlet is beyond the scope of this article, so instead we'll describe how it is laid out, so
the source will be easier to read. First, the views are in Web
and there are three JSPs: NewNotice.jsp,
NoteboardView.jsp, and NoticeView.jsp. The portlet is based on the Portlet Adapter
from the WebSphere Portal API and does not leverage struts or other MVC frameworks
for simplicity reasons. Hence, all JSPs use the s
ame servlet class
com.ibm.workplace.app.component.portlet.SamplePortlet so that is where to look for
the doView() and actionPerformed() methods. The portlet uses the bean
NoteboardViewBean to store a URL to the main view notes view and the bcID of the
ance. Which action is performed and which JSP is displayed is based on form
variables. So, for example, when a delete icon is displayed and then clicked, a form is
submitted, which includes a variable that actionPerformed() uses to call the appropriate
Much of the code for talking to the Workspace tier is embedded in JSP scriptlets
and a single large portlet class. This is considered bad practice as a "real" component
should do things differently. Scriptlets would be replaced with a combina
tion of JSTL
and custom tags, while the struts MVC framework would be leveraged rather than
implementing a single SamplePortlet class. However, for small applications, the
approach we choose for noteboard is easier to read.
When finished changing the portl
et, open portlet.xml and change all references
to SamplePortlet to NoteboardPortlet and make the same change in the three JSPs and
then rename SamplePortlet.java to NoteboardPortlet.java. Without this change, the
portlet is likely to have the same unique I
D as any other portlet based on the sample
application. The second task in portlet.xml is to link the portlet to the adapter EJB. Look
for the parameter name WP_BUSINESS_OBJECT. This parameter specifies the JNDI
name of the adapter, in our case
/workplace/api/app/component/ejb/NoteboardAdapterHome. Without this
setting, the lifecycle methods such as createInstance() are never called and a unique ID
for the application is never available.
The Person tag
Lastly, we want to demonstrate how easy it i
s to leverage other collaborative
features provided by IBM Workplace using the Person Tag. The Person tag enables a
user name to appear as a link, to display when the user is on
line, and to interface with
other Workplace components, such as email and inst
ant messaging. Here are the steps
required to enable additional collaborative component features using the Person tag:
Copy personTag.tld and awarenesstags.tld from PortalServerRoot
tld to CollabComponentPortlet
tld. Strictly speaking, this
is not necessary, but WebSphere Studio Application Developer may print warnings
Optionally, they could be removed again for a production deployment.
Add the following to the JSP files you want to use the tag with:
<%@ taglib uri="/WEB
INF/tld/people.tld" prefix="pa" %>
<%@ taglib uri="/WEB
The tag is now ready for use as documented in the API documentation like the
following for example:
<pa:person value="<%=aNotice.getOwnerID()%>" valueType="LDAPDN" displayName="<%=
An error occurs if the
PersonTag class is not found. To fix this error, add
people.jar to the build path for
Component building and packaging
Assuming all went well, there should be no compilation errors, so all tha
remains is to create the deployment packages. There are two we will be creating, an
EAR containing all our EJBs and the Resource tier and a WAR for the portlet.
Export the EAR
Follow these steps to export the EAR file to the Workplace server.
In WebSphere Studio Application Developer, right
click each of the three EJBs and
Deployment and RMIC Code.
click CollabComponentEAR and choose Export.
Select the EAR file and click Next.
Enter a destination like d:
bcomponentEAR.ear and click Finish.
Export the portlet
Follow these steps to export the portlet WAR file to the Workplace server.
In WebSphere Studio Application Developer, right
and select Export.
Select the WAR file and cl
Enter a destination like d:
collabcomponentWAR.war and click Finish.
Simple enough, but there are two points worth mentioning. First, remember that
portlet WARs are part of an EAR file created on the fly by WebSphere Portal. This
means that t
he portlet and EAR will have different classloaders at runtime and that
classes visible to the portlet are not necessarily visible to the EAR file and vice
This leads to the second point. Both the EAR and WAR files contain the
nt.jar file. This is because of the classloader problem just
mentioned, so the duplicated JAR file is not easily avoided.
If having duplicate JAR files is undesirable or the scale of your application
means there were too many copied JAR files, you can move
them to a shared library.
WebSphere Application Server allows administrators to create shared libraries that
contain a list of JAR files. You can create a shared library that contains only
CollabComponentEJBClient.jar and then the EAR and portlets would r
reference to the shared library to be created. This would avoid duplicate JAR files at the
cost of deployment complexity.
There are two choices for installation. The easiest method is manual deployment,
using the administrativ
e console. It is the best way to understand the range of available
options, which is why we use that method in this article. There are automated means of
deploying EARs with JACL scripts and portlets via xmlaccess, but they are quite in
depth and beyond th
e scope of this article.
Follow these steps to install the EAR file:
Open the Websphere Administrative console at https://yourserver:9044/admin and
log in as the portal administrator.
In the left pane, choose Applications
Install New Application.
Enter the path to the EAR as shown in Figure 13 and click Next.
re 13. Selecting an EAR to import
The next page is "Preparing for the application installation." Click Next.
Now the first step of sev
en is displayed. Read through all of these at least once to
know what is there. We focus on just three steps.
In step 2, you must specify the classpath. We need two: one for the Workplace API
and the second for Workplace code utilities. Assuming WebSphe
re is installed to
Websphere, the classpath is
It is important that the classpath contain no spaces or the deployment will fail
. If the
path does have spaces, use the Windows short name, for example, C:/Websph~1.
Step 3 is where the JNDI names are specified which should be double
Step 5 is very important; it specifies which server the EJBs are bound to
. Select all
the beans, select WebSphere_Portal.
At the last step, click Finish, and WebSphere will start a workbench to generate
deployment code. If RMIC fails, check Websphere/PortalServer/SystemOut.log for
related errors. Chances are, ther
e is a JAR file missing from the classpath
from Step 2 in the EAR deployment, or there are spaces in the path.
On successful deployment, click "Save to master configuration" and Save again on
the next screen.
Start the application by opening Applic
Enterprise Applications, finding
CollabComponentEAR in the list, selecting it, and clicking start.
Follow these steps to install the portlet WAR file on the Workplace server.
Log into your Workplace server as the portal ad
Click the Administration button at the top of the screen.
Click Portlets on the left pane and install as shown in Figure 14.
Figure 14. Selecting the Portlet WAR to install
Installation may take some time.
By default, only the portal administrator may use the portlet, so the permissions
must be set for all users.
Log in as the portal administrator.
Click the Administration button at the top of the screen.
Search for noteboard, and simple noteboard should appear in the list.
Click the Key icon.
Click the Pencil icon beside User.
Select "All authenticated portal users" and "All portal user groups," and then
Click Done. Now end users can see and use the portlet.
Creating a new template
Finally, everything is in place to create a new template with the si
noteboard as part of it. While the component could be made part of an existing template,
we create a new template to keep it simple.
Log in as a user allowed to use Workplace Builder.
Click the Workplace Builder button at the top of the screen t
o open the
Click New to create a new template.
Give the template a name and make it part of the Team Space category
using the Blank Template as a starting point. See Figure 15.
Figure 15. Creating a new template
Click the Pages and Layout tab.
Click the Edit button for Page 2, which is the Pencil icon.
Click Add Portlets.
Search for noteboard, and simple no
teboard should appear on the list. Select it and
Click the Done button.
Click Roles tab, and then click Moderators.
Under Page 2, the noteboard application should be visible. By default, it is called
Sample Business Component and can b
e updated by editing
jb.properties. In the drop
down list, select Administrator and click OK.
Click Contributors, set the role to User for our application, and click OK.
lick Save and Close. The template is now available for use.
All that remains now is to create a Team Space from the new template and to see
the noteboard in action.
Click the My Workplace button if you are still using Workplace Builder, and then
he Team Spaces tab.
Click the New button to create a new Team Space.
Enter a name for the template, select Noteboard Template from the list, and click
The application will now instantiate. During this process, the createInstance()
method of ou
r adapter bean is called. If you open the SystemOut.log for WebSphere
Portal, you will find an informational message saying, "INFO: Initializing
NoteboardResource" in the logs.
Click the link to the new noteboard, and the Team Space opens.
Page 2 link, and the noteboard displays, saying there are no messages.
After posting a few notes, the board should look similar to Figure 16.
Figure 16. Running noteboard application
To see roles in actions, add two new users as contributors to the application
using the Members page. Log in as both users and create notes. You will see that the
Delete icon only appears for the notes they o
wn. If you click Delete and check the logs,
you will see something similar to "Deleted notice N with owner role." However, if you
log in as the creator of the Team Space who is an administrator, you will see the delete
icon for all notes, and the message i
n the log is "Deleted notice N with administrator
role." If multiple applications are created, you will see how each noteboard has its own
In this article, we described the steps required to convert the Lotus Workplace
Products API Toolkit s
ample application to a basic working business component, to
deploy it, and to make it part of IBM Workplace. This was not a full
featured application, but the point is that developing with IBM Workplace means that
you can build powerful appli
cations in short periods of time with relative ease. The time
required to build this application is measurable as one work week for one person, which
is not a large amount of time to have so many features available. This application for
example took about
30 hours of development time, including design, implementation,
reading the API docs, deployment, and debugging.
This article illustrated how you can adapt existing applications to become part of
IBM Workplace by supporting the collaborative API, using the
available information on
roles, and extending the Resource tier to have instance
specific information. If it is not
perfectly clear, the source of the noteboard is there with comments on how it was put