Tuesday, June 21, 2011

plugin.properties fails to replace referenced key string

If this happens make sure Bundle-Localization: plugin is in Manifest.mf

Thursday, April 21, 2011

The simplest possible Buckminster example

While at EclipseCon 2011 Miles Parker and I decided to conduct our own Buckminster BoF. Yes, this year's conference was all about Maven/Tycho builds, but we though that Buckminster had its own advantages that people might find beneficial to them.

For the BoF I created a very simple Buckminster build that build a very simple RCP application, in fact the RCP is so simple that it's just a window. The point of this is just to show a bare bone Buckminster build and give user instant gratification in actually building something quick. In fact, this bare bone build can be used for more complicated project because the beauty of Buckminster is that it does not need any more information that you already have - features and plugins.

If you are just starting out with Buckminster checkout Ralf Ebert's article as a starting point, get familiar with Bucky Book and of course visit Buckminster forum as it has vast amount of information that other people and myself were faced while working with Buckminster.

Grab Buckminster example here

Also, here are notes about Buckminster that were generated while implementing it for our build, hopefully these will be useful to someone.

Friday, October 15, 2010

Power of Buckminster's advisor nodes

Yesterday while working on updating GMF plugins with new model I had some changes in my workspace that produced compilation errors. I did not have time to fix the errors by the end of the day but with the changes I had, I did not want to leave them in my workspace without checking them into SVN. You know what they say "If it's not in version control, it does not exist." However, checking in these changes into SVN would mean that the build would break. Yes, I could have re-branches the changes, but did not have time for that either. What's the solution? Buckminster's advisor nodes! Here is what I did in my cquery:















I added three advisor nodes that set revision to last good revision of the plugins. That's it. During materialization three plugins with revision 63870 will be checked out and although latest revision has compilation errors, build will still work.

Friday, July 16, 2010

buckminster, svn provider and svn+ssh protocol

I've been struggling to make use of svn provider using svn+ssh protocol. After I setup ssh keys I would get errors such as:

ERROR [0000] : No suitable provider for component com.iwaysoftware.core.services:osgi.bundle was found in searchPath resources
ERROR [0000] : Rejecting provider svn({0}/dependencies/trunk/{1}): No component match was found
ERROR org.tigris.subversion.svnclientadapter.SVNClientException: org.tigris.subversion.javahl.ClientException: svn: Handshake failed, received: ''
ERROR [0000] : Rejecting provider svn({0}/iIT/trunk/features/{1}): No component match was found
ERROR org.tigris.subversion.svnclientadapter.SVNClientException: org.tigris.subversion.javahl.ClientException: svn: Handshake failed, received: ''

Fortunately I went to #eclipse-b3 on IRC and by luck jbarkanic was there who had the very same problem. With his help I was able to make this work by adding two lines in Hudson's Buckminster command section:

setpref org.eclipse.buckminster.core.maxParallelMaterializations=1
setpref org.eclipse.buckminster.core.maxParallelResolutions=1

It seems Buckminster does not work well in multi-threaded mode in some configurations, so forcing operation into single-threaded mode fixes the issue.

Thursday, June 10, 2010

Leveraging org.eclipse.ui.intro.samples extension point

Eclipse provides excellent samples framework that is part of 'Welcome' experience, unfortunately docs in the extension point state that This extension point is currently provided for internal Eclipse SDK usage only. It should not be used for anything else except Eclipse SDK examples. What this means is that:
  • Projects are downloaded from eclipse.org so you can't easily define alternate location of the zip files
  • The whole UI revolves around assumption that your project is an Eclipse plug-in or a project that contains some kind of code
Fortunately there is a way to manipulate all these features for your own needs.

Define location
As I stated above default url location for samples locations is eclipse.org which is defined as ShowSampleAction.UPDATE_SITE in org.eclipse.pde.internal.ui.samples. ShowSampleAction class is responsible for downloading zip file that is associated with the sample entry. All that is needed to make downloading sample from you own repository is to copy and modify ShowSampleAction with your own definitions of feature id, feature version and update site. All these constants are defined at the top of the class.

public class ShowSampleAction extends Action implements IIntroAction {
private static final String SAMPLE_FEATURE_ID = "org.eclipse.sdk.samples"; //$NON-NLS-1$
private static final String SAMPLE_FEATURE_VERSION = "3.3.0"; //$NON-NLS-1$
private static final String UPDATE_SITE = "http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/pde-ui-home/samples/"; //$NON-NLS-1$


Customize download message
In addition you might want to change the message that appears in the dialog when user clicks on the sample link. This is done in ShowSampleAction.ensureSampleFeaturePresent() method


private boolean ensureSampleFeaturePresent() {
if (checkFeature())
return true;
// the feature is not present - ask to download
if (MessageDialog.openQuestion(PDEPlugin.getActiveWorkbenchShell(), PDEUIMessages.ShowSampleAction_msgTitle, PDEUIMessages.ShowSampleAction_msgDesc)) {
return downloadFeature();
}
return false;
}


Plugin' it in
So now that we have our custom action defined how do we tell framework about it? When defining your samples in org.eclipse.ui.intro extension point the xml file that creates samples configExtension is the place we are interested in. I am not going to go into detail of how to implement the extension point here as this is covered vastly elsewhere. So here are the contents of my samples xml file:






description







The part we are interested in is the url attribute of the link element, this is where our custom action is defined:


url="http://org.eclipse.ui.intro/runAction?pluginId=com.iwaysoftware.integration.tools.samples&class=com.iwaysoftware.integration.tools.samples.actions.ShowSampleAction&id=com.iwaysoftware.samples.scifi"


Notice definition of the pluginId and class, this is what makes your custom action execute when link in the samples page is clicked.

This takes care of downloading and importing the project part.

Tweaking UI
After project is imported into your workspace from samples page there are number of things that can happen in the framework which is controlled in the IntroURL.doExecute() method: a welcome view can be closed, browser opened or another action ran. Set a break point in the method and interact with samples page to see what happens. By default IntroURL.SHOW_STANDBY is executed, but how and who controls what action is executed? Why it's our friend ShowSampleAction! Take a look at ShowSampleAction.switchToSampleStandby() method.

private void switchToSampleStandby(SampleWizard wizard) {
StringBuffer url = new StringBuffer();
url.append("http://org.eclipse.ui.intro/showStandby?"); //$NON-NLS-1$
url.append("pluginId=com.iwaysoftware.integration.tools.samples"); //$NON-NLS-1$
url.append("&"); //$NON-NLS-1$
url.append("partId=com.iwaysoftware.samples.SamplesStandbyPart"); //$NON-NLS-1$
url.append("&"); //$NON-NLS-1$
url.append("input="); //$NON-NLS-1$
url.append(sampleId);
IIntroURL introURL = IntroURLFactory.createIntroURL(url.toString());
if (introURL != null) {
introURL.execute();
ensureProperContext(wizard);
}
}


This is where url is constructed and passed to IntroURL. So if you change http://org.eclipse.ui.intro/showStandby to http://org.eclipse.ui.intro/close after sample is imported no welcome view will be docked to the left of your Eclipse instance. As I mentioned you can explore all available actions in IntroURL class.

So why is this important? Because samples extension point pre-wired to work with java projects, which might not be the case as it is in our product. Our product is a collection of xml files that are manipulated by user via GEF editors. So when a project is imported into workspace a java-project-centric welcome view appears that is not necessarily what you want to happen in your case because there is no source to browser for example. One obvious thing you can do is to call close action in the ShowSampleAction and be done with it, but you can also customize the view for your own needs.

Customizing the view
The content of the welcome view page are loaded from a class that implements IStandbyContentPart, particularly org.eclipse.pde.internal.ui.samples.SampleStandbyContent. The content of the page is defined in the createPartControl() method which could be as simple as name and description of the sample or as complicated as launching run shortcut with predefined parameters. What is nice here is you are in total control of what happens in the view.
Once you define the view, how do you integrate your changes into the framework? It took some debugging time to find the answer - org.eclipse.ui.internal.intro.impl.parts.StandbyPart.showContentPart() is the place, specifically


IntroStandbyContentPart standbyPartContent = ExtensionPointManager
.getInst().getSharedConfigExtensionsManager()
.getStandbyPart(partId);


this is the extension point from which implementer of IStandbyContentPart is loaded


String standbyContentClassName = standbyPartContent.getClassName();
String pluginId = standbyPartContent.getPluginId();

Object standbyContentObject = ModelLoaderUtil.createClassInstance(
pluginId, standbyContentClassName);


And the place where magic happens is in extension point world, where sample defining xml is set:


point="org.eclipse.ui.intro.configExtension">
configId="org.eclipse.ui.intro.universalConfig"
content="intro/samplesExtensionContent.xml">

id="com.iwaysoftware.samples.SamplesStandbyPart"
class="com.iwaysoftware.integration.tools.samples.content.SamplesStandbyContent"
pluginId="com.iwaysoftware.integration.tools.samples"/>



As you can see our custom SamplesStandbyContent is defined and will be loaded by the extension point mechanism when it's time to display the view.

Disclaimer :)
Any or all information mentioned above could become useless since samples extension point and its supporting classes are internal, so if something changes there this can tumble like a house of cards, I hope it will not. Fingers crossed.

Thursday, November 12, 2009

Eclipse SVN merge



When merging branch to trunk follow these steps:
  • Commit all branch changes to svn
  • Checkout trunk to workspace
  • Right-click on trunk project in workspace: Team -> Merge
  • In from url select branch to be merged to trunk
  • In to url check 'Use "From:" URL'
  • In from revision choose last revision to get from branch. Think about it, you want revision that has all the changes that were done since last merge to trunk
  • Click Merge
  • If there are any conflicts, they will show up in project file tree, resolve them by: Team -> Edit Conflicts... on the file in question.
  • Once conflicts are resolved, Team -> Marked Resolved... on the file.
  • After all conflicts are resolved, and everything works, commit!

Wednesday, October 28, 2009

SVN Hooks

I am working on a project where I need directory of my cakePHP application on the server update on each svn commit. Why? Because I am lazy. I don't want to login to remote server every time I commit something, run svn update...or worse ftp. So I've been reading about svn hooks, and it's a very powerful thing.

These are the steps to make it work:



  • Create and compile c program that will perform svn update, and save it somewhere let's say in /svn/autoupdate


    #include
    #include
    #include
    int main(void)
    {
    execl("/usr/local/bin/svn", "svn", "update",
    "${dirNameToUpdate}",
    (const char *) NULL);
    return(EXIT_FAILURE);
    }



  • Add post-commit to svnrepo/hooks where compiled c program is referenced:

    #!/bin/sh
    /svn/autoupdate/autoupdate


  • chmod +x post-commit


Try to commit something to svn on remote server and watch svn hooks magic in action.

Blogger Syntax Highliter