Welcome to JoshLong.com, home of my personal blog
<< Last | Next >>
March 8, 2012

A Walking Tour of Spring 3.1

I put together a quick walking tour of Spring 3.1. The code is available on my GitHub account. It runs on a Servlet 3 container, and demonstrates how to build a completely XML free (no persistence.xml, no web.xml, no orm.xml, etc.) application that uses Hibernate 4, Spring 3.1, and Spring MVC 3.1. It shows how to build everything from a transactional service to a RESTful endpoint.

February 21, 2012

My trip to JFokus, Vaadin Dev Day, and Spring I/O with my Dad



Top: @sergialmar, me, and @neodevelop.
Bottom two: beautiful Photos of Madrid!


All three photos: una manifestación!
This was my first time in Madrid, Spain, for the Spring IO conference. I enjoyed the people, the culture (y las bebidas!) and more. I brought my dad with me on this trip, since he's never been abroad, and I wanted him to see Europe with me. We had talked about this when I went to JavaZone, last year, and I described to him that there were fjords and plenty of beautiful wildlife and vast expanses of nature's beauty. That trip, for reasons not that relevant here, never panned out for us (although I quite enjoyed it!). JavaZone came and went, but he was still interested in Scandinavia and experiencing that type of culture. When this trip (first to Stockholm, Sweden, for JFokus, and then to Madrid, Spain, for Spring I/O) materialized, dad jumped at the chance. I bought his tickets (a late birthday gift - we share the same birthday!) and I asked him to secure a passport, which he did.

He was most looking forward to visiting Stockholm. Stockholm is every bit as lovely as he imagined it would be, having seen The Girl with the Dragon Tatoo.

But, dad fell ill - something he ate didn't agree with him (probably the airline food!) - and he was trapped in the hotel for a few days, and very weak. This made moving around a bit more problematic than it should have been as we made the subsequent trip to Madrid, Spain. One thing we did learn: getting sick in a hotel room's a good idea, especially in Stockholm. The staff at the hotel we stayed at - the lovely Radisson Blu Waterfront in Stockholm, right next to the JFokus venue - treated him exceptionally. It seemed as though the staff was almost rooting for him to recover! Somebody even checked in on him for me, while I was tending to my obligations as a speaker at the conference! Talk about great service.

During all of this, I took a quick jaunt (a train, then a flight, then a cab) from Stockholm, Sweden to Helsinki, Finland's port, where I jumped on a cruise headed back to Stockholm! This cruise, in particular was the vessel on which the Vaadin Dev Days took place. It was an amazing, enthusiastic group of programmers, and you couldn't ask for a more interesting venue. I enjoyed everything, and particularly, I enjoyed giving a talk against the background sound of ice breaking as the ship plowed onward, through the frozen waters. Adding that to the list of things that I can't beleive I got to do...

We finally made it to Madrid. By that point dad was on the mend, and the temperature in Madrid was more favorable to people of, em, superior years. It was a lot warmer than in Stockholm. Madrid seems like it was realized from a story book illustration: nice people, great food and - most manifestly for an American like my dear dad, never before abroad in his 75+ years of life - full of beautiful architecture! Madrid ended up being his favorite city.

It didn't hurt that the conference coincided with carnivale, which was being celebrated in some form or another in many different Catholic countries world-wide. The streets were abuzz with music, debauchery and crowds of people. Dad and I went outside, took in some of the scenery and had to find a place to sit when one of the Manifestacións plowed through the center where we were! What an incredible thing to behold! We missed the memo, evidently, where it was announced that the entire walking population of Madrid would go on a walkabout!

I really enjoyed JFokus, the Vaadin Dev Days, and finally Spring IO both because they were great events with enthusiastic developers, but also because I got to go with my dad, who got to experience Europe for the first time with me. We learned a lot. I'll be back in Europe next month for 33rd Degree, and I'll be in Sweden, again (!), and in numerous other countries in April for ScanDevConf and the Cloud Foundry Open Tour (which we'll talk about a bit later), respectively, and I'll be sure to approach those trips in the same way as my dad did: full of a (renewed) curiousity.

February 17, 2012

JFokus and Vaadin 2012

Hey guys, are you going to be at JFokus' University day tomorrow? Come see Chris Richardson and I talk about building better Spring applications on Cloud Foundry at 9AM tomorrow morning. If you're in Helsinki, might I recommend the JFokus with Vaadin cruise which leaves from Helsinki aboard the MS Silja Symphony at 17:00 EET, and then works it way to Stockholm, where of course you're then free to attend JFokus. I'll be there, giving a talk on getting to production quicker with technologies like Cloud Foundry, Spring and Vaadin. The deck from the talk from the Vaadin dev meetup on Spring, Roo and Vaadin is available, and so is the deck from the JFokus Cloud Foundry quickie is available here.

Spring IO 2012

Looking forward to presenting my talk on Integration and Batch Processing with Cloud Foundry tomorrow at Spring IO 2012. RabbitMQ, Spring Integration and Cloud Foundry are Natural Vehicles for applications that handle large workloads and scale well. In this talk, I'll introduce common architectural patterns to better scale, using Spring Integration and Spring Batch, using RabbitMQ as the communication fabric. For those of you who want the deck, it's available here.

January 26, 2012

A Google Music API, Please?

You know what I want? A Google Music API. I feel like Google Music's still the leader. Apple's iCloud just kind of leaves me cold. It not only stinks of lock -in, but it's not even particularly flexible. Where's my .ogg support?

The things I would do...

The Google Music App doesn't do the right thing a lot. I plug it into the car and hit play, thinking it'll either playing all songs after it, or the whole album, and often it just plays one song. Even worse, the shuffle function's odd. Google Music has weird behavior when you run the Navigation app and have to share the audio with other apps. Sometimes when Google Music gets the control back, it doesn't pick up and go, again.

Finally, I want Google Music on Roku, and on other devices. Otherwise, I still don't feel like I could just throw away my CDs, yet. And, while I appreciate that there's a "offline" mode for Google Music, I still don't see a way for me to get my original music back. Where's my liberated data section for my music?

January 1, 2012

Supporting Your Own Field or Method Injection Annotation Processors in Spring

So, I had a use case the other day - I wanted to support a custom annotation for denoting injection at the class level. Spring users will know that Spring already supports Spring's native @Autowired, JSR 330's @javax.inject.Inject, and JSR 250's '@javax.resource.Resource. These annotations, when placed on a setter, or a field, signal to Spring that a value should be injected at the site of the annotation. These annotations are synonyms for the same thing. Spring also supports other annotations - like the JPA 1.0 @javax.persistence.PersistenceContext annotation. The annotation is used in a special circumstance, when you want Spring to inject an EntityManager or an EntityManagerFactory. Here are some examples.

	@javax.inject.Inject 
	private DataSource dataSource ;
	
	@Autowired  
	public void setDataSource (DataSource ds){
	  this.datSource = ds ;
	}
	
	@PersistenceContext 
	private EntityManager entityManager; 	

To "teach" Spring what to do with a custom annotation like @PersistenceContext is fairly easy once you know the actors involved. The work is typically done inside of a special BeanPostProcessor. What we want is a framework hook to inspect the beans after the bean's have been created, but before they've been populated with properties. The BeanPostProcessor interface is powerful, but not quite what we need. What we actually need is a combination of the the more specialized InstantiationAwareBeanPostProcessor and MergedBeanDefinitionPostProcessor. InstantiationAwareBeanPostProcessor provides the following callback method:

PropertyValues postProcessPropertyValues ( PropertyValues pvs, PropertyDescriptor[] pds, 
		                       Object bean, String beanName) throws BeansException;
The callback hook lets you stipulate a value for a properties on the bean. We can use that to inject custom values. It turns out that Spring already provides a convenient framework object that you can use to handle the duty of injection called InjectionMetadata. The metadata represents information about the injection sites. You can extend this class and provide specific metadata about the call site - perhaps by caching the contents of the annotation that you're dealing with - and then use that to actually perform the injection. It is up to you to crawl the beans - including the super classes and so on - to gather the fields and property setters and then provide the relevant InjectionMetadata. There's a lot of expectations here, but it's pretty simple to implement. I have provided a reusable base class (below) that generalizes all but the specific concerns. This code is written in Scala, but it can be reused from Java, once compiled. Alternatively, it wouldn't be hard to translate to Java. The only thing that wouldn't map nicely into Java are the uses of callback methods, which can be expressed nicely in Scala, but would require an object with a callback method. (I probably should re-write it in Java and provide callback interfaces in lieu of the various callback methods or provide an abstract base class with well known, abstract callback methods) Anyway, you can basically ignore the implementation - it's presented so you can include it in your project (under the Apache 2 license, of course). See you after the example to see how to implement it.

	package com.joshlong.spring.util 
	import org.springframework.beans.factory.support.{RootBeanDefinition, MergedBeanDefinitionPostProcessor}
	import org.springframework.beans.factory.annotation.InjectionMetadata
	import org.springframework.beans.factory.BeanCreationException
	import java.beans.PropertyDescriptor
	import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
	import org.springframework.beans.PropertyValues
	import java.util.LinkedList
	import java.lang.{String, Class}
	import java.lang.reflect.{Method, Field, Member, Modifier}
	import org.apache.commons.logging.LogFactory
	class AnnotatedSiteInjectionPostProcessor [T <: AnyRef, X <: java.lang.annotation.Annotation]
	   (annotation: Class[X], fieldMetadataCallback:  (X, Field) => InjectionMetadata.InjectedElement, methodMetadataCallback:  (X, Method) => InjectionMetadata.InjectedElement)
	  extends InstantiationAwareBeanPostProcessor with MergedBeanDefinitionPostProcessor {
	  val logger = LogFactory.getLog (getClass)
	  def postProcessBeforeInstantiation (beanClass: Class[_], beanName: String) = null
	  def postProcessBeforeInitialization (bean: AnyRef, beanName: String) = bean
	  def postProcessAfterInstantiation (bean: AnyRef, beanName: String) = true
	  def postProcessAfterInitialization (bean: AnyRef, beanName: String) = bean
	  def postProcessMergedBeanDefinition (beanDefinition: RootBeanDefinition, beanType: Class[_], beanName: String) {
	    if  (beanType != null) {
	      var metadata: InjectionMetadata = findInjectionSiteMetadata (beanType)
	      metadata.checkConfigMembers (beanDefinition)
	    }
	  }
	  def postProcessPropertyValues (pvs: PropertyValues, pds: Array[PropertyDescriptor], bean: AnyRef, beanName: String): PropertyValues = {
	    try {
	      logger.debug ("about to attempt injection for class "+ bean.getClass )
	      val metadata = findInjectionSiteMetadata (bean.getClass)
	      metadata.inject (bean, beanName, pvs)
	    } catch {
	      case ex: Throwable =>
	        throw new BeanCreationException (beanName, "Injection of persistence dependencies failed", ex)
	    }
	    pvs
	  }
	  private def doWithMembers[T <: Member] (clazz: Class[_], filter: T => Boolean, fieldsFactory:  (Class[_]) => Array[T], doWith: T => Unit) = {
	    var targetClass: Class[_] = clazz
	    do {
	      fieldsFactory (targetClass).filter (filter).foreach (doWith)
	      targetClass = targetClass.getSuperclass
	    } while  (targetClass != null && !targetClass.equals (classOf[AnyRef]))
	  }
	  private def findInjectionSiteMetadata (clazz: Class[_]): InjectionMetadata = {
	    val currElements = new LinkedList[InjectionMetadata.InjectedElement]
	    doWithMembers[Field] (clazz, f => !Modifier.isStatic (f.getModifiers) && f.getAnnotation (annotation) != null, c => c.getDeclaredFields, f => {
	      val fieldAnnotation = f.getAnnotation (annotation)
	      val injectedElement = fieldMetadataCallback (fieldAnnotation, f)
	      currElements.add (injectedElement)
	    })
	    doWithMembers[Method] (clazz, f => !Modifier.isStatic (f.getModifiers) && f.getAnnotation (annotation) != null, c => c.getDeclaredMethods, m => {
	      val methodAnnotation = m.getAnnotation (annotation)
	      val injectedElement = methodMetadataCallback (methodAnnotation, m)
	      currElements.add (injectedElement)
	    })
	    new InjectionMetadata (clazz, currElements)
	  }
	}
	

This class takes care of crawling the beans and performing the injection for you. All it needs from you is a subclass of InjectionMetadata.InjectedElement, which you provide. That object in turn is responsible for ultimately providing the reference to the object that you want to be injected based on the metadata available. To make this easy, this particular responsibility is factored out as callback functions which you provide in your concrete implementation. To do its work, you need to tell this class which annotation to match, and the type of object you'd like to inject (you could stipulate just a regular java.lang.Object, or, in Scala terms, an AnyRef.).

In this particular example, I want an annotation that can be used to lookup, and inject, a reference to an Akka actor, called a ActorRef in Akka parlance. Akka actors can live locally, or remotely, and when injected you can lookup an Actor by a logical name or by a path, which itself can be absolute, or relative, as Akka actors form supervisory hierarchies which map very much like a file system. For more information on the supported addressing scheme, check out ths document from the Akka documentation.

So, the example (in Java) might look like this:

@ActorReference ("akka://my-system@serv.example.com:5678/app/service-b") private ActorRef actorRef ; 
or (in Scala)
@ActorReference ("akka://my-system@serv.example.com:5678/app/service-b") private var actorRef: ActorRef = _  
Let's see how to implement this using the base class described above.

First, we need to extend the base class, and provide the callback hooks that tell the base class what to do with a field or property (a setter method). In our case, this is pretty simple, and straight forward:

class ActorReferenceAnnotatedSiteInjectPostProcessor (actorSystem: ActorSystem)
  extends AnnotatedSiteInjectionPostProcessor[ActorRef, ActorReference]
    classOf[akka.spring.ActorReference],
     (ar: ActorReference, f: Field) => new ActorReferenceInjectedElement (actorSystem, ar, f, null),
     (ar: ActorReference, m: Method) => new ActorReferenceInjectedElement (actorSystem, ar, m, BeanUtils.findPropertyForMethod (m)))

In this class, we extend the base class and call the constructor, passing in the class of the annotation to detect, a callback method which accepts an instance of the annotation and a particular instance of a field, and another callback method and a particular instance of a method. The contract is that, given the instance of the annotation and matching field or method, you will return an instance (or sublcass of) the InjectionMetadata.InjectedElement class. So, that's what we do, constructing an instance of ActorReferenceInjectedElement with the ActorSystem reference given in this subclass' constructor and the detected ActorReference annotation, and the detected class member to which the annotation was attached, a java.lang.reflect.Field or java.lang.reflect.Method as well as the annotation itself.

The ActorReferenceInjectedElement is where the important work happens. Let's take a look at that class.

class ActorReferenceInjectedElement
  actorSystem: ActorSystem, 
  annotation:ActorReference, 
  member: Member, 
  propertyDescriptor: PropertyDescriptor) 
extends InjectionMetadata.InjectedElement (member, pd) {
			
  override def getResourceToInject (target: AnyRef, requestingBeanName: String) = actorSystem.actorFor (annotation.value () )
}
	

If you read Scala, then this is a pretty simple class. The constructor (the prototype of which is included inline in the class declaration, at the top) expects an ActorSystem, a reference to the ActorReference annotation, a java.lang.reflect.Member (the common base class of both Field and Method), and a PropertyDescriptor. We don't use the PropertyDescriptor in this code (except to invoke the super constructor), but it's nice to know that we have it available. It might be null, however, if we're looking at a java.lang.reflect.Field. The unspoken bit is that the constructor arguments implicitly become class variables, and so are reference-able from other methods.

In the class, we override the getResourceToInject method, providing the object to be injected. We simply need a reference to the actor, so call actorSystem.actorFor with the String that was provided as part of the annotation (the value () field). We could, for example, provide a wrapper object instead of the reference itself. This is what happens when you use the @PersistenceContext annotation. It injects an EntityManager proxy that in turn manages thread-local EntityManagers so that no matter which thread you call a method on, if it accesses the class EntityManager, it's guaranteed to be thread-safe. We don't do anything fancy like that in this case, but it's easy to see the potential there.

Now, all that's left to do is register the ActorReferenceAnnotatedSiteInjectPostProcessor in your Spring configuration. It's just a regular bean with constructor arguments. Spring detects the interfaces and calls the appropriate methods. Here's a code configuration based example (written in Scala):

@Configuration 
class MyAkkaConfiguration  {
  @Bean def actorSystem = ... // provide your own reference 
	
  @Bean def actorReferenceAnnotatedSiteInjectPostProcessor = 
    new ActorReferenceAnnotatedSiteInjectPostProcessor ( this.actorSystem ())	
	
  @Bean ("sample") def someBeanThatDependsOnActors =
    new Object {  // anonymous inline object just to show you what a usage might look like 
      @ActorReference ("myActor") 
      var someActor:ActorRef = _ 	
    }
} 					
object Main {
  val ac = new AnnotationConfigApplicationContext (classOf[MyAkkaConfiguration])
  val sample  = ac.getBean ("sample")
  Assert.notNull ( sample.actorSystem )	
}
		
    
December 17, 2011

The Week Spring 3.1 Went GA, or, The Holidays Begin Now!

This week has been nothing short of a rollercoaster! The week started with Spring 3.1 debuting, chock full of new features. From the release announcement,

  1. The environment abstraction and the associated bean definition profiles, along with centrally configurable property sources for placeholder resolution.
  2. Java-based application configuration based on @Enable* annotations on configuration classes, allowing for convenient container configuration: e.g. using @EnableTransactionManagement to activate declarative transaction processing.
  3. The cache abstraction with our declarative caching solution (@Cacheable etc) on top, focusing on convenient interaction between application code and cache providers.
  4. The Servlet 3.0 based WebApplicationInitializer mechanism for bootstrapping a Spring web application without web.xml! This is a key piece in Spring's web configuration story, providing a rich alternative to XML-based bootstrapping.
  5. Revised MVC processing with flash attribute support, a new @RequestPart annotation, and further REST support refinements. This new HandlerMapping/HandlerAdapter variant is also highly extensible for custom MVC needs. Beyond the above major themes, we invested into our O/R Mapping support, allowing for JPA package scanning without persistence.xml, and supporting Hibernate 4.0 (CR7 at this time - we will fully support Hibernate 4.0 GA once released).
  6. Last but not least, this is the first Spring release with first-class Java 7 support. While older Spring versions run perfectly fine on Java 7, Spring 3.1 goes the extra mile and fully supports JDBC 4.1 as well as convenient ForkJoinPool setup and injection.
  7. As usual, this release also includes many recent bug fixes. Spring 3.1 is fully compatible with Spring 3.0 and continues to have Java 5+ and Servlet 2.4+ as minimum system requirements. We recommend a Spring 3.1 upgrade to all Spring 3.0.x users.

That was Tuesday. The web reacted as expected, with news announcements aplenty, on TheServerSide, on InfoQ, and on Dzone, and on a zillion other sites, too.

Then, Costin Leau, who I'm pretty sure never sleeps, shipped Spring Data Gemfire 1.1.0, and Spring Data Redis 1.0.0, both of which have many new features and are compatible with Spring 3.1.

Then, Grails 2.0 was released, also compatible with Spring 3.1.

Then, vFabric SQLFire 1.0 was Released! SQLFire, for those of you who haven't heard about it before, is an SQL92 compliant database that runs on top of GemFire, the distributed data grid product from VMware. It can be used to run, unchanged, a good many existing RDBMS applications and acheive drastic improvements in speed immediately. This has little to do with Spring 3.1, but is instead a release of its own import, also released in the last week.

Then, Spring Social 1.0.1 was released, also compatible with Spring 3.1! Spring Social's release is important too because other projects depend on it. So, we can expect to see the floodgates open even more soon with more releases, all because Spring 3.1 was released.

To top things off, Oleg Zhurakousky's interview at JavaOne with InfoQ on messaging, Spring, and the cloud is now available, and so is Roy Clarkson and Keith Donald's SpringOne2GX talk on Making the Mobile Web Native with PhoneGap.

Awesome.

I for one, need a breather. Can't wait until this weekend.

Next week's going to be crazy, as well. I'll be at the San Diego JUG on December 20th, talking about all things Spring and Cloud Foundry. There are actually two talks, one on Spring and Cloud Foundry, and another still on Tailoring Spring for Custom Usage. Hope to see you there!

December 10, 2011

Mamacita...

Yeah, so this is stuck in my head. Sigh. It's really catchy... the first twenty or thirty times.

December 3, 2011

Simple things I do to OS X itself whenever I set it up

I do a few things to every OS X installation to make them more useful. Most of the things I mention below are things you can do to OS X itself, some are third party applications that are generally useful. I hope they help you, but really I'm listing them here so I don't have to rediscover this stuff again next time I'm doing a fresh OS X installation. ;-) My hope is that these are general, generic and useful enough to be applicable for everybody, not just software developers with a penchant for photography like myself. I've put all the things I could remember here, but I'm sure I've probably forgotten a few, too. I'l follow up if I think of anything.

  1. Enable Remote Login Go to System Preferences > Sharing > and then enable Remote Login. This will give you SSH access to your machine, which of course should need no justification.
  2. Add a Login menu to the Finder Go to System Preferences > Users & Groups > and select the Login Options item on the left, with the picture of the house next to it. Then, choose Show Input menu in Login Window and select Show fast User Switching Menu as [Full Name]. This is useful as a quick way to lock the screen, as well as change accounts. You can, of course, use Hot Corners to trigger the login screen, but I found I kept accidentally triggering them.
  3. Show a Full Date Go to System Preferences > Date & Time > and then choose Show the day of the week, Show date, Use a 24-hour clock, and Display the time with seconds. I also uncheck Flash the time separators.
  4. Make the Dock Less Obtrusive Go to System Preferences > Date & Time > and select Minimize windows into application icon, Automatically hide and show the Dock, and Show indicator lights for open applications. Finally, drag the divider - it looks like a broken, vertical line that narrows towards the top - between the dock and the rest of the icons and make the dock as small as you're comfortable seeing with and could still reach with some accuracy with a flick of the mouse.
  5. Know Your Shortcuts While OS X's Finder is pretty shortcut-phobic, it does have some pretty useful ones.
    Home Directory   COMMAND + SHIFT + H
    Applications Directory   COMMAND + SHIFT + A
    Utilities Directory   COMMAND + SHIFT + U
    Desktop Directory   COMMAND + SHIFT + D
    Computer window   COMMAND + SHIFT + C
    For more, consult this useful Apple support doc.
  6. Clean the DockRot Drag Everything on the dock away that you're not absolutely sure you're going to need. I try to keep mine as an indicator of the applications that are open, so I remove about everything except the Trash, Launchpad, and Mission Control. There are lots of ways to still get to your often used applications. You can of course use something like Spotlight, but there are even better (albeit third party) tools like QuickSilver and Alfred that can make all applications trivial to access. I know I implied I wasn't going to mention third party applications, so let me also remind you that you can get at your applications very quickly by using Spotlight or the two commands mentioned above - COMMND + SHIFT + U (for the Utilities folder) and COMMAND + SHIFT + A (for the Applications folder).
  7. Disable Spotlight Since I don't ask much of the Dock, and since I use things like Alfred or Quick Silver, it's useful to reuse Spotlight's keyboard shortcut for those alternative application switchers. While there are a lot of ways to disable Spotlight more effectively, for my purposes it is enough to simply disable the key command and render Spotlight partially inert. Go to System Preferences > Spotlight, and uncheck every checkbox there under the Search Results list. Uncheck the two options below, Spotlight menu keyboard shortcut and Spotlight window keyboard shortcut.
  8. Speak Truth (About) Power You can view detailed information about your Mac's power consumption (if you're on a laptop variety) by going to System Preferences > Energy Saver and then selecting Show battery status in menu bar. In the menu bar, right click on the power icon, and choose Show > Time (to see how much time you've got left before the charge runs out) or Show > Percentage to see how much battery power you've got left.
  9. Switch Resolutions on the Fly I end up plugging into projectors and into various monitors a lot in my work, so keep in mind this might be more valuable to me than it is to you. Go to System Preferences > then select Show displays in menu bar. This will install a menu in the menu bar that you can use to quickly switch resolutions and access monitor settings.
  10. Install a better browser I've always installed as many browsers as possible. It used to be because I wanted to have a better developer-friendly tool to develop web applications with, or because I wanted to have a browsers to test the rendering of my web applications, but these days I'd recommend anybody do it because the default browsers in all operating systems usually leave something to be desired. OS X and Safari, in my humblest of opinions, is no different. I'm using Chrome pretty happily these days, but that's not to say you need to. Next week Firefox might be back on top again! Who knows. Either way, get yourself a better browser.
  11. SWitch it up Switching between applications with the COMMAND + TAB shortcut in OS X is tedious. If you are using an application like Chrome which can have multiple document windows, then you will simply be returned to the application itself, not any specific document in that application. Similarly, if you have minimized a window, COMMAND + TAB'ing to that window will not "activate" and focus on it. So, I sought another option and the intertubes pointed me to Witch. It fixes all of these problems, and more, although be warned it costs (USD $14, as of this writing).
November 30, 2011

Devoxx 2011 Report and Seattle Mongo 2011

Devoxx is a huge conference that redefines "community." I like the conference - a true paradise - it has a lot more soul than JavaOne and represents a really nice sampling of what's what out there, not just what Oracle's working on. So, it was with great pleasure that I went, despite being pretty sick. I stopped by the doctor's on my way out of town and loaded up in antibiotics then began the 20-hour door-to-door journey from Los Angeles, United States to Antwerp, Belgium.

I gave a 15 minute quickie on Spring Roo, a 3-hour university talk on Spring on Cloud Foundry (with Chris Richardson), a regular talk on Spring on Cloud Foundry (with Patrick Chanezon), another regular talk on social Spring applications using Spring Social and Spring Integration, and I helped lead the Spring BOF. Basically, I had more fun than anybody should be allowed. I may have looked (and felt) like death warmed over, but I had a wonderful time. All the talks were well attended, and I loved the feedback! Keep it coming, guys.

That said, I'm now on a flight heading to Seattle, Washington, where I'll present on Cloud Foundry and Mongo DB at the Mongo Seattle event. If you're in town, come see me! We can talk Spring, big data, cloud and anything else you'd like. Also, if you know the area, I'd love to know which coffee shops will help me to best endure the inclement weather. Ping me on Twitter or on Google+. See you there!

<< Last | Next >>