Deadlines Revealed: The Truth About How We Make It Across The Line

Even though all software developers have the best of intentions, sometime we have to bend the rules a bit in order to make deadlines. In most cases these hacks don’t last too long in the codebase, although Microsoft are just getting around to fixing a 17 year old bug. One of the funniest and most original articles I’ve read, that relates to this topic is Gamasutra’s Dirty Programming Tricks. The article is basically a collection of nine pieces of trickery and hackery that people encountered in their programming career. It would be great to hear of your own experiences in the Java development world.

It’s not all hacks though. My favourite trick in there is The Programming Antihero. In this example the team are working on a project where the memory footprint has to be low. Unknowingly to the team who working tirelessy to save every megabyte they can, a senior developer has purposefully injected a wasteful 2MB to make the problem seem worse. Once everyone has got as close as they can to the target, he deletes the call putting the project back on track.

“…so he explained to me that he had put aside those two megabytes of memory early in the development cycle. He knew from experience that it was always impossible to cut content down to memory budgets, and that many projects had come close to failing because of it. So now, as a regular practice, he always put aside a nice block of memory to free up when it’s really needed.”

You’ll find lots of other examples throughout the article covering some shameful hacks to get around those last minute bugs. In my time I’ve had to write plenty of “this is a hack”, or “here be monsters” comments, to warn other developers about the dirty code that I’ve had to inject into my applications. I’ve had to put in Thread.sleep() to get around some problems. I’ve seen times that adding a System.out.println() allows the code to execute nicely, where removing it has caused things to break.  Don’t worry, I’ve gone back and debugged through these issues carefully and fixed them.

At deadline time, sometimes you just have to do whatever it takes. I’d like to hear your software development confessions here. I’m sure there’s no developer out there that hasn’t damaged their integrity briefly to get across the line.

Design Patterns Uncovered: The Iterator Pattern

Today’s pattern is the Iterator pattern which formalizes how we move through a collection of data in a particular class

Iterator in the Real World

MP3 player control is a good example of an iterator. The user doesn’t mind how to view their list of songs, once they get to see them somehow. In older mp3 players, this was done using simple forward and back buttons. With the iPod this changed to the wheel navigation concept. The iPhone moves this on further to use swipe movements. Nevertheless, the same idea is provided by all interfaces – a way to iterate through your music collection.

Design Patterns Refcard
For a great overview of the most popular design patterns, DZone’s Design Patterns Refcard is the best place to start.

The Iterator Pattern

The Iterator pattern is known as a behavioural pattern, as it’s used to manage algorithms, relationships and responsibilities between objects.. The definition of Iterator as provided in the original Gang of Four book on Design Patterns states:

Provides a way to access the elements of an aggregate object without exposing its underlying represenation.

Let’s take a look at the diagram definition before we go into more detail.

The Aggregate defines an interface for the creation of the Iterator object. The ConcreteAggregate implements this interface, and returns an instance of the ConcreteIterator. The Iterator defines the interface for access and traversal of the elements, and the ConcreteIterator implements this interface while keeping track of the current position in the traversal of the Aggregate.

Using this pattern, you can build on the standard concept of iteration to define special iterators that only return specific elements in the data set.

Would I Use This Pattern?

This pattern is useful when you need access to elements in a set without access to the entire representation. When you need a uniform traversal interface, and multiple traversals may happen across elements, iterator is a good choice.

It also makes you code much more reasonable, getting rid of the typical for loop syntax across sections of your codebase.

So How Does It Work In Java?

Java provides an implementation of the Iterator pattern, which provides next() and hasNext() methods. Creation of the iterator in Java is typically done through a method named iterator() in the container class.
The following example shows use of an iterator with a list :

List<String> list = new ArrayList<String>();
//add strings 

Iterator it = list.iterator();
while(it.hasNext())
{
   String s = it.next();
}

Now let’s go to an example where we create the constructs ourselves, with a remote control example.
First we’ll create an iterator with the standard methods:

//Iterator interface
public interface ChannelIterator
{

	public boolean hasNext();

	public void next();

	public String currentItem();

}

Next we create the Aggregate interface, in this case a TV.

//Aggregate interface
public interface TV
{
	public Channel getIterator();
	//other TV methods
}

The concrete implementation of the aggregator has the capability to create the iterator

//Concrete Aggregator
public class ConcreteTV
{
	private ChannelIterator iterator;
	private List<String> channels; 

	public ConcreteTV()
	{
		iterator = new ConcreteChannelIterator(channels);
	}

	public ChannelIterator getIterator()
	{
		return iterator;
	}

}

Finally the iterator helps control how we navigate the data.

//Concrete Iterator
//Iterator interface
public interface ChannelIterator
{
	private List<String> channels; 

	private int currentPos = 0; 

	public ChannelIterator(List<String> channels)
	{
		this.channels = channels;
	}

	public boolean hasNext()
	{
		if(currentPos + 1 < channels.size())
		{
			return true;
		}
		return false;
	}

	public void next()
	{
		currentPos++;
	}

	public String currentItem()
	{
		return channels.get(currentPos);
	}

}

Of course this is a one-way remote control. We could implement back() and hasBack() methods to navigate backwards in our iterator.

Watch Out for the Downsides

I don’t see any disadvantages to this pattern. It’s simple, widely used and provides more readable code. However, you may disagree – if so, please let me know in the comments section.

Find Out More


The classic Design Patterns: Elements of Reusable Object Oriented Software
For more practical Java examples: Head First Design Patterns.

Design Patterns Uncovered: The Decorator Pattern

Today’s pattern is the Decorator pattern, which allows class behaviour to be extended dynamically at runtime.

Decorator in the Real World

The concept of a decorator is that it adds additional attributes to an object dynamically. A real world example of this would be a picture frame. The picture is our object, which has it’s own characteristics. For display purposes we add a frame to the picture, in order to decorate it. You’re probably already familiar with the concept of wrapper objects, and in essence, that is what a Decorator is.

Design Patterns Refcard
For a great overview of the most popular design patterns, DZone’s Design Patterns Refcard is the best place to start.

The Decorator Pattern

The Decorator is known as a structural pattern, as it’s used to form large object structures across many disparate objects. The definition of Decorator provided in the original Gang of Four book on Design Patterns states:

Allows for the dynamic wrapping of objects in order to modify their existing responsibilities and behaviours

Traditionally, you might consider subclassing to be the best way to approach this – but there will be cases that subclassing isn’t possible, or is impractical. This leads us to the Open/Closed Principle: classes should be open for extension, but closed for modification. This is a good principle to keep in mind, as it keeps your class stable, but leaves it open for extension if someone wants to add behaviour.

Let’s take a look at the diagram definition before we go into more detail.

The Component defines the interface for objects that can have responsibilties added dynamically, and the ConcreteComponent is simply an implementation of this interface. The Decorator has a reference to a Component, and also conforms to the  Component interface.  This is the important thing to remember, as the Decorator is essentially wrapping the Component. The ConcreteDecorator just adds responsibilities to the original Component.

Would I Use This Pattern?

The Decorator pattern should be used when:

  • Object responsibilities and behaviours should be dynamically modifiable
  • Concrete implementations should be decoupled from responsibilities and behaviours

As mentioned in the previous section, this can be done by subclassing. But too much subclassing is definitely a bad thing. As you add more behaviours to a base class, you will soon find yourself dealing with maintenance nightmare, as a new class is created for each possible combination. While the decorator can cause it’s own issues, it does provide a better alternative to too much subclassing.

So How Does It Work In Java?

You’ll see decorators being used in Java I/O streams. Stream classes extend the base subclasses to add features to the stream classes.

In our example, we’ll use emails to illustrate the Decorator.

First we have an email interface, which has a getContents method:

public interface IEmail
{
   public String getContents();

}

And we’ll provide a concrete implementation for use:

//concrete component
public class Email implements IEmail
{
   private String content;

   public Email(String content)
   {
      this.content = content;
   }

   @Override
   public String getContents()
   {
      //general email stuff
      return content;

   }

}

Now we’ll create a decorator which will wrap the base email with extra functionality. We’ll model this as an abstract class, and maintain a reference to the base email.

public abstract class EmailDecorator implements IEmail
{
   //wrapped component
   IEmail originalEmail;

}

Let’s say that emails that leave the company internal server need to have a disclaimer added to the end. We can just add in a decorator to handle this:

//concrete decorator
public class ExternalEmailDecorator extends EmailDecorator
{
   private String content; 

   public ExternalEmailDecorator(IEmail basicEmail)
   {
      originalEmail = basicEmail;
   }

   @Override
   public String getContents()
   {

      //  secure original
      content = addDisclaimer(originalEmail.getContents());
      return content;
   }

   private String addDisclaimer(String message)
   {
      //append company disclaimer to message
      return  message + "\n Company Disclaimer";
   }

}

And if we wanted to create secure, encrypted messages, we could use another decorator:

//concrete decorator
public class SecureEmailDecorator extends EmailDecorator
{
   private String content; 

   public SecureEmailDecorator(IEmail basicEmail)
   {
      originalEmail = basicEmail;
   }

   @Override
   public String getContents()
   {

      //  secure original
      content = encrypt(originalEmail.getContents());
      return content;
   }

   private String encrypt(String message)
   {
      //encrypt the string
      return  encryptedMessage;
   }

}

So, if our email sending client detects this message is going outside the company, we can invoke the appropriate decorator before sending:

public class EmailSender
{

   public void sendEmail(IEmail email)
   {
      //read the email to-address, to see if it's going outside of the company
      //if so decorate it
      ExternalEmailDecorator external = new ExternalEmailDecorator(email);
      external.getContents();
      //send 

   }
}

Watch Out for the Downsides

Overuse of the Open/Closed principle can lead to abstract and complex code. This principle should really only be used in places where code is least likely to change.

The Design Patterns book does point out a couple of disadvantages with this pattern. Decorators can lead to a system with a lot of smaller objects that will look similar to a developer and introduce a maintenance headache. Also, the Decorator and it’s enclosed components are not identical, so tests for object type (instanceof) will fail.

Find Out More


The classic Design Patterns: Elements of Reusable Object Oriented Software
For more practical Java examples: Head First Design Patterns.

Debugging Android: Using DDMS To Look Under The Hood

While working on an Android application recently, I ran into some problems, and was finding it difficult to work out what was actually going on in the emulator. As I’m using Appcelerator for my app development, I didn’t have the luxury of using the built in Eclipse tools to find out what was wrong. Luckily for me, Google have a tool for this type of situation: the Dalvik Debug Monitor.

You can invoke the debug monitor from the tools directory of your android SDK install using the ddms command.

Here’s a summary of what the tool provides:

Process View

When you first open DDMS, you will see a list of emulators on the left hand side. Each of these has a number of associated VMs running. Click on any of these VMs and you can view their information on the right hand side, including the threads and VM heap information. You can force garbage collection on any of the VMs at anytime using the trash can toolbar button.

You can also control the state of the emulator on the right hand side using the Emulator Control tab.  Here you can change items such as the voice and data telephony status. This is useful if you need to simulate roaming. You can even call your emulator, providing a source phone number. This section also has local controls to help you simulate location services, passing in you location using manual coordinates, GPX or KML.

File Explorer

The file explorer was the reason I booted up the debug monitor in the first place; I needed to see if a particular file I was providing with my app was included in the final apk that I sent to the device. Not only does the file explorer allow you to browse the emulator, but you can also push and pull files from the device, as well as deleting.  You can even create an SD card image for use in the emulator. When you’re confused about what’s getting included in your app, the file explorer is the place to go.

Device Log

The pane along the bottom presents you with the device log. Obviously this is really useful, particularly if you are not seeing enough information in your development tool.

Of course, the best way to get to know the tool is by using it. If you need to use the debug monitor, you will have your own specific use case, just as I did. I’m really impressed with the level of control and information in this tool. It’s already helped me out with some very tricky problems.

Design Patterns Uncovered: The Proxy Pattern

Today’s pattern is the Proxy pattern, another simple but effective pattern that helps with controlling use and access of resources.

Proxy in the Real World

A Proxy can also be defined as a surrogate. In the real work a cheque or credit card is a proxy for what is in our bank account.  It can be used in place of cash, which is what is needed, and provides a means of accessing that cash when required. And that’s exactly what the Proxy pattern does – controls and manage access to the object they are “protecting”.

Design Patterns Refcard
For a great overview of the most popular design patterns, DZone’s Design Patterns Refcard is the best place to start.

The Proxy Pattern

The Proxy is known as a structural pattern, as it’s used to form large object structures across many disparate objects. The definition of Proxy provided in the original Gang of Four book on Design Patterns states:

Allows for object level access control by acting as a pass through entity or a placeholder object.

So it’s quite a simple concept – to save on the amount of memory used, you might use a Proxy. Similarly, if you want to control access to an object, the pattern becomes useful.

Let’s take a look at the diagram definition before we go into more detail.

As usual, when dealing with design patterns we code to interfaces. In this case, the interface that the client knows about is the Subject. Both the Proxy and RealSubject objects implement the Subject interface, but the client may not be able to access the RealSubject without going through the Proxy. It’s quite common that the Proxy would handle the creation of the RealSubject object, but it will at least have a reference to it so that it can pass messages along.

Let’s take a look at this in action with a sequence diagram.

As you can see it’s quite simple – the Proxy is providing a barrier between the client and the real implementation.

There are many different flavours of Proxy, depending on it’s purpose. You may have a protection proxy, to control access rights to an object. A virtual proxy handles the case where an object might be expensive to create, and a remote proxy controls access to a remote object.

You’ll have noticed that this is very similar to the Adapter pattern. However, the main difference between bot is that the adapter will expose a different interface to allow interoperability. The Proxy exposes the same interface, but gets in the way to save processing time or memory.

Would I Use This Pattern?

This pattern is recommended when either of the following scenarios occur in your application:

  • The object being represented is external to the system.
  • Objects need to be created on demand.
  • Access control for the original object is required
  • Added functionality is required when an object is accessed.

Typically, you’ll want to use a proxy when communication with a third party is an expensive operation, perhaps over a network. The proxy would allow you to hold your data until you are ready to commit, and can limit the amount of times that the communication is called.

The proxy is also useful if you want to decouple actual implementation code from the access to a particular library. Proxy is also useful for access to large files, or graphics. By using a proxy, you can delay loading the resource until you really need the data inside. Without the concept of proxies, an application could be slow, and appear non-responsive.

So How Does It Work In Java?

Let’s continue with the idea of using a proxy for loading images. First, we should create a common interface for the real and proxy implementations to use:

public interface Image
{
  public void displayImage();
}

The RealImage implementation of this interface works as you’d expect:

public class RealImage implements Image
{

   public RealImage(URL url)
   {
      //load up the image
      loadImage(url);
   }

   public void displayImage()
   {
       //display the image
   }

   //a method that only the real image has
  private void loadImage(URL url)
  {
      //do resource intensive operation to load image
  }

}

Now the Proxy implementation can be written, which provides access to the RealImage class. Note that it’s only when we call the displayImage() method that it actually uses the RealImage. Until then, we don’t need the data.

public class ProxyImage implements Image
{
    private URL url; 

    public ProxyImage(URL url)
    {
       this.url = url;
    }

    //this method delegates to the real image
    public void displayImage()
   {
        RealImage real = new RealImage(url);
        real.displayImage();
    }

}

And it’s really as simple as that. As far as the client is concerned, they will just deal with the interface.

Watch Out for the Downsides

Usually this is the stage that I point out the disadvantages to the pattern. Proxy is quite simple, and pragmatic, and it’s one pattern that I can’t think of any downsides for. Perhaps you know of some? If so, please share them in the comments section

Find Out More


The classic Design Patterns: Elements of Reusable Object Oriented Software
For more practical Java examples: Head First Design Patterns.

An Introduction To Cassandra: The Data Model

I’m fairly new to the whole NoSQL game, and one thing I keep hearing is how great Cassandra is. Built by Facebook and open sourced in 2008, Cassandra is probably the most popular NoSQL implementation: “A massively scalable, decentralized, structured data store”. Cassandra takes it’s distribution features from Dynamo and the data model from BigTable.

Before we look at using Cassandra, we first need to understand the data model. For developers new to Cassandra, coming from a relational database background,  the data model can be a bit confusing. Here’s a summary of how the Cassandra data model is composed:

Column

A Column is the most basic element in Cassandra: a simple tuple that contains a name, value and timestamp. All values are set by the client. That’s an important consideration for the timestamp,as it means you’ll need clock synchronization.

SuperColumn

A SuperColumn is a column that stores an associative array of columns. You could think of it as similar to a HashMap in Java, with an identifying column (name) that stores a list of columns inside (value). The key difference between a Column and a SuperColumn is that the value of a Column is a string, where the value of a SuperColumn is a map of Columns. Note that SuperColumns have no timestamp, just a name and a value.

ColumnFamily

A ColumnFamily hold a number of Rows, a sorted map that matches column names to column values.  A row is a set of columns, similar to the table concept from relational databases. The column family holds an ordered list of columns which you can reference by column name.

The ColumnFamily can be of two types, Standard or Super. Standard ColumnFamilys contain a map of normal columns,

meanwhile Super ColumnFamily’s contain rows of SuperColumns.

KeySpaces

KeySpaces are the largest container, with an ordered list of ColumnFamilies, similar to a database in RDMS. The KeySpace is normally named after the application.

Multiple KeySpaces reside in clusters, the machines/nodes in a Cassandra instance.

For another summary of the Cassandra data model, check out the (nicely titled) “WTF is a SuperColumn“.

In the next article in this introduction series, we’ll move onto the good stuff: using Cassandra in Java.

Meanwhile, why not check out Cassandra: The Definitive Guide from Amazon.

Making the Good Programmer … Better

One of the hardest questions to answer in our industry surrounds the issue of what qualities differentiate a ‘good’ programmer from the rest? I just read Eran Galperin’s “What makes a good programmer?” post on the subject today, and thought that I would share my list of those essential skills and traits that I would look for in anyone on my team.

Adaptable and Flexible

It’s always been the case that you need flexible developers on your team, but at no other time in the short history of software development  has it been so important. If you’re usually the person that does the UI coding, we’ll want you to dig into the persistence layer. We might even want you to go do some testing, which you’d usually run a mile from. You may have been hired as a Java programmer, but we want you to write our next application in .NET, and maybe it’s best to accept that. It’s the world we live in, and you’ll be all the better for it. Multi-tasking is as important as being an expert in one narrow field. At the time it might not be pleasant, but your CV will impress as your next employer sees what you’re willing to do.

Enthusiastic

Maybe you went to university and studied computer science because you heard that was where the money is. A few years in, maybe it was not as rewarding as you expected, and you start getting disillusioned. A great programmer will lovecoding – maybe not the code their working on right now – but in general you should be someone who enjoys building something to solve a problem for someone. When you get a chance to have a cup of coffee at the desk you’ll be going to sites like JavaLobby, and finding how to improve. When you hear about Google’s latest move, or the newest web framework that everyone’s talking about you’re interested. After all, why wouldn’t you be – any ripples in the software development and IT landscape are going to reach you eventually.

A Pragmatic Thinker With a Scientific Mind

The Pragmatic Programmer is one of the most important books in the software industry. Not only is it timeless in the way that it doesn’t tie itself down to one language, but it provides a great set of guidelines. Thinking about the consequences of your actions is essential when working in a team, and my favourite metaphor is “No Broken Windows”. Maintain a consistently high standard in all your work – testing, coding and documentation alike – and others are likely to follow your lead. Let that slip however, and things can take a turn for the worse.

The best way to stay fresh, despite what programming language is currently in fashion, is to keep thinking scientifically. Any problem can be broken down and all languages have a similar set of a characteristics. While this may be natural to some and not to others, the main thing to do is to keep questioning yourself. Can you write this piece of code better? Could I present this information in a more structured way? Mind you, the answer is almost always yes, so use pragmatism to find a reasonable end to this questioning!

Well Organised

When I started programming I would just dive right into my latest task. And that was fine back then, as I was just beginning to get assigned tasks. A few months later, I went to a talk on time-keeping, and learnt a lot that I still utilise today. A good programmer will be well organised, perhaps sitting down at the end of every day to list out the tasks for tomorrow. If someone needs something else done, at least I can refer to this list and see where I can fit it in, or what else will get affected. A useful tool for this is Mylyn, a task based Eclipse plugin.

It pays to be organised on the code and documentation side of things too. An organised approach to packaging, class and variable naming and design, makes everything much easier to follow for others on your team, and for you when you look back at something after a few months.

Reasonable and Approachable

The majority of us work in team environments, so we have to possess people skills. All the great programmers who have respect are those who are approachable. You need to make time for those who feel they need your help, whether that’s a developer with a code problem or a project manager wondering about your estimates. Along with these skills, you should endeavour to be clear in all your communications – the worst thing that can happen after any meeting is that all parties walk out more confused than before.

Being reasonable can’t be underestimated. No matter what your position in the organisation, some negotiation will always be required. Maybe something can’t be done that way you know is right, but in the interests of moving forward, it’s good to be able to find some half-way point, rather than being too head strong.

Takes Chances

You can’t assume that someone else will tell you what the right thing to do is, and when. Maybe you need to move to the latest version of a framework even if you’re close to a release -especially if you feel there’s some benefit there. If you’re enthusiastic about your job, then you’ve probably been keeping up to date with what’s available. And if you’re flexible, you won’t mind sacrificing part of your lunchtime, or your spare time at home, to prototype and see if it works. Every chance has it’s costs, but all need some investigation rather than charging in blindly – be prepared to take that time.

Taking chances applies to your career too. Maybe this new startup is worth joining? Maybe you’re just comfortable in your job right now and you need to challenge yourself. You’ll notice there’s a common theme in any success story – the chance was worth taking, and the chances that were wrong calls help you learn.

Takes Pride In Their Profession

If there’s one point that you can take away and implement from this article it’s this one. Take pride in what you do.  Everything else falls into place, and you will become a great programmer if you take this advice. It’s a lesson learned from all professions – the people we regard as great are those who feel that their industry is the most important, the ones that want to believe that the world needs great programmers.

It’s difficult to do if you don’t love programming, but it’s still possible. You’ve to ask why you don’t like your job right now and find ways to address it. If you’re writing tedious code in the day job, maybe joining an open source project will kick off the spark for you again? You can spot developers who take pride in their profession a mile off, from the quality of the code they write, to their enjoyment at being given a difficult task.

This is just my opinion, and it doesn’t hit any of the real technical aspects of a developers job. Are there any other points here that I’ve missed that help produce the Über-programmer? From the great developers that you have known, what would you describe as their outstanding traits?

Effective Teamworking With Eclipse: Highlighting Local Changes

Eclipse can make your life really easy when it comes to working with version control systems. Over the next few articles, I’ll be sharing some of the tips that I’ve picked up while using Eclipse (with CVS).  When you make changes in your local workspace, the default decoration is a  ‘>’ before the change, up to project level.  This is fine, but isn’t particularly obvious when scanning through your workspace.

You can actually make these changes really stand out using some simple changes to your preferences.  You’ll find the preferences on by navigating to Window/Preferences/Team/CVS/Label Decorations

On the Text Decorations tab you can change the default change flags:

On the general tab, you can change the colors and fonts of anything that has changed locally.
First, click through to the Colors & Fonts page.  This part of the preferences dialog allows you to customize the colors that are used.

Now, when you enable font and color decorations, your changes will be much more obvious:

Hopefully you’ll find this as useful as I did. Eclipse is my everyday IDE, but I’m sure that similar settings exist in other Java IDEs. If so, please share how to access those capabilities with a response (or another article).

Effective Teamworking With Eclipse: Change Sets

The last two days I have been looking at various ways that Eclipse assists developers when working with version control systems. First, we talked about highlighting local changes, then we discussed how to automatically synchronize with the version control system. Todays tip deals with Change Sets, which is themost useful feature in Eclipse for seeing real context behind changes in version control.

To view change sets, you can synchronize as normal but by making a few changes to your Synchronize view, everything looks brighter.

First, go to the preferences dialog in the synchronize view and ensure change sets is visible for models:

Next, choose the drop down list on the third button in the view’s toolbar to choose change sets as your view:

 

Once this is chosen you’ll see all changes in the batches that they were committed in. The name of each change set will be whatever the author used as the commit comment, or if they explicitly create their own change set, it will use the change set title.

 

You can create your own change set by clicking on the changes in the synchronize view and choosing Add To> New Change Set.

Of course the neatest way of managing your change sets would be to use Mylyn, but we’ll cover that in another article.

Using the change sets view while synchronizing automatically makes viewing the differences between your local workspace and CVS simple.

Effective Teamworking With Eclipse: Autosync With Version Control

Over the course of your workday, you should find yourself synchronizing with your version control system frequently. After all, you need to see when somebody’s made a change, and the sooner you know, the sooner you can integrate that change locally before committing. Once again, Eclipse has a really easy way to schedule your syncs.

Everything you need is on the Synchronize view (Window/Show View/Team/Synchronize). From there, you can synchronize which ever projects you want.

Click on the synchronize menu (highlighted in red below) and choose Schedule. Here you can set the frequency of the synchronization.

You can also use the Synchronize Preferences dialog to ensure that when you start up Eclipse, that the sync is triggered automatically.

Put this together with yesterday’s tip and you have much better visibility into what’s going on in version control vs your own workspace.
Tomorrows article will add a final piece that makes teamworking with Eclipse much easier.