<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Object Partners Inc</title>
	<atom:link href="http://www.objectpartners.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.objectpartners.com</link>
	<description>Object Partners Inc.</description>
	<lastBuildDate>Thu, 02 Sep 2010 14:05:50 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Remotely Back-up Subversion Repository</title>
		<link>http://www.objectpartners.com/2010/09/02/remotely-back-up-subversion-repository/</link>
		<comments>http://www.objectpartners.com/2010/09/02/remotely-back-up-subversion-repository/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 14:05:50 +0000</pubDate>
		<dc:creator>jwarren</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[back-up]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=2150</guid>
		<description><![CDATA[It happens from time-to-time and for a variety of reasons that one might want to have a back-up of a Subversion repository. This includes the normal back-up reasons for disaster recovery, but could also provide a way to share repositories over slow connections, wanting a local copy of a remote repository, and probably more. 
There [...]]]></description>
			<content:encoded><![CDATA[<p>It happens from time-to-time and for a variety of reasons that one might want to have a back-up of a Subversion repository. This includes the normal back-up reasons for disaster recovery, but could also provide a way to share repositories over slow connections, wanting a local copy of a remote repository, and probably more. </p>
<p>There are a few sure-fire ways to do it, but only one to do it without direct access to the original repository server, and (after initial creation of the repository) not even direct access to the back-up server. Well, you need HTTP access, but that&#8217;s all. We&#8217;re assuming proper access is allowed, and that neither server minds the occasional suck of the bandwidth.</p>
<p>To start, you need a Subversion repository on which to store the copy. Somewhere on this blog is a quickie how-to that will help get one configured. Once you have a server configured, you need to make a repository to receive the back-up; be sure that the server configuration allows exposing the repository path as necessary.</p>
<p>Unless you have some web-based tool to create the repository, you need to pop into the back-up &#8220;to&#8221; server (hereafter named &#8220;backup.server&#8221;) and create the repository (cleverly named &#8220;Repository&#8221;). Note my paths are for not-Windows, so if you&#8217;re on that OS, flip the slashes over. I&#8217;m also making some assumptions about the system configuration and permissions. If you&#8217;re not allowed to do this, of course, it will fail.</p>
<p><code>svnadmin create /path/to/svn/Repository</code></p>
<p>The command won&#8217;t return anything, but you should be able to look and see the new Repository folder in the /path/to/svn, or whever your subversion repository will live (in agreement with your Apache configuration). There&#8217;s one thing that Subversion doesn&#8217;t do by default, and that&#8217;s configure the hooks in a way that allow us to use the provided Subversion svnsync tool. In the new repository folder is a folder named &#8220;hooks.&#8221; By default in that folder are a number of templates. One in particular is of interest, the <a href="http://svnbook.red-bean.com/en/1.4/svn.ref.reposhooks.pre-revprop-change.html">pre-revprop-change</a>.tmpl file. The template file does some checking to ensure that a particular entity is limited to a particular action. The documentation notes that the file must exist and return zero for the hook to pass; you can just create an empty, executable script file named pre-revprop-change in that folder, and it works fine. Something very simple like <code>#!/bin/sh</code> works. Of course, it doesn&#8217;t do any protection (more on that), but gets us flying into the back-up.</p>
<p>After creating the repository and creating the pre-revprop-change script, direct access to the server is no longer required. Somewhere in the middle, either on the source server, destination server, or some other system in the middle with HTTP access to both and Subversion installed, we can kick off a pretty straight-forward <a href="http://svnbook.red-bean.com/en/1.4/svn.ref.svnsync.html">svnsync</a> command.. Here&#8217;s what it looks like, and following is a discussion of the bits we&#8217;re using.</p>
<p><code>svnsync init http://backup.server/Repository http://source.server/Repository --source-username=sourceUser --sync-username=syncUser</code></p>
<p>The &#8220;init&#8221; tells svnsync to configure the destination server so that it knows . It also does a little file manipulation on the system to create configurations to link the two together, hold usernames and passwords, and other Subversion magic. For the curious, watch the files in your home folder&#8217;s .subversion folder (again, on not-Windows) to see what changes. Slightly uncomfortable is that there are files there with passwords (assuming there are passwords associated with the servers) that are stored in clear-text; they are stored with owner-only permissions, but their presence can make some people squirm. Used as described above, svnsync will prompt for the passwords as required; add the parameters of &#8211;source-password and &#8211;sync-password to avoid being prompted (and have the passwords in your history&#8230;).</p>
<p>The first URL is the destination, or the back-up server Repository. Of course, the full and correct URL should be used.</p>
<p>The second URL is the source. Also here the full and correct URL should be used.</p>
<p>The source- and sync-username parameters (each preceded with double-hyphens) are optional. They&#8217;re used to provide the user to gain access where authentication is required. If authentication is required and these are not provided, the current username will be used. As noted in the comments, there are similar source- and sync-password parameters, too, to avoid being prompted if the server requires passwords.</p>
<p>If this is successful, a very simple response will confirm that the properties are configured.</p>
<p><code>Copied properties for revision 0.</code></p>
<p>Once done, trigger the copy command. This will be the same command to copy the first and each iteration in the middle. Issuing the command will bring the repository up to date, in full Subversion fashion, maintaining all of the history along the way. Since the init starts at revision 0, it may be some time if the repository is large or has a lot of revisions. While it&#8217;s working, there should be a cycle of &#8220;copying properties&#8221; and &#8220;transmitting data&#8221; and &#8220;committed version&#8221; messages as each revision is copied. When it reaches the current revision it will stop.</p>
<p><code>svnsync sync http://backup.server/RepositoryPath --source-username=sourceUser --sync-username=syncUser --sync-password=syncPassword</code></p>
<p>Here note that the sync-password parameter is provided. This line can be added to a cron job or other automatically run script to provide periodic updates to the repository. Of course, again, use the correct values for your system.</p>
<p>That&#8217;s the guts of it. Easy, four steps, and done. Make a repository. Prep the hooks. Run an init. Run a sync (repeat as necessary).</p>
<p>About that hook. Reading the svnsync documentation and the contents of the template file, many warnings abound about the trouble that happens if a sync&#8217;d-to repository is otherwise updated; and they&#8217;re true. Consider if a user uses the back-up repository and commits a change; they get to use the next revision number. The next sync will come along and try to use the same next revision number and fail because it already exists. For that simple reason it&#8217;s worth protecting with a more robust pre-revprop-change file. That&#8217;s a little outside the scope of this document, but it&#8217;s not much harder than changing the template file to use your sync username instead of the one in the file. Here&#8217;s a trivial example that will work with our example syncUser.</p>
<p><code>#!/usr/bin<br />
if [ "$3" == "syncUser" ] ; then exit 0 ; fi<br />
exit 1</code></p>
<p>Note this really only limits changing properties (and therefore revision numbers) to the one user, so if you&#8217;re going to do this, make that user be a non-user, one used only for the back-up.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2010/09/02/remotely-back-up-subversion-repository/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Embracing Mylyn</title>
		<link>http://www.objectpartners.com/2010/08/26/embracing-mylyn/</link>
		<comments>http://www.objectpartners.com/2010/08/26/embracing-mylyn/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 13:59:00 +0000</pubDate>
		<dc:creator>jwarren</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[ALM]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[Mylyn]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=2187</guid>
		<description><![CDATA[As a developer, one of the things I really want to do with my work day is development. As a member of a development team, I recognize the need to identify tasks, prioritize work, and (sometimes reluctantly) quantify effort, both in pre-work estimates and post-work time accounting. When these tasks are tracked using compatible software, [...]]]></description>
			<content:encoded><![CDATA[<p>As a developer, one of the things I really want to do with my work day is development. As a member of a development team, I recognize the need to identify tasks, prioritize work, and (sometimes reluctantly) quantify effort, both in pre-work estimates and post-work time accounting. When these tasks are tracked using compatible software, Eclipse has a built-in tool to help leverage those lists and assist in tracking time and work related to completing tasks.</p>
<p>Anyone using Eclipse has undoubtedly run into Mylyn once or twice, probably by accident. There&#8217;s a goofy icon on a number of views that looks like three balls, one in front of the other, and if you bonk it the whole view presents different information than it did before. Especially if done by accident, it can be frustrating and difficult to revert; some of us taking the &#8220;when in doubt, restart&#8221; mindset brought about by one of our common operating system, and restart the IDE to get the view back to what we expect.</p>
<p>That icon is the gateway to a powerful tool that, like so many others, once understood can provide incredible utility. Before digesting a flow of work that includes using that button, here&#8217;s a bit about what Mylyn is.<br />
<span id="more-2187"></span></p>
<h2>What is Mylyn?</h2>
<p>Mylyn is an Eclipse plug-in, usually included by default in a lot of their packages but available for later installation if necessary; it&#8217;s certainly in the Java and JavaEE packages (I would guess these are the ones most of us use). It&#8217;s got its own documentation and propaganda site hosted at Eclipse (http://www.eclipse.org/mylyn/), so I&#8217;ll try to avoid repeating more than is necessary, instead hoping to shine a little light on the process, inviting you to work it into your own project and application lifecycle management.</p>
<p>Mylyn is a &#8220;task-focused interface,&#8221; which makes it really useful if you embrace and use Eclipse&#8217;s tools for task management. When most of us develop software, we tend to think in terms of projects, work-spaces, or even file system structures. Our software is organized into groups that make sense on some level, and those groups are made of smaller groups. Because of this, far too often we think of our software as a project-based product. As we&#8217;re assigned tasks to work on, though, those tasks often break those boundaries. More often it breaks it into a subset of our work-space. </p>
<p>Consider a typical client-server application. There&#8217;s probably a workspace (or few) with a project for the server software and one for the client software. There may be a separate project containing common classes developed for use on both sides. There may be additional server-side projects, especially if implementing a SAAS-style project. There may even further be additional sub-projects with an intent on layering or isolating specific implementations, perhaps for the purpose of swapping out for specific environments.  When we have such a structure of projects in our Eclipse workspace, there&#8217;s going to be a set of top-level projects, each with their sources, libraries, and resource folders.</p>
<p>Consider now a typical list of tasks for such a project. Tasks to create a log-in interface, report log-in failures, provide log-in auditing. Tasks to provide lists of data, allow user sorting or filtering of the data, and even adding, editing, and deleting the data. Where these tasks overlap the projects can be difficult to see initially, but as we&#8217;ve all done this, we know there are classes and resources added and affected throughout our work-spaces, across source-tree boundaries, and across projects.</p>
<p>Mylyn doesn&#8217;t remove any of this, but as we learned by accidentally hitting that button, it does help streamline the views. Further, it helps when we do that inevitable bouncing back and forth between tasks. Let&#8217;s jump in and imagine managing a little bit of development with the help of Mylyn.<br />
<!--more--></p>
<h2>Task List</h2>
<p>The &#8220;Task List&#8221; view is the central point for finding, creating, and focusing tasks. It&#8217;s really fundamental to making Mylyn make sense, and if you&#8217;re not integrating task tracking into Eclipse, much of the usefulness of Mylyn is lost. Out of the box, Mylyn has connectors for Bugzilla, Jira, the built-in Eclipse task list and more! Some of them are added to Eclipse by default, some are just available in the list of plug-ins, and some can be added as third-party add-ons. </p>
<p>The easiest way to get started with your task tracking software is to open the &#8220;Task Repositories&#8221; view in Eclipse, click on the &#8220;Add Task Repository&#8221; button (or right-click the middle of the view and add it that way), and in the dialog-box that pops-up, click the &#8220;Install more connectors&#8221; button. For the most part, once you add the connector, providing whatever URIs, paths, credentials, and whatnot that are required, you should find that your &#8220;Task List&#8221; view is populated with tasks for you to work on.</p>
<p>Really the installation of a repository and task tracking system is outside of the scope of this document, so let&#8217;s just start out using the local task list in Eclipse. This is fine for single machine use, but, of course, doesn&#8217;t synchronize by default with anything that allows multiple developers to participate. To play along, you can simply add a task using the &#8220;Task List&#8221; view; click the &#8220;New task&#8221; button or right-click and select &#8220;New task&#8221; from the context menu, choose the &#8220;Local&#8221; repository, and you&#8217;ll be rewarded with a new task window. You can add a title and details if you like, but let&#8217;s focus for a moment on the Mylyn bits here.</p>
<p>Looking at the task in the source editor area (that&#8217;s where they appear), there are only two Mylyn interactions visible for the Local repository. The first is near the title of the task (once saved); the little purple dot will allow you to activate the task. Once activated, Mylyn (by default) will start keeping track of the work done related to this task. Any files opened in the IDE will become part of this collection, which they call a &#8220;context.&#8221; In more advanced repositories, and when so selected in the preferences, this will also track the time that the task is active, including noting breaks in editing activity, to help with your time tracking. At the bottom of the task editor window are two tabs, named Private and Context. Clicking the Context tab will show the list of affected files (which should be empty when the task is started).</p>
<p>If you activate a task, you should notice a few things happen. If you still have the task open in the editor, it&#8217;s purple dot will appear to be on a depressed button to help identify it as the active task. Likewise, there should be a purple dot next to the task in the &#8220;Task List&#8221; view. Finally, any navigator windows will also have that annoying three-ball button depressed, and all of the projects and source files will have disappeared; more correctly, the navigator windows will show all of the files that exist in the context.</p>
<p>You can activate and deactivate the tasks easily by clicking the purple ball either on the task editor, or more concisely in the &#8220;Task List&#8221; view. I recommend keeping the &#8220;Task List&#8221; open (hide it with a &#8220;fast view&#8221; so it becomes an icon if you want the real estate back) to allow fast switching between tasks. More on that in a second. </p>
<p>Let&#8217;s look at filling the context, now that we&#8217;ve got a task set up.<br />
<!--more--></p>
<h2>Filling the Context</h2>
<p>The various navigation views, such as the &#8220;Project Explorer,&#8221; &#8220;Package Manager,&#8221; and the raw &#8220;Navigator&#8221; are strong users of the Mylyn context. (Note for the purposes of this document, I refer to all of them as &#8220;navigation&#8221; or &#8220;navigator&#8221; views, allowing you to choose your favorite or one appropriate for the situation in which you find yourself.) You can toggle the context filter on the views without affecting the context tracking help Mylyn provides. This allows you to work as you always have, but still take limited advantage of the Mylyn task-focused interface. Since we&#8217;re trying to embrace Mylyn, let&#8217;s shift how we work a little bit.</p>
<p>Activate that sample task. If you&#8217;re not playing with an existing work-space, create a project to play with (or create one anyway if you want to minimize risk to other projects). I simply created a new Java project, and named it Foo. Eclipse did what it always did and created the project files and folders in my work-space, but since I have a task activated, I didn&#8217;t see anything happen. The workspace itself isn&#8217;t yet part of the context. I can see my new project by turning off the Mylyn context to verify that it&#8217;s there.</p>
<p>My pretend task (and more importantly my empty project) requires me to add a class (or something). If you use the context menus to create classes, you&#8217;ll note right away that the folders are missing, so it would seem hard to do so; deactivate the context view, browse to the place you want to make your class and create it. Alternatively, leave the context view activated and use the File menu or context menu on the blank navigator view and get through the &#8220;new&#8221; menus and dialogs to create a class. Again, I named mine Foo, and in bad form just put it in the root (default package) of my Foo/src folder. Activating the context filter, and the context should contain only my Foo.java, and the navigation viewer tree necessary to display it. If I close the source editor, the file remains in the view, with or without the context turned on. If we return to our task, perhaps by double-clicking it in the &#8220;Task List&#8221; view, we can check out that once empty context tab, and we should see the same tree view displayed therein.</p>
<p>In a more complete project, we can see that this could be handy in streamlining our navigator views by streamlining the trees to only show the files related to our task. If a file isn&#8217;t visible, we can find it using one of the many Eclipse tools such as the &#8220;Open Type&#8221; (ctrl+shift+T) or &#8220;Open Resource&#8221; (ctrl+shift+R) dialogs, clicking on a type in our source and hitting F3 or Ctrl+G to jump to its declaration, or even by toggling the context view filter button and navigating to the class and double-clicking to open it in the editor. When the context filter is on, we&#8217;ll only see the items opened while the task is active.</p>
<p>Further, the context only contains members visited while the task was active. This helps reduce the context to just the methods and members that were worked on (or reviewed) during the session, helping to further streamline the views. This will aid in removing much of the background noise that occurs as we work on more complete projects, defending our time by filtering out methods in our classes that aren&#8217;t related to our task&#8230;keeping us focused on the task at hand and the things it affects.</p>
<p>It will happen sometimes that an element isn&#8217;t wanted in the context. Perhaps it was opened by mistake, perhaps it was only opened for a quick review but isn&#8217;t part of the work being done. Right-clicking a file in the navigator view will allow you to remove it from the context. Be forewarned that doing so will close its editor window. It does not undo any changes made, but does remove it from the context for tracking purposes. Removing higher parts of the navigator trees will prune all the items from the context that are beneath it, too, so you can quickly clean contexts before you&#8217;re done working.</p>
<p>Switching active tasks in the Task List switches the context and information in the other views. This is the next best part of Mylyn to the streamlined views.<br />
<!--more--></p>
<h2>Switching Tasks</h2>
<p>If your project is like most of the projects I work on, it&#8217;s seldom the case that you strictly work on only one thing at a time. Well, you probably work on one thing at a time, but switch rapidly back and forth. In many agile disciplines, it&#8217;s not uncommon for the start of work on one task to spawn several others. In a &#8220;getting things done&#8221; mindset, there are two kinds of work; things you can do right now without interrupting what you&#8217;re working on, and what you make note of to do later. This can be seen often in software as the simple task of &#8220;create log-in&#8221; can immediately be seen as needing separate tasks such as generating a web page or other UI, making a message to a service, handling the service request and forming a response, handling the response, and handling errors&#8230; Working strictly in a GTD or agile approach, the developer who picked the &#8220;create log-in&#8221; task should be creating those other tasks as they are recognized.</p>
<p>If you have only the one task discussed so far, create a second task. When done, activate it instead of the first. A few things you may notice should include that the navigator view is again empty, automatically turning on the context filter and removing all of our previous files (not to worry; they&#8217;re still not gone). In the &#8220;Task List&#8221; view, our one active task has the heavy purple ball highlighted, but our previously active task has a dim purple ball. This indicates that the other task has items in its context associated with it. If we reactivate the other task, our editor and navigators should return as we had them when we highlighted the other task. The new task has no dim purple ball as we hadn&#8217;t opened anything (if you did as I just described), and its context is empty.</p>
<p>So, this brings to light the bigger usefulness of Mylyn. Switching tasks helps keep the views focused on the items associated with those tasks. As you work on both the client call to the server and the server handling of that call, switching back and forth between those tasks allows maintaining comprehensive lists of software only associated with those tasks. Those lists may overlap, for example in a common classes project used by both our client and server, but the client task would mostly have client code in its context, and the server code would likewise have its code but not the client code in its context.</p>
<p>Further, when using the more advanced task repositories that support it, the time spent on each task will be correctly recorded. Perhaps it takes all day to write the client-server query and response, but the two tasks could be unevenly divided in the day, and this can help track the six hours for one and the two hours for the other separately. Additionally, if you&#8217;re interrupted with a meeting, either deactivating the active task or going idle will stop the timer, and the interruption won&#8217;t make the task seem disproportionately time-consuming.</p>
<p>Time-tracking is turned off by default, but is easy to add. In the Window menu, select Preferences. Then find Tasks in the list. Near the bottom of the right pane is &#8220;Time Tracking.&#8221; Turn on the &#8220;Track time&#8221; check box, and time tracking will start when tasks are activated and the time will be added to task lists that support it. In our simple use of the Local repository, there will be a simple &#8220;active time spent&#8221; bit at the bottom of the task editor windows.<br />
<!--more--></p>
<h2>Task Updates</h2>
<p>Note this time is for the entire task, not any specific activity on it, so if you&#8217;re looking to track parts of a task more accurately, you need to use a task repository that allows incremental updates such as comments and post comments as bits are done, so you can see the differences in time for each bit. Task repositories like Bugzilla or Jira both support this.</p>
<p>While our simple Local task tracker will keep a list of the files affected, the more advanced trackers do much more than that. For example, using Bugzilla allows uploading the context as a zipped attachment, containing the Java files and resources in the context. This allows gathering files for code reviews or a kind of version control to be directly associated with the task tracking. Some tools that integrate with both task tracking and version control will use Mylyn to help coordinate the context through other means as well.</p>
<p>When completing tasks, the &#8220;Task List&#8221; view allows filtering them out. Test this by opening one of our simple tasks, clicking the complete button and saving it. It should appear dimmed and crossed-off. Then click the crossed-out check mark button on the tool bar and our dimmed task disappears from the view. Toggle the button and it returns. The task and its context can be recalled at any time, to refresh your memory on why it was created and what work was associated with it.<br />
<!--more--></p>
<h2>Conclusion</h2>
<p>To take all of this in a wrapped-up day-to-day example, we&#8217;ll assume a task tracking system is in place and incorporated in the Eclipse &#8220;Task List&#8221; and that a project full of source already exists. Done with the previous task, a skim through the task list will help pick the next thing to do. Many heretofore unmentioned features of the task list include ordering by expected due date, and filtering by assigned developer if the tracking tool allows it.</p>
<p>Selecting a task, the developer activates it. Depending on the tracking system, this should include a submission back to the repository so that the task will be noted as in progress and another developer won&#8217;t select it. Once active, the IDE should present a clear, streamlined work-space. In accordance with the requirements of the task, the developer opens and creates new classes. Occasionally more work than can be easily done may be noted, so the developer pauses and adds new tasks and subtasks. Perhaps correlating work is found to be necessary and appropriately other tasks are activated and noted as in progress, like the first one.</p>
<p>As work is completed, in part or in whole, the developer marks progress on the active task, submitting comments and contexts, optionally with time updates, to the task repository as well as version control system. Switching tasks switches views, helping focus the work to what is important to that task.</p>
<p>As tasks become complete, they are marked as done in the task repository, with their final context and time updates committed. As the set of tasks diminishes, the developer winds down this set of work. Eventually the last task is marked as complete and all of the code is committed. </p>
<p>A deep breath and sigh of relief, and the developer returns to the task list to find the next thing to do&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2010/08/26/embracing-mylyn/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gaining Access to the Spring Context in Non Spring Managed Classes</title>
		<link>http://www.objectpartners.com/2010/08/23/gaining-access-to-the-spring-context-in-non-spring-managed-classes/</link>
		<comments>http://www.objectpartners.com/2010/08/23/gaining-access-to-the-spring-context-in-non-spring-managed-classes/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 14:00:44 +0000</pubDate>
		<dc:creator>jbaso</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[context]]></category>
		<category><![CDATA[legacy code]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=2253</guid>
		<description><![CDATA[There are times where it&#8217;s not practical (or possible) to wire up your entire application into the Spring framework, but you still need a Spring loaded bean in order to perform a task.  JSP tags and legacy code are two such examples.   Here is a quick and easy way to get access to the application [...]]]></description>
			<content:encoded><![CDATA[<p>There are times where it&#8217;s not practical (or possible) to wire up your entire application into the Spring framework, but you still need a Spring loaded bean in order to perform a task.  JSP tags and legacy code are two such examples.   Here is a quick and easy way to get access to the application context.</p>
<p>First we create a class that has a dependency on the spring context.  The magic here is a combination of implementing ApplicationContextAware and defining the ApplicatonContext object as static.</p>
<pre>package com.objectpartners.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class SpringContext implements ApplicationContextAware {
  private static ApplicationContext context;

  public void setApplicationContext(ApplicationContext context) throws BeansException {
    this.context = context;
  }
  public static ApplicationContext getApplicationContext() {
    return context;</pre>
<pre>  }
}</pre>
<p>Next,  we wire SpringContext into our spring container by defining it in our application-context.xml:</p>
<pre>&lt;bean id="springContext" class="com.objectpartners.util.SpringContext /&gt;
</pre>
<p>Now,  anywhere we need access to the spring context we can import SpringContext and call the getApplicationContext method like so:</p>
<pre>import com.objectpartners.util.SpringContext;
class LegacyCode {
.
.

  SpringBean bean = (SpringBean)SpringContext.getApplicationContext.getBean("springBean");
.
.
}
</pre>
<p>Keep in mind that if there are multiple spring containers running on the JVM the static ApplicationContext object will be overwritten by the last container loaded so this approach may not work for you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2010/08/23/gaining-access-to-the-spring-context-in-non-spring-managed-classes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mimicking External Actions With EasyMock</title>
		<link>http://www.objectpartners.com/2010/08/19/mimicking-external-actions-with-easymock/</link>
		<comments>http://www.objectpartners.com/2010/08/19/mimicking-external-actions-with-easymock/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 13:54:01 +0000</pubDate>
		<dc:creator>jwarren</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[easymock]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=2182</guid>
		<description><![CDATA[It will happen sometimes that a unit test will need to do some work that an external source might normally do. One easy-to-see example of this is an ID that gets generated by a database when an entity is persisted. It may be the case that the software will assume success, but it could (nay, [...]]]></description>
			<content:encoded><![CDATA[<p>It will happen sometimes that a unit test will need to do some work that an external source might normally do. One easy-to-see example of this is an ID that gets generated by a database when an entity is persisted. It may be the case that the software will assume success, but it could (nay, should) also be the case that some validation or use of the identifier is done after the persistence, and this can be tricky when mocking these interactions.</p>
<p>Let&#8217;s take a really simple and dumb annotated Entity object.</p>
<blockquote><pre><code>@Entity
@Table(name="pojo")
public class POJO {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Long id;

    @Column
    public String something;
}</code></pre>
</blockquote>
<p>When used, we would expect the database to populate our id column when we saved the object for the first time. Simple, easy.</p>
<p>Let&#8217;s make a simple DAO definition to save such an object.</p>
<blockquote><pre><code>public interface POJODAO {
    public POJO saveOrUpdate(final POJO pojo);
}</code></pre>
</blockquote>
<p>We&#8217;ll leave the implementation of this up to the specific application, but now we know we have a way to save (or update) our POJO. Let&#8217;s make a trivial class that will do exactly this.</p>
<blockquote><pre><code>public class POJOWork {

    public POJODAO pojoDao = null;

    public void makeAndSavePOJO() {
        final POJO pojo = new POJO();
        pojo.something = Long.toHexString(System.currentTimeMillis());
        pojoDao.saveOrUpdate(pojo);
        if (pojo.id == null) {
            throw new RuntimeException("POJO Save Failed!");
        }
    }
}</code></pre>
</blockquote>
<p>Here we&#8217;ve got a pretty useless method that creates and saves one of our objects, assigning some goofy data to its member. Of course, in your code, this would be more useful. After the save is complete, the ID field is used. Here, for a trivial and probably very undesireable validation, the ID field is checked for null, which it shouldn&#8217;t be after a successful save, and will throw an Exception if the field is null. Again, of course, in your code something more useful would be done.</p>
<p>In good test-driven (or test-defended) development, we want to have a test that verifies our method does what we expect it to. There are a few obstacles in our method that we run into when we&#8217;re writing our test, the least of which is that the object we need to mock is local to the member.</p>
<p>Here&#8217;s a quick method that works around this, ensures that the DB interaction is mocked, and passes our simple method without hitting that Exception.</p>
<blockquote><pre><code>import static org.easymock.EasyMock.*;
import static org.junit.Assert.assertNotNull;

import org.easymock.IAnswer;
import org.junit.Test;

public class POJOWorkTest {
    @Test
    public void makeAndSavePOJOSuccess(){
        final POJOWork pojoWork = new POJOWork();
        pojoWork.pojoDao = createMock(POJODAO.class);

        expect(pojoWork.pojoDao.saveOrUpdate(isA(POJO.class))).andAnswer(new IAnswer<POJO>() {
            @Override
            public POJO answer() throws Throwable {
                final POJO pojo = (POJO)getCurrentArguments()[0];
                assertNotNull(pojo.something);
                pojo.id = 0l;
                return pojo;
            }
        });

        replay(pojoWork.pojoDao);
        pojoWork.makeAndSavePOJO();
        verify(pojoWork.pojoDao);
    }
}</code></pre>
</blockquote>
<p>Digesting the test bit by bit, we start out making our object. We then assign its DAO to a mock implementation.</p>
<p>We know that we&#8217;re going to call the method, so we set up an expectation. Since we don&#8217;t have either an equals() method or other means by which to compare the object passed to our expectation, we simply accept one of its kind with the isA() EasyMock matcher. If EasyMock accepts our match (which it will), it then invokes our IAnswer, calling the answer() method.</p>
<p>In our answer() method, we grab the parameter (which we know from the matcher will be the right type and exist). We can do some validation here that helps us overcome other lack of access to the object; in our case, we just confirm that our POJO.somethign has a value.</p>
<p>Happy that our object is prepared for the DB, we play its part and assign the id field a value. Since our test simply makes sure it&#8217;s not null, we just give it a number. Should we have needed to, we could have put more thought into this, of course. Then, because our interface says we return our POJO, we do so from our answer() method.</p>
<p>With our peparation complete, the test tells EasyMock to start waiting for calls, we call the method, it runs, calling our prepared EasyMock method and running as if it were in a real execution flow, and finally we validate with EasyMock that our expectations were met. Running this test gives us total green-bar happiness.</p>
<p>Sure, that&#8217;s the easy one; a method with a return value. What happens if we don&#8217;t return anything, or what is returned has nothing to do with our object? Let&#8217;s change our interface a little to just save and not return our object.</p>
<blockquote><pre><code>public interface POJODAO {
    public void saveOrUpdate(final POJO pojo);
}</code></pre>
</blockquote>
<p>With that little change, our POJOWork code is still valid, as it was not making use of the returned value, but we can no longer use the easy expect().andAnswer() or expect().andReturn() EasyMock methods.</p>
<blockquote><pre><code>import static org.easymock.EasyMock.*;
import static org.junit.Assert.assertNotNull;

import org.easymock.IArgumentMatcher;
import org.junit.Test;

class POJOMatcher implements IArgumentMatcher {
    @Override
    public void appendTo(StringBuffer arg0) {
    }

    @Override
    public boolean matches(Object arg0) {
        final POJO pojo = (POJO) arg0;
        assertNotNull(pojo.something);
        pojo.id = 0l;
        return true;
    }
}

public class POJOWorkTest {
    private POJO isPOJO() {
        reportMatcher(new POJOMatcher());
        return new POJO();
    }

    @Test
    public void makeAndSavePOJOSuccess() {
        final POJOWork pojoWork = new POJOWork();
        pojoWork.pojoDao = createMock(POJODAO.class);

        pojoWork.pojoDao.saveOrUpdate(isPOJO());
        expectLastCall();

        replay(pojoWork.pojoDao);
        pojoWork.makeAndSavePOJO();
        verify(pojoWork.pojoDao);
    }
}</code></pre>
</blockquote>
<p>That&#8217;s a bit more work, and it&#8217;s not nearly as elegant or flexible. Let&#8217;s go over this bit-by-bit, too.</p>
<p>The new class, POJOMatcher, makes use of the EasyMock.IArgumentMatcher interface to allow EasyMock to send an object for comparison. The matches() method will be used to determine if that&#8217;s the right deal after all. Since we&#8217;ve really got nothing to compare to, we do our validation in the matches() method just like in the answer() method before, and when it passes we set the id. The argument passed to the matcher is the one created in our test method, so it will have an id when the method continues from the mocked save attempt.</p>
<p>Our test class has a new isPOJO() method, which kind of binds the IArgumentMatcher to our POJO type. While we do have to return an instance of our class, unless we want to use it to validate the information in the POJOMatcher.matches() method, it can be empty (as it is). had we wanted to, we could  have made the isPOJO() more intelligent, perhaps taking a POJO as a parameter for comparison, and returning that after setting up the ReportMatcher.</p>
<p>In our test method, we changed the preparation a little bit. Since the method doesn&#8217;t return a value any more, we can&#8217;t pass it to EasyMock.expect(), and then can&#8217;t use the expect().andAnswer() or expect().andReturn() methods, which is how we got wrapped up in ReportMatcher and IArgumentMatcher anyway. &#8220;Calling&#8221; the method and then telling EasyMock we expect the last call using the expectLastCall() will satisfy the replay and verify and let the mock do its job.</p>
<p>When the call is run in the middle, our matcher will be called, comparing, ignoring our isPOJO()-provided POJO, and verifying the POJO actually passed in our implementation in the POJOMatcher.matches() method, and successfully setting the id.</p>
<p>Now, in both cases, we can validate the information contained in a local object when passing through a mocked method, and can also meet our initial goal of affecting the passed object as the real object is expected to have affected it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2010/08/19/mimicking-external-actions-with-easymock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>News: OPI hires consultant Jay Bose</title>
		<link>http://www.objectpartners.com/2010/08/18/news-opi-hires-consultant-jay-bose/</link>
		<comments>http://www.objectpartners.com/2010/08/18/news-opi-hires-consultant-jay-bose/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 13:40:27 +0000</pubDate>
		<dc:creator>Ehren Seim</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=2293</guid>
		<description><![CDATA[Object Partners announces the addition of Consultant Jay Bose to their technology consulting staff. Jay&#8217;s main responsibility will be to expand and build upon the knowledge and expertise of OPI’s technology consulting footprint in the Twin Cities by leveraging his knowledge of enterprise level software systems.
Jay comes to OPI with 8 years of experience building [...]]]></description>
			<content:encoded><![CDATA[<p>Object Partners announces the addition of Consultant Jay Bose to their technology consulting staff. Jay&#8217;s main responsibility will be to expand and build upon the knowledge and expertise of OPI’s technology consulting footprint in the Twin Cities by leveraging his knowledge of enterprise level software systems.</p>
<p>Jay comes to OPI with 8 years of experience building distributed and scalable JEE applications. His main focus has been providing solutions using open-source frameworks, such as Spring and Hibernate. Jay&#8217;s work experience includes retail, asset management, manufacturing and the pharmaceutical industries. He has a passion for new technologies, and most recently is looking to build efficient Google App Engine solutions.</p>
<p>His addition solidifies OPI’s strategy towards employing the top talent within the local IT/software community. We’re excited to have him as part of the OPI team!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2010/08/18/news-opi-hires-consultant-jay-bose/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integrating OpenSSO/OpenAM with Liferay Portal on Tomcat</title>
		<link>http://www.objectpartners.com/2010/08/16/integrating-opensso-openam-with-liferay-portal-on-tomcat/</link>
		<comments>http://www.objectpartners.com/2010/08/16/integrating-opensso-openam-with-liferay-portal-on-tomcat/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 14:52:51 +0000</pubDate>
		<dc:creator>Steve Banks</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Liferay]]></category>
		<category><![CDATA[openam]]></category>
		<category><![CDATA[opensso]]></category>
		<category><![CDATA[opensso openam liferay tomcat portal sso integrate single-signon]]></category>
		<category><![CDATA[Portal]]></category>
		<category><![CDATA[single sign-on]]></category>
		<category><![CDATA[sso]]></category>
		<category><![CDATA[Tomcat]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=2267</guid>
		<description><![CDATA[This article will demonstrate how to integrate OpenSSO/OpenAM with Liferay Portal to achieve single-signon.
Liferay Portal and OpenSSO both require a minimum 1.5 JVM, but I would recommend using Java 6 (as Java 1.5 reached its End of Service Life in October, 2009).  Make sure that your JAVA_HOME environment variable is correctly set to point [...]]]></description>
			<content:encoded><![CDATA[<p>This article will demonstrate how to integrate <strong>OpenSSO</strong>/<strong>OpenAM</strong> with <strong>Liferay Portal</strong> to achieve single-signon.</p>
<p>Liferay Portal and OpenSSO both require a minimum 1.5 JVM, but I would recommend using Java 6 (as Java 1.5 reached its End of Service Life in October, 2009).  Make sure that your <code>JAVA_HOME</code> environment variable is correctly set to point to your Java 6 installation.</p>
<p>For OpenSSO to work correctly with Liferay Portal, both servers need to be running in the same domain.  To solve this issue while running both servers on a single machine, edit the hosts file (<code>/etc/hosts</code> or <code>%SystemRoot%\system32\drivers\etc\</code>) and add/update your localhost entry:<br />
<code>127.0.0.1	localhost localhost.example.com</code><br />
where <code>example.com</code> is your actual domain.</p>
<p><strong>Install Liferay Portal</strong><br />
Liferay Portal is an open source portal.  Liferay comes in two editions, <strong>Enterprise Edition (EE)</strong> and <strong>Community Edition (CE)</strong>.<br />
For a full discussion on the differences, see <a href="http://www.liferay.com/products/liferay-portal/ee/faq">this</a>.  Downloads are available <a href="http://sourceforge.net/projects/lportal/files/">here</a>.  For this article, I used <strong>Liferay Portal 5.2.3 CE</strong> bundled with <strong>Tomcat 6.0 (6.0.18)</strong>.</p>
<p>Installation consisted of:</p>
<ol>
<li>Unzip <code>liferay-portal-tomcat-6.0-5.2.3.zip</code> to a directory.  This will create a <code>liferay-portal-5.2.3</code> folder.
<ul>
<li>On Linux/MacOS, you will need to add execute permissions to all of the shell scripts in the bin directory:  <code>chmod +x *.sh</code></li>
</ul>
</li>
<li>In <code>liferay-portal-5.2.3/tomcat-6.0.18/bin/</code>, executing <code>startup.sh</code> (or <code>startup.bat</code>) will start Tomcat, and deploy Liferay Portal.</li>
<li>Open a browser to <code>http://localhost.example.com:8080</code>, and you will see the Liferay login page.  You can login with <code>test@liferay.com/test</code>.</li>
</ol>
<p><strong>Install OpenSSO/OpenAM</strong><br />
OpenSSO is an open source access management and federation server platform.  Announced by Sun Microsystems in July 2005, OpenSSO was based on Sun Java System Access Manager, and was the core of Sun&#8217;s commercial access management and federation product, OpenSSO Enterprise (formerly Sun Access Manager and Sun Federation Manager).  Oracle completed their acquisition of Sun Microsystems in February 2010 and announced that OpenSSO would no longer be their strategic product. OpenSSO will continue to be developed and supported by ForgeRock under the name of OpenAM (see <a href="http://www.h-online.com/open/news/item/Oracle-kills-OpenSSO-Express-ForgeRock-steps-in-939634.html">this</a>).</p>
<p>I downloaded the latest OpenAM build (<strong>OpenAM Snapshot 9.5.1 RC1</strong>) from <a href="http://www.forgerock.com/downloads.html">here</a>.  For consistency, I will refer to OpenSSO as OpenAM for the remainder of this article.</p>
<p>As OpenAM also requires a servlet container, I downloaded the latest Tomcat (6.0.29) from <a href="http://tomcat.apache.org/download-60.cgi">here</a>.<br />
Installation of the Tomcat server consisted of:</p>
<ol>
<li>Unzip <code>apache-tomcat-6.0.29 zip</code> file.  This will create an <code>apache-tomcat-6.0.29</code> folder.</li>
<li>As both Liferay Portal and OpenAM will be running on the same machine, I needed to update the ports that the OpenAM Tomcat server was using.
<ul>
<li>Edit <code>apache-tomcat-6.0.29/conf/server.xml</code>.  I changed all of the ports from <code>8xxx</code> to <code>9xxx</code>.  For example, <code>8080</code> to <code>9080</code>, <code>8443</code> to <code>9443</code>, etc.</li>
<li>On Linux/MacOS, you will need to add execute permissions to all of the shell scripts in the bin directory:  <code>chmod +x *.sh</code></li>
</ul>
</li>
<li>Edit <code>catalina.sh</code> (or <code>catalina.bat</code>) and add the following line to the start of the file, after the comment block listing the various Environment Variable Prequisites:<br />
<strong>Linux/MacOS</strong>:	<code>JAVA_OPTS="$JAVA_OPTS -Xmx1024m -XX:MaxPermSize=256m"</code><br />
<strong>Windows</strong>:		<code>set JAVA_OPTS="%JAVA_OPTS% -Xmx1024m -XX:MaxPermSize=256m"</code></li>
</ol>
<p>Installation of OpenAM consisted of:</p>
<ol>
<li>Unzip <code>openam_snapshot_951RC1.zip</code> to a directory.  This will create an <code>opensso</code> folder.</li>
<li>Copy the <code>opensso.war</code> from <code>opensso/deployable-war/</code> to <code>apache-tomcat-6.0.29/webapps/</code>.</li>
<li>In <code>apache-tomcat-6.0.29/bin/</code>, execute <code>startup.sh</code> (or <code>startup.bat</code>) to start Tomcat and deploy OpenAM.
<ul>
<li>After Tomcat has deployed OpenAM, you will see the exploded war file as <code>apache-tomcat-6.0.29/webapps/opensso</code>.</li>
</ul>
</li>
<li>Open a browser to <code>http://localhost.example.com:9080/opensso</code>, which should redirect you to <code>http://localhost.example.com:9080/opensso/config/options.htm</code>,<br />
to complete the OpenAM configuration.</li>
<li>You should see the OpenAM configuration options page.  Under <em>Custom Configuration</em> click <em>Create New Configuration</em>. Enter the following:
<ul>
<li>Default User Password &#8212; password</li>
<li>Server Settings &#8212; default entries are ok</li>
<li>Configuration Data Store Settings &#8212; select <em>First Instance</em>, select <em>OpenAM</em> as <em>Configuration Data Store</em>, leave other entries</li>
<li>User Data Store Settings &#8212; select <em>OpenAM User Data Store</em></li>
<li>Site Configuration &#8212; select <em>No</em></li>
<li>Default Policy Agent User &#8212; policy01</li>
<li>Configurator Summary Details &#8211; click <em>Create Configuration</em>.  This will create the configuration for your OpenAM server under <code>~/opensso</code> (or <code>c:\Documents and Settings\{username}\opensso</code>).</li>
</ul>
</li>
<li>When this completes, in the <em>Configuration Complete</em> dialog, click <em>Proceed to Login</em>, which should now redirect you to <code>http://localhost.example.com:9080/opensso/UI/Login</code>.<br />
Type <strong>amAdmin</strong> as the username, <strong>password</strong> as the password, and click <em>Log In</em>.  You should now see the <strong>OpenAM Console</strong>.</p>
<ul>
<li>For detailed information about the OpenAM Console, see <a href="https://wikis.forgerock.org/confluence/display/openam/Home">this</a> and <a href="http://wikis.sun.com/display/OpenSSO/Sun+OpenSSO+Enterprise+8.0+Documentation+Center">this</a>.  A detailed discussion of all of the functionality of OpenAM is beyond the scope<br />
of this article.</li>
</ul>
</li>
<li>You can now delete the <code>opensso.war</code> file from <code>apache-tomcat-6.0.29/webapps/</code> directory.</li>
</ol>
<p><strong>Additional OpenAM Configuration</strong><br />
To get OpenAM to work correctly with Liferay, you need to set <em>Encode Cookie Value</em> to <strong>Yes</strong>.  This will prevent infinite redirection between Liferay and OpenAM on login.</p>
<ol>
<li>In the OpenAM Console, select the <em>Configuration</em> tab.</li>
<li>Select the <em>Servers and Sites</em> tab.</li>
<li>Click <em>Default Server Settings</em>.</li>
<li>Select the <em>Security</em> tab.</li>
<li>In the <em>Cookie</em> section, select the <strong>Yes</strong> checkbox beside <em>Encode Cookie Value</em>.</li>
<li>Click <em>Save</em>.</li>
</ol>
<p>Other people have reported having to set the <code>com.iplanet.am.cookie.c66Encode</code> property to <strong>true</strong> as well, to resolve the infinite redirection problem:</p>
<ol>
<li>In the OpenAM Console, select the <em>Configuration</em> tab.</li>
<li>Select the <em>Servers and Sites</em> tab.</li>
<li>Click <em>Default Server Settings</em>.</li>
<li>Select the <em>Advanced</em> tab.</li>
<li>Find the <code>com.iplanet.am.cookie.c66Encode</code> property, and set the value to <strong>true</strong>.</li>
<li>Click <em>Save</em>.</li>
</ol>
<p>Before updating Liferay to use OpenAM, I recommend adding the default Liferay user, <strong>test@liferay.com</strong>, to OpenAM.</p>
<ol>
<li>In the OpenAM Console, select the <em>Access Control</em> tab.</li>
<li>Click the <code>/ (Top Level Realm)</code> realm.</li>
<li>Select the <em>Subjects</em> tab.</li>
<li>Click <em>New&#8230;</em></li>
<li>Setup the default Liferay user:
<ul>
<li>ID &#8212; joebloggs</li>
<li>First Name &#8212; Joe</li>
<li>Last Name &#8212; Bloggs</li>
<li>Full Name &#8212; Joe Bloggs</li>
<li>Password &#8212; password</li>
<li>Click <em>OK</em> to create the user.</li>
</ul>
</li>
<li>Click <em>Joe Bloggs</em> to add the email address.  Enter <code>test@liferay.com</code> for the <em>Email Address</em>, and click <em>Save</em>.</li>
</ol>
<p><strong>Integrate Liferay Portal with OpenAM</strong><br />
Now you are ready to update Liferay Portal to integrate with OpenAM for authentication.</p>
<ol>
<li>If Liferay is running, shut it down (<code>bin/shutdown</code>).</li>
<li>Create a new file, called <strong>portal-ext.properties</strong>, in your Liferay directory, under <code>liferay-portal-5.2.3/tomcat-6.0.18/webapps/ROOT/WEB-INF/classes/</code>.</li>
<li>Edit this file, and add the following properties:<br />
<code>open.sso.auth.enabled=true<br />
open.sso.login.url=\</p>
<p>http://localhost.example.com:9080/opensso/UI/Login?goto=\</p>
<p>http://localhost.example.com:8080/c/portal/login</p>
<p>open.sso.logout.url=\</p>
<p>http://localhost.example.com:9080/opensso/UI/Logout?goto=\</p>
<p>http://localhost.example.com:8080/web/guest/home</p>
<p>open.sso.service.url=http://localhost.example.com:9080/opensso<br />
open.sso.screen.name.attr=uid<br />
open.sso.email.address.attr=mail<br />
open.sso.first.name.attr=givenname<br />
open.sso.last.name.attr=sn</code></li>
<li>Start Liferay (<code>bin/startup</code>).</li>
<li>Once Liferay has started, open a browser to <code>http://localhost.example.com/8080</code>, and you should be redirected to the OpenAM login page<br />
(<code>http://localhost.example.com:9080/opensso/UI/Login</code>).  Enter <strong>joebloggs</strong> for the <em>User Name</em>, and <strong>password</strong> for the <em>Password</em>.  Click <em>Log In</em>.</li>
</ol>
<p>You will be authenticated against OpenAM, and redirected to Liferay.</p>
<p>Now that Liferay is using OpenAM for authentication, if you create a new user in OpenAM, that user will also be created in Liferay on the first log in.  That newly created user in Liferay will only have the basic information filled in &#8211; First Name, Last Name, Screenname, Email Address &#8211; and will have the default Roles, Groups, and Organizations assigned.</p>
<p>This article demonstrated a basic integration with OpenAM and Liferay Portal.  Now you are ready to explore more advanced topics include configuring OpenAM to use an existing LDAP or other user datastore, creating a custom datastore plugin (e.g. JDBC) for OpenAM, setting up a separate realm for Liferay users, as well as taking advantage of OpenAM for incoming and outbound SSO in conjuction with Liferay Portal.  Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2010/08/16/integrating-opensso-openam-with-liferay-portal-on-tomcat/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Spring @PathVariable Head-slapper</title>
		<link>http://www.objectpartners.com/2010/08/12/spring-pathvariable-head-slapper/</link>
		<comments>http://www.objectpartners.com/2010/08/12/spring-pathvariable-head-slapper/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 14:01:43 +0000</pubDate>
		<dc:creator>jwarren</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Controller]]></category>
		<category><![CDATA[PathVariable]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=2174</guid>
		<description><![CDATA[Recently some peers and I spent a little time spinning around a goofy little annotation trick that Spring uses, that bit us because of the way p-code is generated. It all makes sense afterwards, but at the time it was a little frustrating and puzzling.
Taken straight from the Spring documentation, the following example shows a [...]]]></description>
			<content:encoded><![CDATA[<p>Recently some peers and I spent a little time spinning around a goofy little annotation trick that Spring uses, that bit us because of the way p-code is generated. It all makes sense afterwards, but at the time it was a little frustrating and puzzling.</p>
<p>Taken straight from the Spring <a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#mvc-ann-requestmapping-uri-templates">documentation</a>, the following example shows a similar use to what we&#8217;d done.</p>
<blockquote><pre><code>@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable String ownerId, Model model) {</code>
  Owner owner = ownerService.findOwner(ownerId);
  model.addAttribute("owner", owner);
  return "displayOwner";
}</code></pre>
</blockquote>
<p>Our code looked pretty much the same, with our names and useful bits, of course. Quickly scanning that documentation shows that our syntax was accurate. The compiler didn&#8217;t complain, and sometimes it worked. Where it got confusing is that the code would work just fine when run in an integration test using HTTPUnit (in the IDE and run by Ant) and in a Servlet engine (Tomcat, specifically) when launched from Eclipse. Some people had success when deploying to Tomcat using an Eclipse-created WAR file, but some people experienced failure. Everyone failed when using the Ant-built WAR file.</p>
<p>When the error occurred, the root cause of the Exception caught ultimately was the following:</p>
<blockquote><p><code>java.lang.IllegalStateException: No parameter name specified for argument of type [java.lang.String], and no parameter name information found in class file either.</code></p></blockquote>
<p>When you look at the code, you can see the @RequestMapping has the appropriate {variable} notation, and that the parameter list has a variable of the same name, of type String, as expected (other types can be used, but ours was a String also).</p>
<p>A peek at the Ant script gave a clue to the solution. Changing the javac target&#8217;s debug attribute to &#8220;on&#8221; allowed the Ant-built WAR file to also deploy and run with success. That&#8217;s when the head-slapping began.</p>
<p>When the code is compiled with debug, as it is when working in the IDE, and apparently is sometimes when exporting from the IDE (probably some of us have a workspace setting different than the others), the name of the parmeter is available to the JVM at runtime. When the code is compiled without debugging, as the Ant script was doing, then the parameter name is lost, truncated by the p-code generator based on its type and order and other factors.</p>
<p>Adding the name to the @PathVariable annotation allows the runtime to find the correct parameter even without debug information in the class file. Again, straight from the same documentation, just a couple paragraphs down from the other example shows the more correct way to declare the @PathVariable. Right above the example on their page is a discrete mention of this fact, and a recommendation that you specify the name. Below is the subtle difference in the declaration, one that makes all the difference.</p>
<blockquote><pre><code>@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable("ownerId") String ownerId, Model model) {
  // implementation omitted
}</code></pre>
</blockquote>
<p>While it&#8217;s convenient to have Spring work this out for you during the development cycle, it seems more appropriate that the value be required which can be achieved simply by removing the default from the annotation. Since it isn&#8217;t that way, it&#8217;s certainly a good practice to get into to always provide the name (or names) of your path variable when annotating your controllers in Spring.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2010/08/12/spring-pathvariable-head-slapper/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Developer Bits on Sustainable Computing</title>
		<link>http://www.objectpartners.com/2010/08/09/developer-bits-on-sustainable-computing/</link>
		<comments>http://www.objectpartners.com/2010/08/09/developer-bits-on-sustainable-computing/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 15:01:08 +0000</pubDate>
		<dc:creator>bkarels</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[consulting]]></category>
		<category><![CDATA[green development]]></category>
		<category><![CDATA[sustainable computing]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=2245</guid>
		<description><![CDATA[The world is trying to &#8220;green up&#8221; our cars, light bulbs, clothing, and even our laptops.  Apple is pushing the greenest laptops of all time.  Google goes lead free and commits to 100% recycling practices.  Massive data centres recycle water and implement radical new energy efficient cooling technologies.  But, as consultants, [...]]]></description>
			<content:encoded><![CDATA[<p>The world is trying to &#8220;green up&#8221; our cars, light bulbs, clothing, and even our laptops.  Apple is pushing the greenest laptops of all time.  Google goes lead free and commits to 100% recycling practices.  Massive data centres recycle water and implement radical new energy efficient cooling technologies.  But, as consultants, we primarily write code &#8211; what role do we play in sustainable computing?  Some will argue that our role here is best served by the principle of, &#8220;Every little bit.&#8221;.</p>
<p>A quick search of the Internet reveals thousands upon thousands of books, articles, and studies focused on becoming more efficient.  Blogs on the agile methodology preach bringing speed to development and TDD strives to make the QA cycle a blip on the project timeline.  <a href="http://grails.org/">Grails</a> and <a href="http://www.springsource.org/roo">Spring Roo</a> bring projects and prototypes online in minutes rather than days.  It cannot be argued that more efficient development reduces cost and makes good business sense &#8211; but are there other benefits as well?</p>
<p><strong>Doing the same work in less time</strong><br />
As developers our days mandate carbon output &#8211; what we get in return for our expenditure is variable.  As we develop we need to be conscious about making the most of our machines each minute that we are in front of them as well as time we spend away from them.  An few moments of consideration can save thousands of watts of power each day.  Do you stare at your console while compiling or do you execute other tasks during that time?  Do you practice <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a> to remove much of the overhead of manual testing?  Do you hibernate or fully shut down your machine when leaving for meetings or lunch?  These are all small things by themselves, but few million persons doing them everyday makes a very large difference.</p>
<p>Conserving bandwidth<br />
Each bit we push and pull across the wire has a cost associated with it.  As such, it is in everyone&#8217;s best interest to conserve bandwidth (unless you are in the business of selling bandwidth) at every turn.  Servers will do less work, switches and firewalls breathe more easily, pages load faster, and all while using less energy and costing your client less.  Here again, the work we do can have a large impact over time.</p>
<ul>
<li>Have we minimized and optimized CSS and JavaScript?</li>
<li>Are we serving only compressed images?</li>
<li>Have we done all we can to leverage client side caching?</li>
<li>Is Ajax being used to reduce full page loads?</li>
</ul>
<p>All of these things result in more speed for the user, less cost for the client, and less carbon out of the pipe.  </p>
<p><strong>Optimising code</strong><br />
Servers are like athletes &#8211; the harder they work the more energy they need to consume to keep going.  World class athletes have figured out that at a certain level of performance even the smallest gains in efficiency determine victory or loss.  Cyclists shave fractions of grams of weight off each component to save weight, then test in wind tunnels to reduce drag.  Swimmers now wear full body suits of technologically advanced material modeled after shark skin to reduce friction in the water.  They do this all to finish fractions of a second faster than they could before.  Can we learn from the world&#8217;s elite athletes and reduce total clock cycles necessary to compete a task?</p>
<p>Here again we have a situation where everyone wins.  When we fully optimize our code we will use fewer resources to complete the same set of tasks.  Our code will be faster, the user experience better, client costs reduced, and less energy will be wasted.  While techniques for code optimization is beyond the scope of this writing it is something that we as developers need to be conscious of and work to master.</p>
<p><strong>Summary</strong><br />
While the methods and mechanisms that can be used to make software an integral part of sustainable computing are seemingly infinite, we can all work to implement a small, finite set of options every day and together make a huge difference.  Whether we simply add break statements to for loops or implement reduced carbon data centres, we can all do something everyday to reduce the number of bits of carbon we produce.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2010/08/09/developer-bits-on-sustainable-computing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How Do Annotations Work?</title>
		<link>http://www.objectpartners.com/2010/08/06/how-do-annotations-work/</link>
		<comments>http://www.objectpartners.com/2010/08/06/how-do-annotations-work/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 15:03:36 +0000</pubDate>
		<dc:creator>jwarren</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Annotations]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=2215</guid>
		<description><![CDATA[Recently, I was giving an overview of Java to a bunch of C/C++ developers to help them bridge the gap. Mostly I ended up assuring them that they knew what they were doing and filled in very few gaps. I did enlighten them on some of the fun things like Collections and some confusing things [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I was giving an overview of Java to a bunch of C/C++ developers to help them bridge the gap. Mostly I ended up assuring them that they knew what they were doing and filled in very few gaps. I did enlighten them on some of the fun things like Collections and some confusing things like Date. We covered lots of ground in those few hours of presentation and banter, but one question I couldn&#8217;t answer was about annotations.</p>
<p>I had put a few code samples in my presentation that I&#8217;d pulled from a recent project. Stuff I knew worked, so I wouldn&#8217;t be surprised with any hastily thrown together code with style, format, or syntax errors. One of the classes was an annotated Spring class, with some code not too much unlike this snippet:</p>
<blockquote><pre><code>@Autowire private SomeBean someBean;</code></pre>
</blockquote>
<p>We went down a path of queries related to how to create new ones, which is a simple @interface declaration like the following.</p>
<blockquote><pre><code>public @interface Foo{ }</code></pre>
</blockquote>
<p>They queried how to put them in the code, and I pointed back to the example. I also showed them some other examples related to using them on class definitions, methods, and on parameter values, as defined by the @Target annotation and ElementType enum. We looked at examples of commonly encountered annotations such as @Deprecated and @SuppressWarning among others. We even looked at the different uses of @Retention and discussed the RetentionPolicy enum; how SOURCE is used to provide hints for the compilers (and IDEs) but aren&#8217;t retained in the compiled code, how CLASS is retained in the code but not necessarily available at runtime, and how RUNTIME is certain to be available at runtime.</p>
<p>Then they wanted to know how to use them. Not how to implement them, but how to access the @Retention(RetentionPolicy.RUNTIME) declared annotations.</p>
<p>I hated to admit that I didn&#8217;t really know. I knew there weren&#8217;t any frequently used utility classes for grabbing annotations, but that there were annotation-related methods on the reflection classes. I knew in practice <i>that</i> they were used, but not directly <i>how</i>, so I set out to learn so I could completely satisfy their questions.</p>
<p>To be sure, I use annotations all day long. I probably @Deprecate a method every day, sometimes permanently, sometimes just to quickly find uses as Eclipse is faster at adding them to problems than it is at searching. Any class that extends or implements another is surely fraught with @Override annotations. I probably write twice as many @Test annotated methods than anything else. I have @Autowire in nearly every function-full class of a Spring application, and every Hibernate project is filled with the @Column and all the other JPA annotations.</p>
<p>What I hadn&#8217;t had to do, though, was write any code to find and use annotations. I can&#8217;t even recall passing an annotation to a method to try to identify them. After much digging, I ascertained that indeed there aren&#8217;t any utility classes that aid in finding or using annotations. There&#8217;s got to be some heavy work behind the classpath scanning in frameworks like Spring and Hibernate to find annotated classes and methods. I&#8217;m not quite prepared to dive into that, but let&#8217;s look at some simple cases of using annotations.</p>
<p>First, a simple set of annotations should be built for our various uses. Let&#8217;s take one for each kind of element: class, method, and property.</p>
<blockquote><pre><code>@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME)
public @interface TypeAnnotation { }

@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME)
public @interface FieldAnnotation { }

@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME)
public @interface MethodAnnotation { }

@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME)
public @interface ParameterAnnotation { }</code></pre>
</blockquote>
<p>There are actually eight different ElementTypes that can be used, but these are surely the most common, and are certainly enough to provide a thorough example. I&#8217;ll expand on the simple examples here, but I wanted to first discuss the annotations on our annotations.</p>
<p>The @Target annotation lets the compiler know where the annotation may be used. Compilers and IDEs will warn if the annotation is used on the wrong type of element. If the @Target is left off, the annotation may be applied anywhere without warning. The ElementType must be defined, and allows multiple, but not duplicate entries. Multiple ElementType allow the annotation to be used in any of those instances.</p>
<p>The @Retention annotation lets the compiler know how long to maintain the annotation. As mentioned, there are three RetentionPolicy values that are allowed, SOURCE, CLASS, and RUNTIME. If the @Retention annotation is used, a RetentionPolicy must be declared. If the @Retention annotation is not used, the default is CLASS, which will keep the annotation in the compiled class, but it may not be available to the runtime.</p>
<p>The @interface is used to define the annotation. The name of the interface is then used when putting the annotation in source later. Other than that modification to the naming, the annotation is declared much like any other interface, in that you can declare member variables and methods. It is important to note these aren&#8217;t intended for use as regular interfaces, so there are some other restrictions. Member variables must be public, static, or final, but may be of any valid type. Only public and abstract modifiers are allowed on methods. And only a small set of return types are allowed for methods; strictly, primitives, Strings, enumerations, other annotations are allowed, or 1-dimensional arrays of those types.</p>
<p>One more bit, if you want to make an annotation that takes a value without a name, you must declare a member variable named &#8220;value.&#8221; That is, like @SuppressWarnings(&#8220;unchecked&#8221;). It can be a single value or array, depending on your needs. If you define it as an array you can provide several values by wrapping them in squiggly-braces like @SuppressWarnings({&#8220;unchecked&#8221;,&#8221;unused&#8221;}) would do. If you do not wish to use &#8220;value,&#8221; the variable must be explicitly declared (and, truly, value is optional) such as @SuppressWarnings(value=&#8221;unchecked&#8221;).</p>
<p>Other differences will become apparent as the article continues, and as you play with annotations of your own. In trying to keep the article short, and not delve too much into every possible use case, I&#8217;ll show some simple uses, point out some of these other nuances of @interface definitions, and leave it to the reader to expand on that.</p>
<p>We&#8217;ve got some trivial annotations set up, so let&#8217;s apply them to a simple class.</p>
<blockquote><pre><code>@TypeAnnotation class Foo {
  @FieldAnnotation public Object object;

  @MethodAnnotation public Object setObject(@ParameterAnnotation final Object object){
    this.object = object;
  }
}</code></pre>
</blockquote>
<p>If you&#8217;ve used annotations in your code, you&#8217;ve probably used some or all of these kinds of annotations. Certainly, the annotations used before have actually done something. Before we get into doing something, let&#8217;s try to find the annotations at runtime.</p>
<p>I mentioned previously that Spring and Hibernate and other frameworks have functionality to scan classes in the classpath for annotations. If you&#8217;ve taken a look at how they do it (they&#8217;re both open-source projects, so dig in&#8230;) or hit a search engine looking for the answer, you probably have seen or correctly surmised that interrogating a classpath is not as easy as it seems. As such, I&#8217;m not going to try to lay that out here (sorry to whet your appetite), but instead will use the annotations in a more explicit manner.</p>
<p>First, a simple method to see if the annotation exists, just as an example of accessing them.</p>
<blockquote><pre><code>public boolean isAliased(final Class<?> type) {
    final TypeAnnotation typeAnnotation = type.getAnnotation(TypeAnnotation.class);
    return (typeAnnotation != null);
}</code></pre>
</blockquote>
<p>The trivial example interrogates the provided class using the Class.getAnnotation() method. There&#8217;s a similar Class.getAnnotations() that will return an array (zero-length if empty) of the annotations if you want to check for more than one. This would be used very simply by something like the following snippets, the first returning true, and the other false.</p>
<blockquote><pre><code>isAliased(Foo.class);
isAliased("yes, a literal".getClass());</code></pre>
</blockquote>
<p>It isn&#8217;t a terribly useful example, so let&#8217;s make a method that does a little more. First, let&#8217;s expand one of our annotations to give us some runtime differences from source.</p>
<blockquote><pre><code>@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME)
public @interface FieldAnnotation { String value(); }</code></pre>
</blockquote>
<p>Here we&#8217;ve changed our FieldAnnotation to require we provide some additional information in the form of a String property. It&#8217;s been named &#8220;value&#8221; for convenience, so we can use it without forcing the use of the name. Note that it looks like a method declaration, but we&#8217;ll be treating it as both a variable and a function.</p>
<p>If we applied the same annotation to the same class as before, we&#8217;d run into an error as we&#8217;re missing a required property. Let&#8217;s update our class a little and give this value some functionality.</p>
<blockquote><pre><code>@TypeAnnotation class Foo {
    @FieldAnnotation("here") public Object object;

    @FieldAnnotation("there") public Object other;

    @MethodAnnotation public Object setObject(@ParameterAnnotation final Object object){
      this.object = object;
    }
}</code></pre>
</blockquote>
<p>Again, the class isn&#8217;t terribly useful, but we now have two annotated member variables with different names. Let&#8217;s make a quick method to set those values by their annotation name, ignoring their object name.</p>
<blockquote><pre><code>void setPropertyByAnnotationName(final Object object, final String name, final Object value) {
    final Field[] fields = object.getClass().getDeclaredFields();
    for (final Field field : fields) {
        final FieldAnnotation fieldAnnotation = field.getAnnotation(FieldAnnotation.class);
        if(fieldAnnotation!=null &#038;&#038; name.equals(fieldAnnotation.value()){
            field.set(object, value);
        }
    }
}</code></pre>
</blockquote>
<p>Lots of spots for error there, as there&#8217;s no null checking, it assumes the field is accessible, and the object is of the right type&#8230;but it matches our simple Foo class, so we&#8217;ll let it go for now. As with the Class, there is a Field.getAnnotations() in case you&#8217;d like to investigate more than one annotation. What we have is a method that interrogates our object (first one) to look for fields (member variables) annotated with our FieldAnnotation. When it finds one, it checks to see if the name matches the value (note it looks like a function here) in the annotation. When there&#8217;s a match, it sets the value as provided by our value parameter. This would be used simply as thus:</p>
<blockquote><pre><code>Foo foo = new Foo();
setPropertyByAnnotationName(foo, "here", "this is set!");
setPropertyByAnnotationName(foo, "there", Calendar.getInstance());</code></pre>
</blockquote>
<p>With this, we should end up with a Foo.object that contains the String &#8220;this is set!&#8221; and Foo.other that contains a Calendar with the current time in it.</p>
<p>One might desire to ask what good is that? We surely have access to Foo.object and Foo.other directly in this class, but it will certainly be the case that we might not have such access in other classes. Additionally, with the annotation, we don&#8217;t even really need to care that it&#8217;s a Foo object. We could very easily declare another class with similar annotated members and have their fields accessed with the same method we just created. This is roughly how Spring&#8217;s @Autowire works. They, of course, do a bit more in terms of recognizing names and types and whatnot without explicit definition, but this is the crux of it.</p>
<p>Accessing methods is done pretty much the same way. Let&#8217;s use the @MethodAnnotation to use the setter we&#8217;ve got. Note that calling methods is a lot trickier because the annotation itself has no way to ensure that the parameter list is correct. It is up to the method using reflection to determine if the prototype of the method is something it can work with. For brevity, I&#8217;ll leave this using the original annotation, which means every annotated method will be called and its value set to the same thing; the same modifications on the @FieldAnnotation can be done here for similar functionality.</p>
<blockquote><pre><code>void callMethodByAnnotation(final Object object, final Object value) {
    final Method[] methods = object.getClass().getDeclaredMethods();
    for (final Method method : methods) {
        final MethodAnnotation methodAnnotation = method.getAnnotation(MethodAnnotation.class);
        if(fieldAnnotation!=null){
            method.invoke(object, value);
        }
    }
}</code></pre>
</blockquote>
<p>Again, a slew of opportunities for errors with missing null-checks, accessibility, and the mentioned parameter list validation. Also, there is a similar Method.getAnnotations() method that will return an array of annotations in case you want to check for more than one. This method simply checks the class for all methods with the right annotation, and if found, tries to invoke the method with the provided object as the parameter. Again, with this functionality you can find methods in classes without caring about their real names. This, again with more guts, is how Spring handles its @RequestMapping methods in @Controller classes. As before, this can be implemented with this simple </p>
<blockquote><pre><code>Foo foo = new Foo();
callMethodByAnnotation(foo, ""this is set!");</code></pre>
</blockquote>
<p>In the end, we end up with Foo.other set to a String saying &#8220;this is set!&#8221; using the annotation instead of calling the method directly.</p>
<p>Trickier is handling the ElementTypePARAMETER annotations. This is because there&#8217;s no direct reflection access to the parameter list. There are a few arrays that can be gathered to help identify the parameters, but the parameters are actually only realized when you use the Method.invoke(), so to use these, you need to handle all of the parameters by annotation, name, or type. A typical use would be some form of IOC or other runtime association of parameters to other values available to the application. </p>
<p>Why this is tricky is that there is no opportunity, except perhaps inside an invoked method, to access the parameter annotations when calling the methods directly. With that understanding, we can see that these are best paired with annotated classes or methods, where the functions are going to be called indirectly, and therefore there is time to interrogate the Method for annotations before calling Method.invoke. That said, let&#8217;s modify our other method-calling method to take a map of values to tie to our parameters.</p>
<p>Before we do, though, this brings about another sticky bit. Unlike classes, member variables, and methods, parameters don&#8217;t always keep their names. When classes are compiled, the parameters are reduced essentially to a type and order. The variable name associated with it is not kept with the method unless the class is compiled with debugging symbols. As such, like we did for the fields, we&#8217;ll add a required value to represent the name of the parameter. This way, the annotation will maintain the value that we&#8217;ll use to pull values from our map, and it won&#8217;t matter if debug is enabled or not; our annotation will continue to work.</p>
<blockquote><pre><code>@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME)
public @interface ParameterAnnotation { String value(); }</code></pre>
</blockquote>
<p>And since it&#8217;s required with no default, we&#8217;ll have to change our class appropriately.</p>
<blockquote><pre><code>@TypeAnnotation class Foo {
    @FieldAnnotation("here") public Object object;

    @FieldAnnotation("there") public Object other;

    @MethodAnnotation public Object setObject(@ParameterAnnotation("inside") final Object object){
        this.object = object;
    }
}</code></pre>
</blockquote>
<p>And we&#8217;ll modify the method to take advantage of that annotation.</p>
<blockquote><pre><code>public void callMethodByAnnotation(final Object object, final Map<String, Object> map) {
    final Method[] methods = object.getClass().getDeclaredMethods();
    for (final Method method : methods) {
        final MethodAnnotation methodAnnotation = method.getAnnotation(MethodAnnotation.class);
        if (methodAnnotation != null) {

            final Annotation[][] parameterAnnotations = method.getParameterAnnotations();
            final Object[] parameters = new Object[parameterAnnotations.length];
            for (int i = 0; i < parameterAnnotations.length; i++) {
                parameters[i] = null;

                final Annotation[] annotations = parameterAnnotations[i];
                for (final Annotation annotation : annotations) {
                    if (annotation instanceof ParameterAnnotation) {
                        parameters[i] = map.get(((ParameterAnnotation) annotation).value());
                    }
                }
            }
            method.invoke(object, parameters);
        }
    }
}</code></pre>
</blockquote>
<p>Note the busy work necessary to grab the annotation. The annotations come from an array of arrays. The first dimension is one for each parameter, and the second dimension is the array of annotations for the parameter at that first dimension. If there are no parameters, the first dimension array is zero-length. For each parameter, if there are no annotations, that second dimension array is zero length. There is a related Method.getParameterTypes() that could be used to be certain that the type in the map was compatible with the type in the parameter, but ours is an Object, so we can be a little sloppy.</p>
<p>The new method can be used very much like the other, except we'll pass the parameters in a Map. We could, of course, use any mechanism for keeping track of the things that could be put in the parameter list. If you've used Spring to annotate a @Controller with @RequestMethod methods, you'll notice that you can just toss in a whole slew of parameters such as ModelMap or HttpServletRequest and it will figure them out by type.</p>
<blockquote><pre><code>Map map = new Map();
map.put("inside", "this is set!");
Foo foo = new Foo();
callMethodByAnnotation(foo,map);</code></pre>
</blockquote>
<p>Same caveats as before regarding shortcuts taken for brevity... Now when we call our method, it will check our map for the value. If it doesn't find an element in the map that matches our annotation name, it puts null in the parameter list. As before, our Foo.other will have a String with the value "this is set!" when we're done.</p>
<p>That seems like a lot of busy work to make sense of annotations. Really it's a lot of fluff code around it to make it understandable. Really, the magic lies in the getAnnotations() or getAnnotation() methods on the Class and the reflection classes Field and Method, and the Method.getParameterAnnotations() method. And, of course, our trivial examples don't carry much insight into any kind of usefulness, so let's expand on this and make a one-class annotated XML parser. A very simple one, mind you.</p>
<p>Parsing XML is a pain that way too many of us go through. There are plenty of tools to help us do this, so this isn't intended as a replacement or any kind of competition for them. It's just familiar territory, and one I think I can squeak in a small pair of classes for a solid example of annotation use.</p>
<p>Consider this fairly trivial XML, where we have  a Foo element with a single attribute, id, and a nested element also named Foo.</p>
<blockquote><pre><code>&lt;Foo id="alpha"&gt;
    &lt;Foo/&gt;
&lt;/Foo&gt;</code></pre>
</blockquote>
<p>The astute among us can quickly envision a likewise trivial POJO that would do the same. I'm making public members for brevity; for real, we'd use getters and setters, right?</p>
<blockquote><pre><code>class Foo {
    public String id;
    public Foo foo;
}</code></pre>
</blockquote>
<p>With this class in mind, we can see we'll need a couple annotations to handle identifying the class and our members.</p>
<blockquote><pre><code>@Target({ElementType.TYPE, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME)
@interface XMLElement { String value() default ""; }

@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME)
@interface XMLAttibute { String value() default ""; }</code></pre>
</blockquote>
<p>A quick word about the two noticeable differences from the previous examples. First, we'll note that the XMLElement has been annotated with two ElementType targets. This allows the same attribute to be used to identify types and members, as XML elements are often neatly identified with POJOs. Also, I've added a default to each. This is both to show what it looks like and allow us to optionally rename the item in question. A small annoyance with the defaults is that there is no <i>null</i> value. When the value is an array, you can declare an empty list as the default, but that's not really null either.</p>
<blockquote><pre><code>@interface ArrayExampleAnnotation { String[] value() default {}; }</code></pre>
</blockquote>
<p>This allows us to alter our class to add the annotations as follows:</p>
<blockquote><pre><code>@XMLElement class Foo {
    @XMLAttribute public String id;
    @XMLElement public Foo foo;
}</code></pre>
</blockquote>
<p>We could be more explicit and annotate it thusly:</p>
<blockquote><pre><code>@XMLElement("Foo") class Foo {
    @XMLAttribute("id") public String id;
    @XMLElement("Foo") public Foo foo;
}</code></pre>
</blockquote>
<p>Or even make the POJO and XML a little less tightly coupled by changing the POJO names from the expected XML names (this is where the value makes more sense!):</p>
<blockquote><pre><code>@XMLElement("Foo") class FiddleStix {
    @XMLAttribute("id") public String identifyingAttribute;
    @XMLElement("Foo") public FiddleStix next;
}</code></pre>
</blockquote>
<p>Now we <i>just</i> need a function to digest our XML string and populate our POJO. To be short and sweet, and not emphasize the XML processing too much, I'm just going to use the typical W3C DOM classes that come with the Java runtime. Easy, short-ish.</p>
<blockquote><pre><code>public static <POJO> POJO turnXMLStringIntoPOJO(final String string, final Class<POJO> type) {
    final POJO pojo = type.newInstance();
    final XMLElement topXmlElement = type.getAnnotation(XMLElement.class);
    final Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder()
            .parse(new ByteArrayInputStream(string.getBytes()));
    if (document.getNodeName().equals(topXmlElement.value())) {
        final NamedNodeMap namedNodeMap = document.getAttributes();
        for (int i = 0; i < namedNodeMap.getLength(); i++) {
            final Node node = namedNodeMap.item(i);
            String name = node.getNodeName();
            final Field[] fields = type.getDeclaredFields();
            for (final Field field : fields) {
                final XMLAttribute xmlAttribute = field.getAnnotation(XMLAttribute.class);
                if (xmlAttribute != null) {
                    if (("".equals(xmlAttribute.value()) &#038;&#038; field.getName().equals(name))
                            || xmlAttribute.value().equals(name)) {
                        field.set(pojo, node.getNodeValue());
                    }
                }
            }
        }
        final NodeList nodeList = document.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            final Node node = nodeList.item(i);
            final String name = node.getNodeName();
            final Field[] fields = type.getDeclaredFields();
            for (final Field field : fields) {
                final XMLElement xmlElement = field.getAnnotation(XMLElement.class);
                if (xmlElement != null) {
                    if (("".equals(xmlElement.value()) &#038;&#038; field.getName().equals(name))
                            || xmlElement.value().equals(name)) {
                        final Object object = field.getType().newInstance();
                        field.set(pojo, object);
                    }
                }
            }
        }
    }

    return pojo;
}</code></pre>
</blockquote>
<p>With a little recursion or other care, this simple method could be used to handle nesting our XML so that Foo could have Foo wtih Foo containing Foo... But for our purposes, this meets our needs. Again, much with the caveats of missing care exchanged for brevity. Notice it's a generic class, giving us flexibility to just send it any old class. With our caveats, it makes assumptions that the class is annotated (or null pointer exceptions will occur). The string is quickly (since it's small) into a DOM tree, and we make two passes through it, once for the attributes and once for the elements. We compare the names of the nodes to the names (value) of our annotations, if they're defined, or to the name of the field, if the value is empty. If a match is found for the annotation, we set the value to whatever the XML contained. If a match is contained for the element, we simply instantiate the right type and add it to our object. We could explore the DOM deeper and set its values, but that's a little larger example.</p>
<p>This class could take all three of our example classes (careful, as two of the classes will conflict) and parse the same XML and get the expected results.</p>
<blockquote><pre><code>String xmlString = "&lt;Foo id=\"alpha\"&gt;&lt;Foo /&gt;&lt;/Foo&gt;";
Foo foo = turnXMLStringIntoPOJO(xmlString, Foo.class);
FiddleStix fiddleStix = turnXMLStringIntoPOJO(xmlString, FiddleStix.class);</code></pre>
</blockquote>
<p>What should result is that our objects would have an id String of "alpha" and their same-type member populated with an empty, but instantiated item. Both classes, from the same XML just because of the annotations. </p>
<p>And that, my friends, is how you use annotations. Well, one way...</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2010/08/06/how-do-annotations-work/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Packaging your Java application for the Mac</title>
		<link>http://www.objectpartners.com/2010/08/03/packaging-your-java-application-for-the-mac/</link>
		<comments>http://www.objectpartners.com/2010/08/03/packaging-your-java-application-for-the-mac/#comments</comments>
		<pubDate>Tue, 03 Aug 2010 13:54:51 +0000</pubDate>
		<dc:creator>jmcclure</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=2196</guid>
		<description><![CDATA[The Mac has some nice tools to turn your jar file into a first class Mac application. This is most useful if the application has a GUI interface; Swing, SWT, etc. There are three parts to this process: 

Package your application as a jar file
Create an icon for your application
Create an application bundle

Some applications referenced [...]]]></description>
			<content:encoded><![CDATA[<p>The Mac has some nice tools to turn your jar file into a first class Mac application. This is most useful if the application has a GUI interface; Swing, SWT, etc. There are three parts to this process: </p>
<ol>
<li>Package your application as a jar file</li>
<li>Create an icon for your application</li>
<li>Create an application bundle</li>
</ol>
<p>Some applications referenced below may not be installed on your Mac by default. If not, you can either install them from your distribution or download them. </p>
<p>I assume you already know how to do step one so we&#8217;ll move on to step two.</p>
<p>Find an icon you like for your application. A little Googling will produce a variety of free icons. The png file format will work for you. Be sure to follow any licensing restrictions that apply to your icon and do the following:</p>
<ol>
<li>Download the png file.</li>
<li>Open the Icon Composer application (its in /Developer/Applications/Utilities).</li>
<li>Drag the png file into the largest box in the icon composer.</li>
<li>From the largest box drag it to the next largest then the next and so on to create various size icons. Be sure to go from larger to smaller for the best results.</li>
<li>Choose File->Save in the Icon Composer and save your new icns file.</li>
</ol>
<p>Finally, build your application bundle:</p>
<ol>
<li>Open the Jar Bundler (its in /Developer/Applications/Utilities).</li>
<li>Select the Classpath and Files tab and add your jar file to the classpath.</li>
<li>Select the Build Information tab.</li>
<li>Click Choose next to the Main Class drop down, select your application&#8217;s jar file again.</li>
<li>Select the entry point for you application from the Main Class drop down.</li>
<li>Select your JVM Version from the drop down</li>
<li>Click Choose Icon and select the icns file you created above.</li>
<li>Click Create Application, enter a name for your bundle, and click Create</li>
</ol>
<p>Now you have an application bundle file you can just drop in your /Applications directory to install.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2010/08/03/packaging-your-java-application-for-the-mac/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
