Showing posts with label spring. Show all posts
Showing posts with label spring. Show all posts

Thursday, February 11, 2010

Step 4 – Spring Dynamic Modules

Our previous installment finally began to show the benefits of OSGi. Service production, consumption and registry were all accomplished programmatically with the APIs of the OSGi specification. While this does provide the benefit of reduced coupling and improved cohesion in an enterprise application, the end result was an invasive and difficult to test implementation. Surely there has to be a better way?

The good people at SpringSource asked the same question and they came up with a solution that feels very natural to Spring developers: Spring Dynamic Modules. Spring DM provides OSGi developers with a declarative means of wiring bundles together in much the same manner that the Spring framework allows developers to wire together Java classes. Getting up and running requires a couple of new repositories and an import from the root project level.

Up until now we’ve been able to download the few OSGi bundles that we’ve needed from the typical maven repositories. When we begin to use the Spring extender for OSGi, a number of other bundles will come into the picture. Downloading these bundles from the maven repositories can be hit or miss, so instead let’s use the SpringSource Enterprise Bundle Repository as our main repository for OSGi bundles. EBR is basically a collection of commonly used libraries for Java in valid OSGi bundle form.  Add the two repository locations with pax construct using the following commands from the root directory:

pax-add-repository \
-i com.springsource.repository.bundles.release \
-u http://repository.springsource.com/maven/bundles/release
pax-add-repository \
-i com.springsource.repository.bundles.external \
-u http://repository.springsource.com/maven/bundles/external


Then we can slightly adjust the pax import command to pull in the Spring DM extender and all of it’s dependencies in one fell swoop.



Screen shot 2010-02-11 at 7.34.37 AM



This command is a little different from prior imports in that we have added a couple of properties to the maven command. The importTransitive property instructs pax-construct to not only pull in the spring-osgi-extender, but also all of the other bundles that it depends on. The widenScope property instructs it to import not only those compile time bundles, but also the runtime dependencies as well. This should result in a slew of downloads occurring in your main project directory.



Using Spring DM extender will remove the OSGi programmatic approach to wiring and activating bundles, in favor of autowiring bundles together in a Spring context. By default the extender will look in META-INF/spring for any .xml files that it can sink it’s teeth into. I follow the pattern of using an OSGi specific context and an other file for all the rest. Change to the directory of the service bundle and from there create a src/main/resources/META-INF/spring directory. Within that directory, we’ll create two application context files. The first, service-context.xml will just declare the service implementation as a bean:



<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  
  <bean id="raffleService"
    class="com.pillartech.raffle.service.internal.RaffleServiceImpl" />
</beans>


The osgi-context.xml is fairly straightforward as well:



<beans:beans xmlns="http://www.springframework.org/schema/osgi"
  xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/osgi
  http://www.springframework.org/schema/osgi/spring-osgi.xsd
  http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  <service ref="raffleService" 
    interface="com.pillartech.raffle.service.RaffleService" />
</beans:beans>


This context decalres the osgi namespace as the default and can then simply publish the service to OSGi via the <service> tag. You’ll note it uses a reference to the raffleService bean in the other context, make sure these match. With these two files in place the activator for this bundle is no longer necessary. Remove that entire file and you should be able to compile and deploy.



OSGi also provides a means for consuming services. Let’s change the Rigged bundle to make use of it. Start by creating the same src/main/resources/META-INF/spring structure so that the dm extender will find all of the contexts. The OSGi context for a consumer is very similar to the producer:



<beans:beans xmlns="http://www.springframework.org/schema/osgi"
  xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/osgi
  http://www.springframework.org/schema/osgi/spring-osgi.xsd
  http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  <reference id="raffleService" 
    interface="com.pillartech.raffle.service.RaffleService" />
  
</beans:beans>


The major change is that instead of using a service tag to produce a service, we use a reference tag to consume one. The rigged activator class will need changed to consume this service via dependency injection. Let’s tweak that class so that all OSGi based lookups are removed and replace it with a simple setter. While we’re in here, let’s also remove the APIs for bundle activation as well. The end result is a ServiceBasedRiggedRaffleActivator that looks like this



package com.pillartech.raffle.rigged.internal;
import java.util.Set;
import com.pillartech.raffle.service.RaffleService;
public final class ServiceBasedRiggedRaffleActivator {
  private RaffleService service;
  
  public RaffleService getRaffleService() {
    return service;
  }
  
  public void setRaffleService(RaffleService svc) {
    service = svc;
  }
  
  public void start() throws Exception {
    if (service != null) {
      addEntrants();
    }
    else {
      System.out.println("Unable to rig the raffle, cannot get a handle on the service");
    }
  }
  private void addEntrants() {
    System.out.println("Adding entrants");
    final int COUNT = 10;
    for (int i = 0; i < COUNT; i++) {
      service.addEntry("Todd("+i+")", "toddkaufman@gmail.com");
    }
    System.out.println(COUNT + " entries added to the raffle.");
  }
  public void stop() throws Exception {
    System.out.println("And the winner of the raffle is ...");
    Set<String> winners = service.pickWinners(1);
    for (String winner : winners) {
      System.out.println(winner + " won!");
    }
  }
}


You can tell by the imports that this code now has zero reliance on OSGi APIs so it is easier to understand and maintain, with the benefit of also being able to be tested in isolation. The final step in getting this to work is to create a context file that wires up the rigged class with it’s dependency on the external service bundle. The rigged-context.xml is



<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  
  <bean id="riggedActivator"
    class="com.pillartech.raffle.rigged.internal.ServiceBasedRiggedRaffleActivator"
    init-method="start" destroy-method="stop">
    <property name="raffleService" ref="raffleService" />
  </bean>
</beans>


Here we make use of the init-method and destroy-method properties of a spring bean to automatically kick off the raffle and shut it down, just as we did with the bundle’s OSGi start/stop lifecycles. One last item of cleanup is to tweak the BND files for both bundles to reflect the removal of a BundleActivator. While we’re in there I would add the following line so that Spring does not expose the bundle’s context to other services:



Spring-Context: META-INF/spring/*.xml;publish-context:=false


Executing a mvn clean install and pax-provision command should provide you with a more verbose lifecycle to these bundles, but the main functionality remains the same. Starting and stopping the rigged service will create a raffle and pick a winner as you would hope.  We’ve deleted a slew of code and added just a handful of configuration to the application to get a simpler and easier to test set of bundles. In the next installment we’ll build upon the use of Spring DM from this point on by adding some database interaction as 90% of the apps we write would.



Source is available as always on githhub.

Tuesday, December 9, 2008

Howdy Parnter!

I'm pleased to announce that Quick Solutions, Inc. is now a certified Systems Integration Partner with SpringSource.

The Spring framework is the standard for Java development. SpringSource has built upon that momentum with a keen vision in developing products and services that benefit enterprise customers using Spring. Whether it is the OSGi enabled dm Server, an instrumented version of the Spring offering with a common monitoring application, or a support model that bests Oracle, IBM, or JBoss, the future of Java development is a very clearly dominated by Spring and SpringSource.

Quick Solutions is driven by providing software based solutions to our customer's problems. We strive to do this in a manner that passes the most value on to our clients. Partnering with SpringSource will allow us to clearly articulate and demonstrate the value that their products generate within Enterprise Java development. We look forward to working closely with Rod and the gang in 2009 and beyond.

Stay tuned for some more information on making best use of the products in the SpringSource umbrella.

Friday, September 19, 2008

Clustered Scheduling with Spring and Quartz

I initially cut my teeth as a Java programmer writing some batch JDBC programs to update various sets of data. We were deployed in a Unix environment so we traditionally wrapped all of the JDBC programs in a bash shell script and kicked that thing off via a Cron entry. This environment was successful for the most part but there were issues. If our batch machine was taken offline due to upgrades, failed disk, or coffee spill then our batch process just did not run. If we wanted it to run after the fact we had to create another 1 time cron entry to kick the thing off. This typically took about 2 hours because the first hour and a half was spent with me trying to decrypt the cron syntax (minutes first or seconds? need a question mark here but star there? comma or dash between my minutes?).

Fast forward to 2008 and I have just completed a week long adventure with a coworker finally getting Spring and Quartz up and running to kick off some batch programs in a clustered environment. Failover is automatic, ad hoc runs are possible, and I still wind up spending an hour and a half each time I have to add a cron entry. I thought I would post some code snippets with explanation so that you kind reader, could maybe trim this process down to about a day.

1.) Download Spring 2.5.5 and only use the Quartz 1.6.1 RC1 jar that is bundled within the lib directory of it. DO NOT USE A PREVIOUS VERSION OF QUARTZ.

2.) Execute your appropriate database script. They can be found in the quartz distro under the docs\dbTables subdirectory. Make sure that indexes are setup as outlined here.

3.) Wrap a batch processing service with some form of Quartz. Here's the wrapper we used:
public class GenericQuartzJob extends QuartzJobBean
{
protected Logger logger = new Logger(getClass(), Constants.LOGGER_APP_NAME);

private String batchProcessorName;

public String getBatchProcessorName() {
return batchProcessorName;
}

public void setBatchProcessorName(String name) {
this.batchProcessorName = name;
}

protected void executeInternal(JobExecutionContext jobCtx) throws JobExecutionException
{
try {
SchedulerContext schedCtx = jobCtx.getScheduler().getContext();
ApplicationContext appCtx =
(ApplicationContext) schedCtx.get(
"applicationContext");
IBatchProcessor proc = (IBatchProcessor) appCtx.getBean(
batchProcessorName);
proc.invoke();
}
catch (Exception ex) {
logger.error("Unable to complete execution of " + batchProcessorName, ex);
throw new JobExecutionException("Unable to execute batch job: " + batchProcessorName, ex);
}
}
}

With that wrapper, you can execute any batch processor that is wired up in Spring, that implements the homegrown IBatchProcessor interface (which typically only has some variant of an execute or invoke method). You don't need to manage the dependencies of those batch processes as they themselves are just beans defined a Spring app context somewhere. Additionally, the base class jumps through the various contexts that you must navigate to get a properly wired bean from the Spring factory.

4.) Configure the Job Detail in your Spring app context with an xml snippet resembling this:

    <bean id="someJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.some-company.batch.GenericQuartzJob" />
<property name="jobDataAsMap">
<map>
<entry key="batchProcessorName" value="SomeJobBean" />
</map>
</property>
</bean>

This definition creates an instance of GenericQuartzJob (which fulfills the contract required by JobDetailBean), and plugs in the bean name of a batch processor defined somewhere else in the app context with all of it's necessary dependencies.

5.) Configure the Trigger in your Spring app context. A simple cron based version would look like this:

    <bean id="someCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="someJobDetail" />
<!-- Cron expression runs at 1am and 1pm -->
<property name="cronExpression" value="0 0 1,13 * * ?"/>
</bean>

And yes, it did take me an hour and a half to get that cron syntax working correctly. Some habits die hard.

6.) Configure the SchedulerFactoryBean

    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
<property name="applicationContextSchedulerContextKey" value="applicationContext" />
<property name="dataSource" ref="qtzTxDataSource"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="overwriteExistingJobs" value="true"/>
<property name="autoStartup" value="true" />
<property name="triggers">
<list>
<ref bean="someCronTrigger" />
</list>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceName">SomeBatchScheduler</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate</prop>
<prop key="org.quartz.jobStore.tablePrefix">qrtz_</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<prop key="org.quartz.threadPool.threadCount">25</prop>
<prop key="org.quartz.threadPool.threadPriority">5</prop>
</props>
</property>
</bean>

That configuration while lengthy does a few very important things. Let's go through them. The applicationContextSchedulerContextKey property will ensure that the app context is available to all of those instances of the GenericQuartzJob wrappers. The dataSource and transaction manager are necessary in order to ensure that the database is updated in a safe manner (many server instances may be updating the database at once). Their bean definitions are pretty much typical for Spring, checkout the Spring reference docs if you need more info there. OverwriteExistingJobs will make sure that every time the scheduler is started it will use the list of triggers found internally to overwrite any existing ones that may have been changed in the database. AutoStartup makes sense, but I'm not entirely sure it's necessary.

The quartz properties can be maintained in a separate file, but I prefer they are inline with the scheduler definition. They are all pretty much self explanatory, and explained in greater detail, but nested deeply in the Quartz docs.

Hopefully this article will advance you to the point of configuring a clustered, database backed, scheduling system within hours instead of days. This configuration will get you a set of spring enabled batch processes that have dependencies wired as normal, with the added benefit that their schedule is persisted and fault tolerant across nodes in the cluster. This also leaves the door open for a couple of methods of doing ad hoc runs of the jobs. We'll cover that in a part 2 article shortly.

Tuesday, June 10, 2008

Ruby Integration with Spring

I recently gave a presentation at COJUG on ten facilities in Spring that you may not know much about. I saved my favorite for the last. Dynamic Language integration. This facility has been around since Spring's 2.0 release, but has been mired in the relative obscurity of Chapter 24 of their docs.

While many IT managers might be hesitant to adopt a language like Groovy or Ruby for their production environment due to misconceptions about performance, security, or what have you. The management types should have very little concern with testing code making extensive use of dynamic languages. If Ruby or Groovy provides a lower barrier of entry for complex testing or mocking, why not make use of it?

Spring provides the typical DI goodness of abstracting away the underlying implementation and allowing the developer to switch from mock to production code without changing client code. In the case of Ruby backed implementations, JRuby provides the hooks to allow the .rb file to be recognized as an implementation of the Java interface.

Here's a simple interface implemented in Java with which I've created a Java and a JRuby implementation.



A JRuby based implementation of this only has a few tricks like including the library and calling a method to include the class



Finally, with the spring integration facilities, a few lines of xml locates the file and plumbs in the implementation. Client code accesses the Java interface, none the wiser to the Ruby implementation.



There are a couple of gotchas to keep in mind with JRuby/Groovy Spring integration:
- JRuby 1.1 is not supported until Spring Framework 3.0, use JRuby 1.0
- Model code after what I have above, not what is in the Spring reference docs. At last check the docs were somewhat confusing in the use of include versus include_class
- AOP can be used to wrap the dynamic beans just as if they were POJOs. The one big caveat here is to make sure they are implementing an interface. Class based proxies will not work

Spring's support for dynamic language beans is pretty powerful in it's simplicity. The uses of this technology are much farther reaching than just mock scenarios, though. JRuby or Groovy files can be polled and reloaded without compilation or server restarts. This can be immensely useful for dynamic portions of applications like lightweight rules, environment configuration, validation, or even web site navigation.

Hope this helps get you started with integrating dynamic languages into your Java code. Please leave a comment with your scenario if you are using or planning on using dynamic languages integrated with Spring.

Thursday, May 1, 2008

A Polarized Community?

The news that SpringSource announced yesterday regarding their application server is not surprising but possibly very concerning to many developers in the Java landscape. We see now a very clear divide between people's perception of what is standard for Java Enterprise Development. Is the standard the open source platform that is used in a greater number of projects or is the standard the framework released by the Java Community Process? In my opinion it is very clearly the former.

I'm in the fortunate position of seeing every Java requirement that comes in to my consulting company and guess what? The number of Spring requirements far outweighs the number of EJB, let alone JSF reqs. I still see more Struts requirements than JSF and EJB reqs combined. So now, is the news that not only is there a non-standard framework, but also a non-standard application server something to be concerned with? Hell no.

How many developers have actually taken advantage of the fact that your app can be ported to different app servers with "no code change"? I've been on one project in the last 10 years that did so and guess what? We still had to change a lot of XML to make sure that stuff didn't break. Portability is a farce at the app server level and it's largely unnecessary.

So if there is no need to port my SpringAppServer application to JBoss or WebLogic or god help me WebSphere, what are the issues with adopting SpringSource Application Platform? It surely will present some amount of a learning curve. It may not be adopted by many of my clients initially who continue to write checks to IBM and BEA for inferior products that lag behind the so-called standards.

On the flip side, it will provide the ability to roll out smaller, componentized versions of your applications. It will let you keep multiple versions of the same components running on the same server. It will let you deploy your app without restarting your server. It will cost about $15k per cpu less than BEA or IBM products. Oh, and it will not force you to use JDK 1.4 or prior in order to run on the system.

Is it really a polarized community if everyone is heading in one direction?

Saturday, December 15, 2007

The Spring Experience - Day 4

Day 4 started much like Day 3 with another good presentation from Ben Alex regarding Spring Security. This session focused on the enhancements provided in Spring Security 2:

  • Annotation driven security that allows a developer to specify required roles directly above a method declaration

  • User management API for creating users and default implementations for JDBC and LDAP backed stores

  • Hierarchical roles. UPDATE_ALL implicitly grants you UPDATE_CUSTOMER, UPDATE_ORDER, etc...

  • Many other features like NTLM support, Portlet Security integration, and Automatic login page generaton


The second session I hit was RESTful web services in Spring by Arjen Poutsma. This session was a combination introduction to REST (Representational State Transfer) and highlight of facilities coming soon for developing clients and providers of these web services. It was great to see how similar the EndPoints Arjen displayed were to the Controller classes shown by Keith Donald earlier in the week in the RESTful web sites talk. Despite the number of disparate people working on these separate Spring based sub-projects, they are all adhering to a few common designs that make it very easy for a Spring developer to become productive in each of the environments.

OSGi was next up, presented by Adrian Colyer and Costin Leau. OSGi will provide Java application developers with a facility for deploying and managing separate versions of the same subsystems or libraries. The examples shown were somewhat contrived, but the concepts of OSGi are extremely powerful and immediately useful in at least two of the last three Java clients I've worked at. If you've ever found yourself trying to juggle version collision of components in your application, be sure to investigate OSGi.

Final talk of the conference for me was Spring Batch Internals by David Syer and Lucas Ward. They covered a plethora of the common issues facing batch processing systems and the solutions provided to these issues by Spring Batch. Batch processing seems to be the red headed step child of software development. Continually neglected while SOA and AJAX based applications win all of the adoration of the parents. Regardless, it is still a significant portion of the software projects out there and there are a wealth of common patterns that can be pulled up a level into a framework like Spring Batch. I'd go into more detail on it but I am seriously exhausted and my head hurts from the amount of information presented at this conference.

In a nutshell, the content at this conference was great and the majority of the speakers were very good. Only downside was that I didn't win an iPhone.

Friday, December 14, 2007

The Spring Experience - Day 3

Started off day three with Spring Security directly from it's creator, Ben Alex. The session provided a good intro to Spring Security but I felt bad for Ben as he got peppered with 4011 questions during the talk. Even with all of the tangents, Ben did a good job of presenting the core benefits of Spring Security. An example of it's power is to have a configuration that intercepts a method, say getEbayItemListing() and checks to see before execution if the user is authorized to perform this action. This can be a complex check that even validates if the current requester is actually seller of the item (instance level authorization). Then upon method completion, the after advice will mask the minimum sale amount by nulling it out on the object if the requester is not the original seller. With this being performed at the method level, it doesn't matter if the request comes from a website, web service, or other Java program. Very powerful.

Rob Harrop gave a talk on concurrency in Java that was very in depth coverage of the Java 5 concurrency objects. There was a ton of info in that session that I'll not cover here other than to say if you are developing in a multi-threaded environment in Java 5, please review the docs in the java.util.concurrency package.

The third session I attended was from one of my favorite tech speakers Venkat Subramaniam. Venkat covered Spring's facilities for integrating dynamic language objects like Ruby and Groovy classes into your Java framework as plain beans. I had no idea that this facility existed and as with most things Spring, it is accomplished very painlessly with a little configuration. A great use case for this is on the fly loading of dynamic processing logic (like rules) without stopping your application or server. Want some small dynamic rules processing without dealing with a full blown rules engine like JRules or JBoss rules? Here's your answer (and you don't need to wait for your company to deploy Java6). The second half of his talk covered using the GroovyObjectCustomizer object from Spring to implement a DSL. This also seemed relatively simple, but it was surprising how much more complex it was to implement in straight Java versus Groovy. I still prefer Ruby though.

The final talk before 500 pasty, flabby geeks descended upon the Hollywood, FL beach was Spring Web Services by Arjen Poutsma. I didn't gather a ton of info out of this session but a couple of nuggets were useful. The speaker advocated the opposite approach of XFire. Basically that you should start with the contract and work back towards mapping to your domain which I think makes sense in all but some of the more trivial cases. Additionally it seems that once you get the gist of Spring and the annotations provided in 2.5, moving from Spring MVC and WebFlow to something like Spring WebServices is rather trivial.

Time to hammock up!

The Spring Experience - Day 2

I focused on web framework related sessions today and came away with a wealth of knowledge and a long list of technologies to investigate further. Keith Donald gave a presentation on full stack web frameworks that was very interesting. He gave a very unbiased perspective on how frameworks like Grails, Rails, Django and others excel and lag with respect to about 10 criteria that comprise a "full stack" web framework (AJAX, REST, data binding, security, testability, etc...). He offered that Spring really doesn't have a full stack web framework, but instead acts as a foundation for them (Grails being built on top of it for instance). That is changing however as Spring MVC and WebFlow are adapting and integrating with some other technologies to really provide a complete offering.

I attended a few other sessions that focused on REST with Spring, AJAX offerings, JSF and WebFlow based apps, and Reasonable Server Faces. They all provided ton of information outside of my traditional area of expertise (middleware and persistence).

I think the most striking thing that I realized in these sessions though was how much of a huge step up in productivity there is in Spring 2.5. Annotations seem like a much better fit for metadata and being able to tell the container to only autowire a few certain dependencies right at their declaration point is immensely useful. Spring Security (formerly ACEGI) has gone from around a minimum of 150 lines of configuration to about 15 for the simplest cases by making use of these constructs. Spring 2.5 maintains backwards compatibility as well, so run, don't walk to the download if you haven't already.

Thursday, December 13, 2007

The Spring Experience - Day 1

Day one of TSE was just registration, dinner, and a keynote by Rod Johnson but it was a great evening for a couple reasons.

Rod's keynote focused on the changing of the guard and disruption for the Java EE landscape. Most notably, his contention was that the committee driven process that we have now is largely failing. EJB 3.0 being just the latest example. OpenSource is a much more dynamic and user driven process that nearly immediately produces software and frameworks that a lot of users need. The committees by contrast are steered by people who try to sell application servers and move at the pace of a Columbus driver in a 1/2 inch of snow (aka very s l o w l y). I think his point here was right on and I think it might signal a very polar divide between users and committee.

Additionally, the conference passed out Rod Johnson bobblehead dolls complete with the pose from this book cover:



Classic!

Monday, December 10, 2007

Christmas Comes Early for Spring Fanboy



Wednesday I leave balmy Ohio (currently 38 degrees with showers) for Hollywood, FL (currently 82 degrees). Weather aside, I am extremely excited as I'm going there for the Spring Experience conference. As big a fanboy as I am with Spring, I'm somewhat daunted by the sheer volume of information that will be coming at me this week. There are 70 1.5 hour sessions crammed into 3 full days and I've got more than a passing interest in attending about 50 of them.

TSE is organized by Jay Zimmerman of NoFluffJustStuff fame, so I've got high expectations. I've been to NFJS conferences the last four years and every time I come back to work re-energized and armed with a bevy of new tools and techniques that are immediately applicable to my daily work. NFJS typically brings only noted authors and thought leaders in as speakers for these conferences and this one is no different with Rod Johnson, Juergen Hoeller, Rob Harrop, Ben Alex, Ramnivas Laddad, and a slew of other Spring contributors and experts speaking at the conference.

I'm going to have the laptop with me and battery willing, I'll be able to share my impressions throughout the conference.

Time to get packing. Now where did I put the old banana hammock...

Wednesday, November 21, 2007

The first of many Spring kicks arse posts

In my opinion, nothing has brought life into Java development like the Spring Framework. Enterprise development in Java 4 years ago had me scratching my head. Why do I need to implement methods in this interface when I don't declare I implement it? Why do I need Entity Beans? Which of the 8 web frameworks should I be using? Why does it take so long to go from fixing a bug to actually testing that it worked? Spring has in some way, shape, or form answered all of these questions. Well except for the 8 web frameworks one.

Spring started with a couple of developers who were as frustrated as I was with the complexity inherent in Java enterprise development. Fortunately for our community, they were and are much smarter and driven than I am and they wound up with a set of tools that simplify almost every aspect of development in a Java enterprise. I think one of the keys of Spring's success has been focusing on simplifying advanced concepts and providing extremely useful tools out of the box. This example shows how Spring has simplified Aspect Oriented Programming which was a rather radical shift for Java developers in the early days of AspectJ. Additionally it provides something that 90% of all Java projects would want out of the box. Simple entered/exited logging and performance monitoring.



This code in it's current state will provide good trace logging for any bean named *DAO or *Service. Change or add the interceptor name to PerformanceTraceInterceptor and it will provide performance metrics using the JAMon performance monitoring utility. All of this provided out of the box with Spring. Stay tuned for more Spring fanboy-ism in the future.