Recently in eclipse Category

Teamprise Releases Client Suite 3.2

March 3, 2009 1:31 PM

We at Teamprise are very excited about the newest release of our flagship
product, Teamprise Client Suite 3.2. This new release adds a bunch of new customer-driven features.

Flexible Project Mappings in Eclipse
Many customers - especially those moving from other version control systems - want more control over the import process in Eclipse. In earlier versions of Teamprise Plug-in for Eclipse, we required that your Eclipse projects live beneath the Eclipse workspace root. While this restriction was mostly sensible, many customers wanted to be able to keep a hierarchical project layout. In Teamprise Plug-in for Eclipse 3.2, we allow you to set up your local project layout however you wish, then perform your Import from Team Foundation Server.

To take advantage of this new functionality, open up Team Explorer before
performing your import and map your working folders manually before performing
your input. Let's say your projects look like this in Team Foundation Server:

$/BigProject
$/BigProject/Client
$/BigProject/Client/com.example.bigproject.client
$/BigProject/Client/com.example.bigproject.client.ui
$/BigProject/Client/com.example.bigproject.client.ui.win32
$/BigProject/Client/com.example.bigproject.client.ui.gtk
$/BigProject/Server
$/BigProject/Server/com.example.bigproject.server
$/BigProject/Server/com.example.bigproject.server.soap
$/BigProject/Server/com.example.bigproject.server.core

Now you can set a working folder mapping for $/BigProject - say to
C:\BigProject - then open up the Teamprise Import Wizard and select all your
projects. They'll be imported relative to C:\BigProject:

C:\BigProject\Client\com.example.bigproject.client
C:\BigProject\Client\com.example.bigproject.client.ui
C:\BigProject\Client\com.example.bigproject.client.ui.win32
C:\BigProject\Client\com.example.bigproject.client.ui.gtk
C:\BigProject\Server\com.example.bigproject.server
C:\BigProject\Server\com.example.bigproject.server.soap
C:\BigProject\Server\com.example.bigproject.server.core

You can even do a Get Specific Version inside the Source Control Explorer:
the Import Wizard won't overwrite the version you download, so you'll be
able to import a historic version easily.

The only restriction is that you must map these projects outside of your
Eclipse workspace root - projects inside your Eclipse workspace root must
live in a flat listing. (This is an Eclipse restriction, not a
Teamprise-imposed one. Sorry!)

Kerberos Authentication
Teamprise clients now support passwordless authentication to the Team
Foundation Server on Linux and Mac OS X platforms using a Kerberos ticket.
This provides a convenient, and secure way to authenticate to your Team
Foundation Server.

Switch to Branch
This is a handy little feature that allows you to work with multiple branches more easy in Eclipse. Want to work in a different branch? Simply right click on a project, select "Switch to Branch" and select the TFS branch that you want to work in. Then you can make whatever changes you want in that branch and switch back to your main branch.

Command-Line Client Functionality
The Teamprise Command-Line Client adds a lot of new functionality in 3.2, most notably full support for merging branches from the command line. CLC also adds conflict resolution, diff support and improved navigational functionality.

Other New Stuff
3.2 offers much better controls in work item tracking -- native controls for Areas and Iteration dropdowns, autocomplete for other work item dropdowns, and a better history control on most platforms. Plus we've added support for a new IDE: IBM RAD 7.5, as well as a new operating system: HP-UX on Itanium processors.

Teamprise Client Suite 3.2 (and any of the component products) is a free
upgrade for existing Teamprise Client Suite 3.x customers, as well as
customers with a current maintenance agreement. We recommend upgrading to
get these great new features.

Chicago: Java Development with Team System

April 15, 2008 6:14 PM

It's been a long time since I updated my blog, in part because I'm lazy, but mostly because we were busy putting the finishing touches on Teamprise Client Suite 3.0. We're very proud of our 3.0 release, it's got a lot of great new features, and we think you'll be very happy with it.

If you're in the greater Chicagoland area next week, I've been invited to the Chicago VSTS User Group to give a tour of the new version of Teamprise. If you're interested in how Team System can play nice with Java developers, I suggest you stop by and check it out:

The meeting begins at 5:30 PM at the Microsoft Chicago (Loop) Offices:
77 W Wacker Dr, Suite 2300

Please RSVP if you're going to attend.

Even if you can't make it next week, be sure to check out the Chicago VSTS User Group, or another user group near you. It's a great resource if you're a VSTS or Team Foundation Server user!

UI in your Eclipse 3.3-based RCP App

July 13, 2007 11:10 AM

So you're developing Eclipse RCP applications, and you're excited about moving your RCP app to the Eclipse 3.3 framework...

Wait, you're not? Then this post probably doesn't interest you too much.

But if you are, there are some UI changes in the way Eclipse 3.3 starts up that you should be aware of.

Likely, your application has a subclass of WorkbenchAdvisor, probably called something like YourWorkbenchAdvisor. And this is doing various useful things like creating views and setting preferences, all that good stuff. And maybe you're overriding WorkbenchAdvisor.postStartup() to do some useful things after the Workbench has started.

Maybe one of those useful things happens to be raising a Dialog. In versions past, this would have worked fine for you. In Eclipse 3.3, you may be in for a rude awakening. Despite the name, the Workbench has not started and the UI is not fully functional when YourWorkbenchAdvisor.postStartup() is called.

In particular: other threads cannot call back into the UI thread with Display.asyncExec() or Display.syncExec(). The UISynchronizer will queue up any runnable you post on to the UI thread to run once it actually has started. This can present a problem if the dialog you raise fires off a background thread to do some work.

For example, in Teamprise Explorer our login dialog has an option to test your connection to the TFS server. This involves firing off a background thread to look at your network settings, try to connect, etc. The results of these test are then posted back to the dialog using Display.asyncExec().

What happens in Eclipse 3.3? Since the login dialog was started from our postStartup() method, the UISynchronizer hasn't started. So when we call Display.asyncExec() to display our results, they're put in a queue to display once the UI has fully started. This, of course, only occurs after you've closed the login dialog, at which point there's no dialog to display these settings to.

Ouch.

To combat this, you should move any UI code out of YourWorkbenchAdvisor.postStartup(). You can either do this by putting your code in the UI queue to execute as soon as the Workbench starts fully, or you can move it out of postStartup() entirely and use a different hook to raise your UI once the Workbench is started.

These options are both sort of a hack, so you're welcome to use whichever you find less obscene:

  1. Queue your UI code in the UISynchronizer, where it will be run as soon as the Workbench is started
    If a non-UI thread calls Display.asyncExec() before the Workbench startup has completed, your Runnable will be queued to run after the Workbench has started, but this is only true if it's called from a thread other than the UI thread. So you need to get off the UI thread to post this into the queue. Firing off a new thread from your postStartup() method should do the trick:
    new Thread(new Runnable() {
        public void run()
        {
            Display.asyncExec(new Runnable() {
                public void run()
                {
                    // do something on the UI thread
                    // after Workbench startup
                }
            });
        }
    }).start();

    This will put your inner Runnable on the UI queue to execute as soon as Workbench startup is complete. (Had you called Display.asyncExec() from the current thread, it would execute immediately.)

    If you don't like the idea of stuffing a Runnable inside another Runnable, there's a second option:

  2. Override WorkbenchAdvisor.eventLoopIdle() to call your code the first time the UI is idle

    If you look closely at Workbench.runUI(), you'll see that the UISynchronizer isn't started until right before a call to Workbench.runEventLoop(). So hooking in to WorkbenchAdvisor.eventLoopIdle() is your first opportunity to execute code once the UI thread is properly started.

    Adding this to YourWorkbenchAdvisor should be sufficient:

    private static ThreadLocal eventLoopStarted = new ThreadLocal() {
        protected Object initialValue()
        {
            return Boolean.FALSE;
        }
    };
    private void start()
    {
        // do something on the UI thread after Workbench startup
    }
    public void eventLoopIdle(Display display)
    {
        // the ui is now started, we can do our work
        if(eventLoopStarted.get().equals(Boolean.FALSE))
        {
            // call any post-startup UI
            start();
            eventLoopStarted.set(Boolean.TRUE);
        }
        else
        {
            // default: yield cpu until new events enter the queue
            super.eventLoopIdle(display);
        }
    }

    I'm synchronizing on the eventLoopStarted flag, which is probably not necessary since only the UI thread should be calling eventLoopIdle(). But proof of thread-safety is left as an exercise for the reader.

    Also, if you override eventLoopIdle(), be sure you call back to the base class or call Display.sleep(). Unless, of course, you like burning up your processor whilst doing nothing.

There you go - with just a bit of hackery, you should be able to move your RCP application over to Eclipse 3.3 and still get all the same UI at application startup time.

Who's Afraid of the Big Bad Merge

March 6, 2007 2:30 PM

This is Part One in my introduction to the Eclipse Synchronize View

I'm not ashamed to admit it: my first time was terrifying.

It was a friday afternoon in late spring, and I was lazily fixing bugs while mostly thinking about what I'd do when I got off work. I wasn't even paying attention - I was just staring out the window when I decided to do a Get Latest. Then, from nowhere, was the Big Bad Merge.

It turns out that one of my coworkers had done a major refactor of our project, and we'd both been working on many of the same files. Automerge couldn't handle it - oh no, these changes were nasty and invasive - I resolved them all by hand, well into the night.

The state of version control has changed significantly since then - atomic transactions and bug tracking integration were unheard of then - but even with a version control tool like Team Foundation Server, many of us still have no idea what's coming at us when we do a Get Latest. Many of us have no idea when the Big Bad Merge might appear for us to fight again.

It's a scary thing to live in constant fear of conflicts. Many programmers have strategies for dealing with this unknown... most of them ineffective... Here are some of the coping mechanisms I've seen:


The "Real Programmer"
Many programmers, after their first few Big Bad Merges, develop a strange belief that merging is somehow a "real programmer's" sport. That their successful ability to merge widely disparate codebases is what separates them from those lower echelons of untalented hacks who use crutches like "automerge" to get the job done for them. The eschew tools - preferring to pore over every line of code, fixing even indentation and line breaks, than trust a tool to do the job for them.

Their tales of "that nasty conflict that took all day to resolve" are often accompanied by bragging about how they merged back in "the old days", presumably done on punch cards, uphill both ways in the snow.

This particular coping mechanism is very dangerous, as it's entirely psychological and doesn't actually get your conflicts resolved any quicker or more accurately. It often has the opposite effect, as these are the sorts of people who are prone to throw out their three way merge tools[1] in a fit of hubris.

You can identify the "Real Programmers" easily as they use obscure operating systems with an 80x24 green on black terminal, and drink black coffee (not because they like it, but because it puts hair on their chest.)


The "Edge Case"
Some programmers have had just one too many of those really hard merges and it's left them shell-shocked and resentful of ever having to do it again. They respond with a little insurance policy - a second copy of the source tree, isolated from the one they're working in, which they keep updated constantly so they know what conflicts are coming down the line.

Unfortunately, the line between "proactive" and "insane" gets blurred pretty quickly and eventually they're spending as much time looking at the changes you've made as they spend actually working. They get farther and farther away from the server's version and closer and closer to that Big Bad Merge they were trying so desperately to avoid. As they realize what's happening, they become increasingly nervous and erratic. They often become angry and will lash out you - after all, it's you that made those checkins, and put their working repository into a conflicted state. (Helpful hint: avoid the "Edge Cases" with an affinity for large caliber firearms.)

Eventually, these programmers will spend a panicked, sweaty afternoon getting their changes checked in and their work repository up to date, and they'll be productive again... at least until the next conflict.

You can identify the "Edge Cases" by their facial ticks, occasional psychosis and their desire to work for the Post Office or TSA.


The "Agilist"
Some programmers get smart, and decide to minimize the cases of the Big Bad Merge by developing a a "checkin early, checkin often" attitude[2]. Thinking - correctly - that if they track the latest version on the server and make small, incremental changes, they're never so out of sync that they have a really horrible merge.

Ultimately, anybody on a team who uses this style of development is rewarded with few conflicts that are kept small and manageable. This means those developers get an added bonus: they implicitly punish their Lazy, Annoying Coworker[3] by making them deal with the big bad merges.

The problem with this solution is that eventually your Lazy, Annoying Coworker is going to catch on and adopt this solution for himself[4]. There are few things worse than a programmer who's simultaneously lazy and annoying and checks in quickly. Soon the Lazy Annoying Coworker will be checking in before they bother to test what they just wrote - or worse, even bother to compile it. Suddenly builds fail due to missing quotes and poor use of semicolons.[5]


So what's a software hack to do? How does one cope with this constant unknown?

One makes it a known problem -- one gets better tools.

One uses the Eclipse Synchronize View, which I'll demonstrate in my next post.

  1. Shameless plug: SourceGear's excellent DiffMerge 3.0 will be available very soon.
  2. (I'm not entirely sure, but I suspect that the entire "Agile Methodology" sprung from a really long day of merging branches with CVS.)
  3. Not having a Lazy, Annoying Coworker is much like playing poker without a chump. As Amarillo Slim said: "Look around the table. If you don't see a sucker, get up, because you're the sucker."[6]
  4. Or start cleaning his handguns at work.
  5. (Being Lazy and Annoying, when you confront your Coworker with this, they'll merely shrug and make you deal with it yourself.)
  6. As I've mentioned previously, my coworkers are neither Lazy nor Annoying. I'm sure that you realize what this says about me.
Edward Thomson is a Software Engineer at Teamprise, where he develops cross-platform client solutions for Microsoft Team Foundation Server, with an emphasis on Macintosh compatibility and IDE integration.