1 2 Previous Next

crazybob

27 posts
crazybob

Guice 1.0 Blog

Posted by crazybob Mar 10, 2007

We're pleased to announce the open source release of Google's internal Java dependency injection framework Guice. Guice wholly embraces annotations and generics, thereby enabling you to wire together and test objects with less effort than ever before. Annotations finally free you from error-prone, refactoring-adverse string identifiers.

Guice injects constructors, fields and methods (any methods with any number of arguments, not just setters). Guice includes advanced features such as custom scopes, circular dependencies, static member injection, Spring integration, and AOP Alliance method interception, most of which you can ignore until you need it.

An earlier version of Guice already powers Struts 2's plugin architecture. Google has been running Guice in mission critical applications for months, and now you can, too. We hope you enjoy Guice as much as we do.

Guice lives at Google Code. From there, you'll find the user's guide,Javadocs, and download. Please direct any questions to the mailing list.

With anonymous inner classes at one end of the spectrum and BGGA closures at the other, CICE closures rest comfortably in between.  
I've written up some patterns for using ThreadLocal. This is the first in what will hopefully turn into a series of articles on the core Java library and language.  

Scopes are one of the first things we learn as Java developers. Public, private and even protected scopes are easy enough to grok, but package-private scope alludes many Java newbies. I remember confusion when I first read about package-private scope; "Why would I ever need that?" I learn by understanding, not memorization. Missing the necessary context, my brain failed to retain package-private scope the first time through: in one ear, out the other.

Even when developers do have the background necessary to understand package-private scope, I think its inconsistency with the other scopes leads to further confusion. If you want a public method, prefix the method signature with public. For a private method, use the private keyword. Protected,protected. If you want a package-private method... omit the keyword altogether. For example, use String foo()instead of private String foo(). Adding fuel to the fire, Java documentation often interchanges the terms "package-private," "package," and "default." I'm embarrassed to admit I once tried to use package-private as a keyword.

Many programmers don't know (or think) they need package scoping. They try to work around its absence. Some messily expose implementation classes as part of their public API. This clutters the Javadocs and increases the library author's maintenance burden; whether the author likes it or not, they should support clients who depend on these implementation classes. Using package scope prevents clients from creating dependencies on internal implementation classes in the first place.

A few programmers like to put their public API in one package and their private implementation in another. They attempt to hide the "private" package from the client by not publishing its API. From a security viewpoint, exposing your private package to your public package inherently exposes it to everyone else (including the client). This may fly for application code, but you must hold reusable libraries to a higher standard. Java provides no way to say, "make foo public, but only for this one other package." In addition, splitting your public API and implementation into two different packages confines you to class granularity, whereas package scoping enables you to mix public and package-private members in the same class.

Others use protected scope when they should use package scope. My skin crawls when I see Javadocs dusted with protected members (Struts anyone?). This solution suffers the same fate as making your internal implementation classes public. Unlike package scoped members, protected members are still part of the public API; clients can access them, and the fields and methods show up in the Javadocs.

Package scoping particularly shines during unit testing. Some programmers argue that you should only test through the public API. Don't be silly. Limiting your tests to the public API contradicts the spirit of unit testing and subjects you to unnecessary dependency pain. I prefer to isolate and limit the amount of code I test at one time, and test as close to the code as possible.

To expose a class member to a test without impacting the public API, put the test class in the same package as the code it tests. Make the member you wish to expose to the test package-private instead of private (i.e. delete the private keyword from the declaration). I've actually grown accustomed to using package-private scope instead of private by default. Less typing, less clutter. To prevent clients from putting their classes in the same package as yours and accessing your package-private members, Java supports package sealing.

crazybob

Google @ JavaOne Blog

Posted by crazybob Jun 24, 2005

You won't find me loitering around Cam's booth this year. Google rented one of its own! I think the mass of Java work going on at Google would surprise a few developers. Did you know that Java powers Gmail, AdWords, and Blogger (to name a few)? Google also belongs to the JCPExecutive Commitee, not to mention a few JSR expert groups. Please stop by and meet some fellowengineers and me in person.

P.S. Don't forget about the blogger meetup Monday night from 6-8 at Thirsty Bear hosted bySimon Phipps.

When I first heard rumors of a "headless iMac" a few weeks back, I got very excited. I already have a Mac hooked up to my home theater system, and I would prefer something more consistent with the other components. I doubt very seriously Apple would leave the monitor out just to save money. The thought of a beige 15" PC CRT hooked up to an Apple gives me the willies. Hooking an Apple to a TV is a completely different story. This will be the Mac for your living room. I like the idea of computing from the couch with my Bluetooth mouse and keyboard. This won't just steal away existing Windows users. This has the potential to compel non computer owners. Imagine your grandparents emailing pictures from their big screen TV.

Though the photos of the "iHome Media Centre" on Engadget sure look convincing (JPEG meta data and all), I doubt they're genuine. One, Apple hasn't sued them yet (though you could also interpret this as Apple not wanting to acknowledge the authenticity). Two, all of the ports are on the back. I would hope it would have USB and firewire ports on the front to hook up digital cameras, etc. Three, the spelling of "centre" is a little too cheeky, even for Apple.

I do not foresee this being a PVR. First, a PVR would require more hardware and horsepower for the video encoding whereas a low end G4 is more than enough for playing back video. Second, why would you need to record anything when you can download it all from Apple's new iTunes-like service for video? iClips anyone? As easy as Tivo is to use, browsing and downloading in iTunes is even easier. This setup would also make much better use of hard drive space than a PVR because it doesn't suffer the limitation of encoding video in real time. If Apple partners with TV networks like they have record labels, I'll be able to watch my shows at the same time as those watching them on conventional TV.

Cross your fingers.

Update: The keynote is over. Oh well. The Mac Mini would fit nicely into a home theater system. I'm surprised it doesn't have an s-video output. Steve did say this is the year for HD. I guess I'll be sticking to my PowerBook and bittorrent for the time being. Maybe next year.

Yours truly is filling in on Mary's Friday Free Stuff Puzzler this week. As of this posting, no one has submitted a correct solution. Give it a shot:

Create an object "o" such that "o.getClass().getMethods()" returns a method that throws "java.lang.IllegalAccessException" when invoked.

Post solutions on Mary's blog. Mary will send some free Java swag to the first person that gets it right.

Update: We have a winner! Keep an eye on Mary's blog for an explanation of the solution.

Treat yourself this holiday season to a copy of Mike Clark'sPragmatic Project Automation. I love this book. Congratulations to the Pragmatic Programmers for this addition to the series and more importantly to the team. I'm already looking forward to future installments.

Foremost in my mind, the quality of the content to page ratio rocks. I'm tired of publishers stuffing 400 pages of bullshit down my throat. I don't have the time. Save your money. Save a tree. I want quality, not quantity. Mike writes as efficiently as he entertains. This book is airplane, stick it in your laptop bag and go, friendly. My shoulder thanks you, Mike.

Mike packed this book with awesome tips and tricks, some of which guest authors contributed. After reading it, you'll be making lava lamps turn on in response to build failures, your application will file bug reports automatically, and you'll have gained some insight into why Ant works the way that it does (as told by its creator). I personally learned how to create GUI installers automatically from my build file using free software. Cross platform wizard installer, $0. Happier end users, priceless.

I can't say enough good things about this book. Resolve to snuff out application down time this New Year. Put all of those little boxes called "computers" lying around your office to work. Spend more time on quality code (or with your family, whichever floats your boat). Buy a copy for your build guru. Buy one for your manager. I guarantee it will put you at the top of their gift giving lists next year.

I must run IntelliJ IDEA on Linux, but OS X is my OS of choice. After trying various setups involving X Windows, VNC, x2vnc, and Synergy, I've settled on running IDEA from my Linux box under X11 for OS X. In other words, IDEA runs on the Linux box but displays in OS X. For some reason, the Alt key did not work out of the box (which becomes an issue when I try to select a menu or hit "Alt+Enter" to import a class). I fixed the issue by creating.Xmodmap in my home directory on my Mac:

  keycode 66 = Alt_L
  clear Mod1
  add Mod1 = Alt_L Alt_R
crazybob

Porting the Cuckoo's Egg Blog

Posted by crazybob Oct 21, 2004

Russell Miles continues his introduction to AOP in Spring with aCuckoo's Egg Design Pattern example. TheCuckoosEgg interceptor routes method invocations to alternative implementations in his ReplacementFeatureclass. The example Spring AOP configuration takes nearly 60 lines of XML to say, "apply the CuckoosEgg interceptor toIBusinessLogic.foo() andIBusinessLogic2.bar()." Since Russell used the AOP Alliance API, we can reuse his same code with Dynaop and enjoy a considerably simpler BeanShell-based configuration:

  interceptor(IBusinessLogic, "foo", CuckoosEgg);
  interceptor(IBusinessLogic2, "bar", CuckoosEgg);

And, Dynaop integrates well with the rest of Spring.

crazybob

Google++ Blog

Posted by crazybob Oct 15, 2004

I just accepted a job offer from Google. Thanks for the hook up,Cedric.

Many have tried, but Google is the first company to convince me to leave beautiful St. Louis, MO (Go Cards!). I've decided I want to live in San Francisco as opposed to the San Jose area. I have to move in a couple weeks, but I have no idea where I'm going to live. I like lofts. Any advice would be much appreciated.

This won't impact my blogging [in]frequency or work on Dynaop.

Our resident Oracle guru just dropped a copy of the September/October edition of Oracle Magazine on my desk. Inside James Holmes usesDynaop to implement examples for his article "Taking Abstraction One Step Further." Thanks, James.  
crazybob

The AOP Elevator Speech Blog

Posted by crazybob Sep 20, 2004

So what's this AOP thing I've been hearing about?

Aspect-Oriented Programming (AOP) picks up where OOP leaves off. AOP enables me to abstract boilerplate code into one place as opposed to scattering it throughout my code base. AOP lets me say, "apply some code that follows this generalized pattern to all of these places."

Say for example that I have a form class that holds data from a screen. The class has multiple setter methods for the fields and anisValid() method that returns true if the form fields are valid.

  class LoginForm {
    ...
    void setUserId(String userId) { ... } 
    void setPassword(String password) { ... }
    boolean isValid() { ... } 
  }


 

My code calls the isValid() method multiple times, and it takes a non-trivial amount of time to execute (perhaps it validates against a remote system). It makes sense to cache the result and blow it away any time the form's state changes.

With traditional OO, code in each setter could delete the cached value, and the template design pattern could abstract the caching logic fromisValid() into a method in a super class. Unfortunately, adding caching logic impacts all of my form classes. The more form classes, the more changes. I have to put code in every setter (running the risk of accidentally missing one), and now I have to modify the form classes to implement a template method instead of isValid(). Lastly, reusing code through inheritance couples validation caching with other such reusable functionalities in the parent classes preventing me from reusing them independently.

AOP enables me to leave my form classes untouched and to fully decouple reusable functionalities. My form classes shouldn't care that I'm caching the validation result. With AOP, I can implement the caching logic in one module and apply it at runtime or build time to all of my forms or to other places that follow a similar pattern. Each new form I add will enjoy caching for free. I've gone from a constant maintenance effort to zero effort thanks to AOP. Plus, I have a lot less code to unit test.

 

Piqued your interest? Take Dynaop for a spin.

crazybob

Where is AOP? Blog

Posted by crazybob Sep 14, 2004

Dion is excited by the proliferation of AOP talks at the NFJS symposiums. Cedricremains skeptical about the adoption of AOP.

Many developers have an itch they aren't entirely aware of. Repeated boilerplate code causes it. AOP can scratch it. I survived without OOP for a long time, but now that I'm aware of it, and I understand it, I have no desire to go back. The same happened with AOP to a lesser degree. Whether others choose AOP or some other road, I'm confident the itch will get scratched. It's just a matter of time. Developers who understand AOP will open others' eyes to how they can improve their code, and they will in turn open even more developers' eyes. Pay it forward. I've witnessed this effect in my own company as interest in AOP slowly but surely snowballs.

In regard to alternate roads, annotations (assuming I understand them correctly) have the potential to partially supplant AOP, solving some problems in a less powerful but simpler manner. Take undo logic for example. I can use AOP to pick out undoable methods and apply undo logic to them completely independent of the target code. Or, I can just add @Undoable annotations in the source code of the undoable methods and inject the undo logic at compile time (generating undo command classes, etc.). The annotation-based approach isn't as concise as an AOP-based implementation, but some might argue that it's more maintainable.

crazybob

Don't Try This at Home Blog

Posted by crazybob Sep 11, 2004

Dr. Josh Bloch and Dr. Neal Gafter (Click and Hack) guest starred on Mary's Friday Free Stuff Puzzler last week. Every week, Mary, a Sun marketing geek, boxes up random items she finds around her office and ships them off to the weekly winner. Her blog is a fun read. Check it out.

Click and Hack provided an example of subverting compiler exception checking (i.e. throwing a checked exception like an unchecked exception) using the deprecated Thread.stop(Throwable) method, and then challenged the reader to do the same with a non deprecated method and without any sort of bytecode trickery. They knew of two possible alternate solutions, one that would work with any JDK, and one that was JDK 1.5 specific. Their provided example method performs the same function as the throw clause, except the caller is not forced to handle checked exceptions:

 public class Thrower { public static void sneakyThrow(Throwable t) { Thread.currentThread().stop(t); // deprecated } } 

See for yourself by running this example program:

 public class Test { public static void main(String[] args) { Thrower.sneakyThrow(new Exception("Ouch")); } } 

The first solution takes advantage of a bad design decision in the Class.newInstance() method. Class.newInstance() directly propagates any exception thrown by the default constructor. The API designers have since avoided problems in other reflective methods by wrapping target exceptions. For example, Constructor.newInstance(Object[]) throws InvocationTargetException which wraps any exception thrown by the target constructor. This helps the client differentiate between target exceptions and exceptions thrown by newInstance() itself.

 public class Thrower { private static Throwable throwable; private Thrower() throws Throwable { throw throwable; } public static synchronized void sneakyThrow(Throwable throwable) { // can't handle these types. if (throwable instanceof IllegalAccessException || throwable instanceof InstantiationException) throw new IllegalArgumentException(); Thrower.throwable = throwable; try { Thrower.class.newInstance(); } catch (InstantiationException e) { // can't happen. e.printStackTrace(); } catch (IllegalAccessException e) { // can't happen. e.printStackTrace(); } finally { Thrower.throwable = null; } } } 

Note that the code sets the static throwable field back to null in a finally block. Neal added this to prevent a memory leak (this is why we trust these guys with our core code). "Who cares about how much memory one exception takes up?" some might ask. Though this is a trivial example, the real world implications are much larger. For example, without the finally block, if Thrower is in the system class path, we call sneakyThrow() with an exception whose class loaded in a web application, and then we try to hot deploy that web application, the VM can not garbage collect the old deployment. The system class loader holds a strong reference to the exception instance, which holds a strong reference to the class, which holds a strong reference to the web application classloader, which holds a strong reference to all of the classes in the web application (substantially more than one exception). Whether we're talking about a framework that handles AOP, dependency injection, or logging, the implementor has to keep this in mind.

The final JDK 1.5 specific solution takes advantage of the fact that the compiler does not type check generics at runtime. In defense of JDK 1.5, the compiler does print a warning.

 public class TigerThrower { private void sneakyThrow2(Throwable t) throws T { throw (T) t; // Unchecked cast!!! } public static void sneakyThrow(Throwable t) { new TigerThrower().sneakyThrow2(t); } } 

Filter Blog

By date: