Welcome to JoshLong.com, home of my personal blog
<< Last | Next >>
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!

November 11, 2011

Trip Roundup for October and November

What a ridiculous blur of insanely fun travel and technology.

I spoke at the MongoDB Chicago conference on the 18th of October on using MongoDB with Spring Data Document on Cloud Foundry. This was a fantastic event and the response seemed enthusiastic about the cloud and, of course, Cloud Foundry. After all, Cloud Foundry was among the first (the first?) major PaaS players to bring MongoDB to market. On a related note, I'm honored to say that I'll be giving the same talk (basically) at Mongo Seattle, on December 1. If you're in Seattle, and want to grab a beer (or coffee!), then ping me on Twitter or on Google+. Naturally, you could always just come to the Mongo Seattle event - $100 for a fully day of talks from experts in the field is amazingly good deal (and, at this point, an ideal holiday gift!).

That was October 18th. I flew home, caught my breath, and then flew back to Chicago for SpringOne2GX, which I blogged about recently. SpringOne2GX was amazing. I ended up doing not only the three talks I blogged about before, but an impromptu joint session with Roy Clarkson on HTML5 mobile application development. The whole conference is something not to be missed. What an absolutely amazing show filled with amazing people.

the venue at Mongo Chicago was called The Library, in a library
The Mongo Chicago venue at "The Library" Adam Fitzgerald kicking off the keynote festivities at SpringOne2GX
The Chicago skyline at night from one of those trips. I love how the clouds hung in the air, making an otherwise mundane photo really beautiful.

I returned home just long enough to get a fresh load of laundry and then set back out to Sofia, Bulgaria, for one of my absolute favorite conferences, Java2Days. The conference, in South East Europe, is at the nexus of Greece, Turkey, Italy, Armenia, etc., so it attracts a lot of people who are really enthusiastic about the conference and the technology.

I met Jean Claude van Damme, and survived!

The conference itself is unrivaled, of course, but the real draw is the chance you have to meet and greet and to take in the culture. Pack your stomach pump, though, the rakia (and the fraternizing, dancing and fun that accompanies it!) tends to sneak up on you! I was at dinner on with the other speakers and with attendees from the show and in walks Jean Claude van Damme who was in town, apparently, shooting the Expendables 2. He sat down, celebrated a bit and was even kind enough to indulge me in a photo, which I proudly post here. Merci, Jean-Claude!

I returned home on the 6th - giving me just enough time to get a small flu and to prepare my decks for Devoxx, which I leave for on the 12th (in 24 hours, or so, basically). If you're in Belgium, this is the event to see! Come see me talk with Chris Richardson on Spring on Cloudfoundry for the university talk (3 hours! We're going to cover NoSQL, AMQP, the <cloud:/> namespace, and much more!) and with Patrick Chanezon for a 1-hour introduction to getting started with Spring on CloudFoundry. Additionally, I'll be participating in the Spring BOF. I've also got a Spring Roo "quickie" talk, and a talk on socializing your Spring applications using Spring Social. Should be utterly exhausting, but I look forward to seeing you all there! We're gonna have a lot of fun.

October 24, 2011

SpringOne2GX 2011

SpringOne2GX 2011 is upon us! I'm in a terminal at San Francisco Airport ("SFO," for those of us in the live-on-plains biz) waiting for my flight to Chicago. This year's going to be ridiculous. Honestly, I can't wait.

I've got three talks - each 1.5 hours! So, eh, if you can't get enough of my ugly mug, then please join me for some of these talks!

One talk is with Roy Clarkson, we're co-presenting on Native Android Development. This talk I look forward to quite a bit - Android's a powerful platform and certainly the most ubiquitious, so learning how to build a better Android application from client to server is very useful! (I can't wait to make it even more ubiquitous when I buy my Galaxy Nexus!).

My second talk is a deep dive at Spring Batch. Sure, anybody can sling together a Spring Batch application, but do you really know what's going on there? Do you know what you could do with Spring Batch? Spring Batch's so amazingly robust and feature rich that a lot of people just plunk down what they need to get their occasional batch processing solution finished, but don't stop to reflect on the power-user features as well as the details. This is a credit to Spring Batch - after all, the 80% case is super simple. But, you can take it and further, and this talk should be a great start for the curious. Additionally, because I'll be diving deep into some basic concepts, this talk will also be a good introduction to Spring Batch for the uninitiated.

My last talk is that's a bit more medium-to-advanced level. In this talk, I'll introduce some of the Spring framework's various SPIs. Spring's a very simple technology and it features a rich component model and framework libraries that you can pull down and use, a la carte. However, a lot of Spring's power is in the stuff right below the surface - the extension points. Come learn about some of my favorite extension points in this talk. Remember, these extension points are the same ones that we leverage in building other Spring frameworks like Spring Integration, Spring Batch, etc., so this isn't just idle speculation! The most demanding user of the Spring framework is often the engineer trying to build a sister project!

October 10, 2011

Great Content to get Started with Neo4J and Spring Data Graph

I recently had somebody ask me what the best content for getting started with Neo4J is. Naturally, my answer was to grab Spring Data Graph and don't look back. But that's not entirely fair. Admittedly, you might be better served by simply learning Neo4J and then layering in the Spring Data support to reduce a lot of the tedium. So, without further ado, here's a list of great content that I put together for people who are looking to learn Neo4j and Spring Data Graph (which works with Neo4j.).

October 1, 2011

Python? Good. Python on CloudFoundry? Better.

I love the characterization of Python in this post from InfoQ:

"For Adam, Python fostered the development of modern web frameworks, with Zope and Plone. These frameworks introduced concepts like separation of business and display logic via view templating, ORMs for database interaction, and test-driven development were built into Zope 5 years before Rails was born. The main reason why they have not been successful in the market is their complexity and a steep learning curve while being way ahead of their time. Eventually, and despite the initial lack of involvement of the Python community, Django emerged as a strong competitor to rails. .."

That basically says it all: Zope (and Plone) was an integrated, productive framework/application server before EJB 1.0x and it already had ORM, a proper MVC web framework, etc. It was no wonder that EJB and J2EE left a lot of us who had Python backgrounds a little... underwhelmed. I love the point surrounding the "noise" of the community: Python's everywhere - it's a "sleeper" success and yet most people would still not describe it as either legacy or hipster. I remember learning Python in the late 90's and it had already seen adoption by companies that were doing amazing things. That's actually what struck me so much about Python: people who could use any language and technology they wanted, as long as they got results, chose Python. Among the companies that "chose" Python instead of C++ or PHP or even Java (at that point) were unambitious, fly-by-night organizations like Google, NASA, ILM, and many, many more. That spoke volumes more than all the noise Node's generated. (As an aside, if you want to actually build software and take advantage of Node's promise with a language and platform you trust, may I recommend Node.X?)

Python offers a wealth of options for developers. My first Python use cases - even at Python 1.5 a decade ago - were all about exploiting Python's "batteries included" mantra to build distributed applications on grids. Oh, and text processing. Honestly, Python does a remarkable job at text processing. I don't miss Perl, at all!).

I note that if you want a seriously good Python cloud-story, check out ActiveState's (you know, ActiveState, the maker of leading IDEs and integrated language bundles/SDKs for Python, Perl, Tcl, etc., for at least the last decade?) Stackato, which is based on CloudFoundry, the open-source PaaS, is awesome. As much as I love the MicroCloud Foundry VM instance, the truth is that the ActiveState guys beat us (I work for SpringSource, a division of VMware) to the punch: they had a VMWare image running their port of the CloudFoundry cloud before VMware! Awesome ;-)

<< Last | Next >>