Author of Spring in Action
Craig Walls has been professionally developing software for over 14 years (and longer than that for the pure geekiness of it). He is the author of Spring in Action (now in its second edition) and XDoclet in Action, both published by Manning and is currently writing about OSGi and Spring-DM.When he's not slinging code, Craig spends as much time as he can with his wife, two daughters, 6 birds, and 3 dogs.
Presentations by Craig Walls
From "Hello World" to Real World : Building Web Apps with Spring-DM
As a matter of good design and best practice, we all know we should divide our application code into logical layers or modules that can be developed independent of each other. But if modularization is a good practice to follow as we write our code, why do we package it all up into a monolithic WAR file for deployment?A (re)introduction to Spring Security
Spring Security (formerly known as Acegi Security) is a very powerful and flexible security framework for Java. Based on the Spring Framework, Spring Security provides declarative method and web level security including a wealth of options for meeting your application's specific security needs.Spring in Action: Fundamentals for Developing Spring Apps
Spring has been one of the most exciting frameworks to emerge in the past few years. With Spring you can decouple your application's objects, enrich them with AOP, and apply transactional boundaries and security to them declaratively. It simplifies data access, remoting, web services, and JMS. It comes with its own web framework. And, even though Spring eliminates much of the need for EJBs, it will still integrate nicely with any EJBs you may have lying around. What's not to love?Spring for the Angle-Bracket Averse: Developing Spring Applications with Absolutely No XML
One of the most prevalent myths about Spring is that Spring requires heavy use of XML. While it is true that XML is the conventional option for configuring a Spring application context, it is not the only option. Non-XML alternatives exist, including scripting configuration with JRuby or Groovy and annotation-based configuration with Spring JavaConfig.Spring Cleaning: Tips for Managing XML Clutter
A common complaint about Spring is the vast amount of XML required to configure an application. In this presentation, I'll show you ways to reduce or even eliminate much of the XML required to configure Spring.Testing With (and Without) Spring
Dependency injection and interface-driven development, two practices encouraged and supported by the Spring Framework, lead to more loosely-coupled code and, consequently, code that is more easily unit-tested. But how can you integration test your application components after they have been assembled by Spring?A (re)introduction to Spring MVC
Perhaps you've tinkered with Spring MVC before. Maybe you've even built an application or two with it. But its complex hierarchy of controller classes and the hefty amount of XML required to configure it has made it easy for you to be tempted by the siren song of other frameworks.Well, if you haven't had a look at Spring MVC lately, then it's time you take another look.
Books by Craig Walls
by Craig Walls
Spring-Loaded
got <beans>?
Wednesday, August 6, 2008
Just a short blog entry for today to let you know that I'll be speaking at the JavaMUG meeting in Dallas a week from today (8/13/2008). I'll be talking about two of my favorite topics: Spring and OSGi...or Spring-DM when they're used together. Hope to see you there.
Monday, August 4, 2008
I'm building a little OSGi application that has a search aspect to it. So I figured Lucene would be a great choice...or better yet, Compass since it's objects that I'll be searching on. In case you're not in the know, Compass is an object-to-Lucene mapping framework. Compass is to Lucene what Hibernate or JPA is to JDBC.
So, I decided to add Compass as a bundle in my application. But first, I need to make sure that it is a proper OSGi bundle. The minimum requirement for an OSGi bundle is that its META-INF/MANIFEST.MF contain a Bundle-SymbolicName: header. Sure enough, the Compass JAR has a Bundle-SymbolicName. So I'm good to go, right?
Private Packages
Hold on! Not quite yet. Even though Compass meets the minimum requirements to be an OSGi bundle, it's all but useless, because its MANIFEST.MF doesn't export any of its packages. What this means is that even though I can install Compass into an OSGi framework (such as Equinox), my other bundles can't see the contents of the Compass bundle. Effectively, Compass is entirely private.
No problem. I can use Peter Kriens' BND tool to wrap Compass with a MANIFEST.MF that does export packages I need. The magic BND instructions are:
Embed-Dependency: *;scope=compile|runtime;type=!pom;inline=true Import-Package: *;resolution:=optional
Or better yet, since I'm using Pax Construct, I can use pax-wrap-jar to do it for me:
% pax-wrap-jar -g org.compass-project -a compass -v 2.0.1
Split Packages
Okay, so now that the newly wrapped Compass bundle exports some packages, I'm ready to roll, right?
Well...not quite. You see, Compass depends on Lucene to do its bidding. So, I need to make Lucene available to Compass. The seemingly obvious way to do that is to install Lucene as a bundle in the OSGi framework. BND or pax-wrap-jar could help me do that, but then I run into a new problem...
A basic rule of OSGi is that no two bundles can export the same provide the same package...that is, no split packages. It turns out that within the Compass JAR are some org.apache.lucene.* packages which are also provided by Lucene itself. As a bundle, Compass provides its own org.apache.lucene.* content, so it will never see the packages exported by Lucene.
The solution? I ultimately decided that since I wouldn't be interacting with Lucene directly, it'd be best to embed Lucene within the Compass bundle. Pax Construct to the rescue again with its pax-embed-jar script:
% pax-embed-jar -g org.apache.lucene -a lucene-core -v 2.3.2
This adds a new entry to the Compass bundle's BND instructions:
Embed-Dependency: *;scope=compile|runtime;type=!pom;inline=true,\ lucene-core;groupId=org.apache.lucene;inline=false Import-Package: *;resolution:=optional
Okay, so now Compass is exporting packages for my bundles to use and has all of the Lucene stuff it needs. Surely my Compass woes are behind me now.
Dynamically Imported Packages
Not so fast! I used pax-wrap-jar (which uses BND) to automatically export the packages in the Compass bundle. That works. But when BND (via the Felix Bundle Plugin) generates the manifest for my bundles, it doesn't import all of the packages I need.
You see, BND is great at analyzing code and figuring out what packages are being used, both directly and transitively, and adding those packages the a bundle's Import-Packages: header. The problem, however, is that Compass makes liberal use of Class.forName() to dynamically load classes. Because the classes are loaded dynamically, BND doesn't know that they're needed. This meant that I needed to add instructions to the BND instruction file to ensure that BND would include them (either as more entries in Import-Package: or (even better) using DynamicImport-Package:):
DynamicImport-Package: org.compass.*
Now I think that I've bent Compass to my OSGi will. But it hasn't been easy. I wonder what other surprises Compass has for me as I continue to develop my application. But for now it seems to work.
Did I write this to gripe about Compass? Maybe...a little. I do think it's silly that they included a Bundle-SymbolicName: header but failed to provide any other headers that would make Compass useful in an OSGi context. The split package thing and dealing with dynamically imported packages were annoyances, but I worked through them.
And, let me be clear that I think Compass is great at what it does...kudos to the Compass team for such a great framework.
No, the main reason I write this is to highlight a few of the real-world gotchas you might encounter while working with OSGi and to give some insight on how you might deal with them. I love working with OSGi, but it will do no good if I candy coat the snags or sweep the hassles under the rug. It's better if I meet them head on, address them, and then share the experience with others.
I strongly suspect that Compass isn't the only JAR out there that presents these kind of problems when used in OSGi. I just picked on Compass because it was the one that has kept me on my toes the most lately.
Friday, August 1, 2008
If you're wanting to wade in the waters of OSGi (or even if you're ready to do a deep dive), you owe it to yourself to take a look at what the folks at OPS4J are doing, specifically with their Pax collection of projects.
Let me give you the nickel tour of what Pax has to offer...
Coin
Coin is a relatively new entry to the Pax family (at this time there's not even a release available). Pax Coin is advertised as a highly configurable implementation of the OSGi Configuration Admin Service Specification that supports configuration from a variety of sources. Those sources could include the file system, a bundle, or the service registry. I don't know much about Coin yet, but it looks very promising.
ConfMan
ConfMan is an implementation of the OSGi Configuration Admin agent that loads configuration details from a properties file. It does require that a Configuration Admin service be installed in the OSGi framework. It's unclear to me what the future of ConfMan is with regard to Coin, but I think that ConfMan could end up being an agent to feed Coin.
Construct
Pax Construct is, in my opinion, the crown jewel of the Pax family. In a nutshell, Construct is a Maven plugin, plus a dozen or so scripts that make short work of developing OSGi-based projects. I like to describe Construct as "OSGi on Rails" (DHH probably won't care for me using that name...oh well). Keeping the comparisons in the Java space, you might compare Construct to Matt Raible's AppFuse. But Construct is less about "let's build a web site" and more about how to quickly develop OSGi bundle projects. Pax Construct can generate project folders, wrap non-bundle JARs, embed JARs in bundle projects, manage your MANIFEST, provision your bundles, and much more. If you're just starting out on a new OSGi project, I'd definitely consider using Construct to kick start the effort.
Cursor
Pax Cursor is an Eclipse plugin that uses Pax Runner (see below) to provide all supported OSGi platforms in Eclipse. In contrast to Eclipse PDE which is limited to deploying to a single version of Equinox, Cursor makes it possible to work with Felix, Knopflerfish, Concierge, and even multiple versions of Equinox within Eclipse.
Drone
Pax Drone is an bundle testing framework for OSGi, based on JUnit. A Drone test case sets up an OSGi framework (using Pax Runner under the covers), installs a selection of bundles, then makes the BundleContext available to the test methods to make assertions against the framework and the bundles contained therein.
Logging
Pax Logging is an implementation of the OSGi Logging Service that provides the API of several popular logging packages (such as Log4J and Commons Logging). The problem with the conventional logging packages is that due to they way they deal with the class space, they are incompatible with OSGi. The problem with the OSGi logging service is that it doesn't implement any of the de facto logging APIs. Pax Logging satisfies both issues.
Reflector
Reflector provides the ability to inspect a running application without any special debugger. It comes in the form of a handful of bundles that can be installed/uninstalled at will (while the application is still running) to help pinpoint problems.
RadMan
Pax RadMan is still in drawing board and prototyping stages, so there's not much to see yet. But it aims to be a remote and distributed management solution for OSGi, enabling remote administration of an OSGi installation, including installation/update/uninstallation of bundles (among other things). Sounds interesting.
Runner
Starting an OSGi framework, then installing and starting all of the bundles in an application can be a tedious endeavor. Pax Runner simplifies all of that by starting an OSGi framework of your choosing (Equinox, Felix, Concierge, or Knopflerfish) and installing/starting a selection of bundles that you specify. What's especially cool about Pax Runner is that it can provision the bundles from several sources, including the file system, an HTTP URL, and from a Maven repository.
Swissbox
As the various Pax projects were being created, several common utilities were discovered. Those utilities found a home in Swissbox. But, since the utilities are generic, they can be used outside of Pax...perhaps in your OSGi application. Included are utilities for dealing with the core OSGi framework, writing implementations of the extender pattern, dealing with the service lifecycle, and tracking services.
URL
Most OSGi frameworks (Equinox, anyway) can resolve and install bundles from file and http URLs. Pax URL extends the framework to support other URLs, including...
- classpath: - Access resources in the classpath or within other bundles
- mvn: - Access bundles in a Maven repository
- obr: - Access bundles in an OBR repository
- war: - Automatically wraps WAR files with an OSGi manifest
- wrap: - Uses Peter Kriens' BND to wrap non-bundle JARs as OSGi bundles
Web
Pax Web is an implementation of the OSGi R4 Http Service. Under the covers it uses Jetty 6. What sets Pax Web apart from other implementations of the Http Service is that it supports the full Java web portfolio, including servlets, filters, listeners, error pages, and JSPs (most Http Service implementations only support servlets).
Personal note: I think Pax Web is great, but have stopped using it in favor of Spring-DM's Jetty and/or Tomcat bundles, which work much better with Spring-DM's web extender.
Web Extender
Pax Web Extender is an implementation of the extender pattern that watches for WAR bundles to be installed, then parses their WEB-INF/web.xml file to deploy them to the Http Service (such as Pax Web).
Personal note: Again, I like Web Extender, but find that Spring-DM's web extender is a much better choice for my Spring-oriented needs.
Wicket
Pax Wicket is an OSGi extension to Apache Wicket that makes it possible to add, remove, and move around parts of a Wicket application at runtime (without restarting the application) by loading and unloading OSGi bundles.
As I said in the beginning, Pax is a must-see collection of tools for OSGi developers. If you're working in OSGi or even interested in looking into OSGi, you should have a look at Pax. I'd start with Construct, Runner, and URL, as I have found them to be the most valuable parts. (Note that Contruct uses Runner in its pax-provision script, so if you're using Construct, you're already using Runner).
Today I've kept my blog entry peaceful, by giving you an overview of the goodness that Pax provides. But in my next entry I'll express a little frustration...a topic perfectly suitable for a Monday. In the meantime, have a Pax-ful weekend!
Thursday, July 31, 2008
It's been awhile since I've blogged here. Sorry. I've been a bit busy. What have I been doing?
Well, I'm not quite ready to fess up to the whole story...but my next few blog entries should give you some idea.
For today, a little Haiku clue (or Hai-Clue, if you will):
Monolithic WAR
Refit for OSGi
Modularity!
Monday, May 26, 2008
For quite some time I've been pondering OSGi and how it fits into enterprise Java. And that interest has been magnified over the past month with the release of "The Platform".
I've got lots of OSGi, Spring, and enterprise Java stuff cooking up--I'll share more about that in some future post. But today, I'm unveiling a new term that I've coined to describe the stuff I'm working on...
OS-JEE-i
After all, the "G" in OSGi isn't really applicable anymore. And I'm mostly interested in the intersection of OSGi and JEE--not purely OSGi, not purely JEE. The term "OS-JEE-i" hit me earlier today. I've Google'd it quite a bit and haven't found anyone else using it, so I thought I'd claim it before someone else does.
I hereby issue an almost obligation-free, irrevocable license to use the term. The only thing I ask is that if it catches on, then let it be known that you saw it here first. :-)