tag:blogger.com,1999:blog-250955192024-03-13T17:09:41.572-05:00Andrew NieferOne more Eclipse developer.Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.comBlogger33125tag:blogger.com,1999:blog-25095519.post-16296039218624508192013-05-06T09:48:00.001-05:002013-05-06T09:48:56.503-05:00Quick Tip: Naming Eclipse WorkspacesI often have multiple eclipse workspaces open. Windows 7 stacks them nicely for me, but this presents a problem: it is difficult to distinguish between them when switching between the applications. The path of the currently open file in each instance is visible, but that is not always enough information.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikdo6qtz6PRe5Akvvb1UBhpbjr841I_lSRPssctqE_HolhyphenhyphenJOeAdfxa2tnUzKILf8BhrPhXwbXftY8cHpMXUcIIPF5F-XStZD9Uw-1CRIcXW9OAGOHALl3kW7NdZ3GGjv9g-o8pQ/s1600/taskbar1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikdo6qtz6PRe5Akvvb1UBhpbjr841I_lSRPssctqE_HolhyphenhyphenJOeAdfxa2tnUzKILf8BhrPhXwbXftY8cHpMXUcIIPF5F-XStZD9Uw-1CRIcXW9OAGOHALl3kW7NdZ3GGjv9g-o8pQ/s1600/taskbar1.jpg" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
I've always used the <tt>-showLocation</tt> command line option which appends the location of the workspace to the end of the title. Unfortunately, most of the time the title is too long for the workspace location to show up when switching between applications.<br />
<br />
Today I decided to go hunting through the Eclipse preferences and I found exactly what I was looking for: <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEic-ZyZmet9Tz5dVbcZEwgNfCC35wGsSIzy18IVwaz13VK4YwfFn-kO8OpfFxSs0xXFueWgWvpsqGZY5RcL5SgtXXrFmwxHxp8EhbyI8f19_C1Ly6RIv94ZUmw5nMIJwgUnhXLD5A/s1600/preferences.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="281" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEic-ZyZmet9Tz5dVbcZEwgNfCC35wGsSIzy18IVwaz13VK4YwfFn-kO8OpfFxSs0xXFueWgWvpsqGZY5RcL5SgtXXrFmwxHxp8EhbyI8f19_C1Ly6RIv94ZUmw5nMIJwgUnhXLD5A/s320/preferences.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Naming Eclipse Workspaces</td></tr>
</tbody></table>
<br />
After setting names for all my workspaces, their titles are now useful:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrgJU0DmaQ9qW0Wh9vhut0dTYSpYgtQ8uN0esbY9voanZvudaOH8nHjnkAj-YLJ7qE1ESLz_LAtWVz7ViBfQlwgK-q1NIFclKvR-k3KYdlHw8UleuxRNTrHwd9HZwqy8OqysG17A/s1600/taskbar2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrgJU0DmaQ9qW0Wh9vhut0dTYSpYgtQ8uN0esbY9voanZvudaOH8nHjnkAj-YLJ7qE1ESLz_LAtWVz7ViBfQlwgK-q1NIFclKvR-k3KYdlHw8UleuxRNTrHwd9HZwqy8OqysG17A/s1600/taskbar2.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com2tag:blogger.com,1999:blog-25095519.post-6271327698339881622011-02-02T16:10:00.008-05:002012-01-03T16:10:41.519-05:00Embedding the Orion Editor<p>[<b>Edit Jan 3, 2012</b>: Orion has evolved significantly since this post was first written a year ago. Please see <a href="http://orioneditor.blogspot.com/2012/01/using-orion-editor-with-almond.html" target="_blank">this post</a> written by Felipe for an update.]<p/>
Yesterday I wrote a <a href="http://aniefer.blogspot.com/2011/02/overriding-pdebuild-with-ant-import.html">blog post</a> which contains a few snippets of Ant code. If you have java-script enabled, those snippets should be nicely formatted with line numbers and some basic syntax highlighting.<br />
<br />
Those code snippets are actually being shown using the <a href="http://wiki.eclipse.org/Orion">Orion</a> Editor embedded into my blog post. Granted, using the full editor here is a little over-kill since we aren't doing very much with it, but this was an interesting exercise.<br />
<br />
Here is the javascript I wrote to do this:<br />
<div>
<pre name="orion">/*******************************************************************************
* Copyright (c) 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
function findOrionElements(tagName){
var elements = [];
var tags=document.getElementsByTagName(tagName);
for(var i=0;i<tags.length;i++) {
if(tags[i].getAttribute('name')==='orion') {
elements.push(tags[i]);
}
}
return elements;
}
function createEditors() {
//find all pre elements named 'orion'
var elements = findOrionElements('pre');
for(var i=0; i < elements.length; i++) {
var element = elements[i];
//extract the text from inside the pre
var text = "";
for( var j=0; j < element.childNodes.length; j++ ) {
var nodeName = element.childNodes[j].nodeName;
if (nodeName === "#text")
text += element.childNodes[j].nodeValue;
else if (nodeName === "BR" )
text += '\n';
}
/* Create the editor:
- parent is the containing div element
- readonly by default, but can specify class="writable"
- use the given stylesheet */
var parentNode = element.parentNode;
var elementClass = element.getAttribute('class');
var editor = new eclipse.Editor({
parent: parentNode,
readonly: !(elementClass && elementClass.indexOf('writable') > -1),
stylesheet: "http://download.eclipse.org/e4/orion/js/org.eclipse.orion.client.editor/editor.css"
});
// use javascript styler for now, there is no html/xml syntax highlighting yet
var styler = new eclipse.TextStyler(editor, "js");
// add a ruler with line numbers to the left side
var lines = new eclipse.LineNumberRuler("left", {styleClass: "ruler_lines"}, {styleClass: "ruler_lines_odd"}, {styleClass: "ruler_lines_even"});
editor.setText(text);
editor.addRuler(lines);
//fix the height of the containing div
parentNode.style.height = (editor.getLineHeight() * (editor.getModel().getLineCount() + 1)) + 2 + 'px';
}
}</pre>
</div>
<br />
<br />
This code is looking for all <tt><b><pre name='orion'></b></tt> elements and creating editors to replace them. These elements should generally be contained inside a <div> element. HTML for a replaceable section would look like this:<br />
<br />
<div>
<pre class="writable" name="orion"><div><pre name="orion" class="writable">
var hello = "Hello World!";
alert(hello);
</pre></div></pre>
</div>
<br />
This example above was made writable by adding "<tt>class='writable'</tt>" to the <pre/> element. Inside the <pre> element, all <tt>'<'</tt> should be escaped as <tt>'&lt;'</tt> and all <tt>'>'</tt> as <tt>'&gt;'</tt>.<br />
<br />
As a final step, to get this working on blogger.com, I combined my javascript together with:<br />
<pre><a href="http://git.eclipse.org/c/e4/org.eclipse.orion.client.git/tree/bundles/org.eclipse.orion.client.editor/web/js/editor.js">org.eclipse.orion.client.editor/web/js/editor.js</a>
<a href="http://git.eclipse.org/c/e4/org.eclipse.orion.client.git/tree/bundles/org.eclipse.orion.client.editor/web/js/model.js">org.eclipse.orion.client.editor/web/js/model.js</a>
<a href="http://git.eclipse.org/c/e4/org.eclipse.orion.client.git/tree/bundles/org.eclipse.orion.client.editor/web/samples/rulers.js">org.eclipse.orion.client.editor/web/samples/rulers.js</a>
<a href="http://git.eclipse.org/c/e4/org.eclipse.orion.client.git/tree/bundles/org.eclipse.orion.client.editor/web/samples/styler.js">org.eclipse.orion.client.editor/web/samples/styler.js</a></pre>
and minified it all using the <a href="http://code.google.com/closure/compiler/">Google Closure compiler</a>. I hosted the resulting .js file on download.eclipse.org and added the following lines to the bottom of my blog post:<br />
<br />
<div>
<pre name="orion"><script type="text/javascript" src="http://download.eclipse.org/e4/orion/js/org.eclipse.orion.client.editor/orion-editor.js"></script>
<script type="text/javascript">document.onload=createEditors();</script></pre>
</div>
<br />
<br />
If someone visits the post without javascript enabled, then they don't get the nice formatting on the code snippets, but at least they are still inside <pre> elements which give them some basic formatting.<br />
<br />
<script src="http://download.eclipse.org/e4/orion/js/org.eclipse.orion.client.editor/orion-editor.js" type="text/javascript">
</script><br />
<script type="text/javascript">
document.onload=createEditors();
</script>Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com7tag:blogger.com,1999:blog-25095519.post-87498823662689882712011-02-01T13:49:00.008-05:002011-02-02T16:01:17.859-05:00Overriding PDE/Build with the Ant Import taskPDE/Build has a number of places where you can run <a href="http://help.eclipse.org/topic//org.eclipse.pde.doc.user/tasks/pde_customization.htm">custom ant scripts</a> during the build.<br /><br />The general pattern is the you would copy one of the customization templates from org.eclipse.pde.build/templates/headless-build into your builder directory and then modify the file as required. For simple builds it is often unnecessary to copy these files at all and PDE/Build will just use its original copy.<br /><br />If you only have a small change to make to the customization scripts, then it can be cleaner to not copy the template file and instead use <a href="http://ant.apache.org/manual/Tasks/import.html">Ant's Import task</a>.<br /><br /><h3>Using Import to make minor changes</h3>The ant Import task allows for overriding a target from the imported file. As an example, the Eclipse SDK includes the Build Id in its about box. The About Box contents come from "about.mappings" files inside plug-ins.<br /><br />What we want to do is after getting all our source from CVS, we do a quick replace in all the about.mappings files to update them with the build id.<br /><br />Instead of copying the customTargets.xml file into our builder, we create our own that contains just the following:<br /><tt><b>builder/customTargets.xml</b></tt>:<div name="orion"><pre name="orion"><project name="customTargets overrides" ><br /> <import file="${eclipse.pdebuild.templates}/headless-build/customTargets.xml"/><br /> <br /> <target name="postFetch"><br /> <replace dir="${buildDirectory}/plugins" value="${buildLabel}" token="@build@"><br /> <include name="**/about.mappings" /><br /> </replace><br /> </target><br /></project><br /></pre></div><br /><tt>${eclipse.pdebuild.templates}</tt> is a property that is automatically set by PDE/Build and it points the folder containing the template files. This small snippet is much cleaner than copying the entire customTargets.xml just to add a few lines.<br /><br />This pattern can make for smaller and neater build scripts, but it turns out that this can also be a very powerful tool for modifying PDE/Build's behaviour.<br /><br /><h3>Here is the Magic</h3><br />During <a href="http://download.eclipse.org/e4/orion/drops/S-0.2M5-201101311515/index.html">M5</a> milestone week, the <a href="http://wiki.eclipse.org/Orion">Orion</a> builds began <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=335723">failing</a> about 90% of the time. The failure was "Unable to delete directory" in the middle of packaging ant scripts that are generated by PDE/Build. This seems to have been caused by an <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=335274#c8">overloaded/lagged NFS server</a> (or disk array).<br /><br />When building a product for multiple platforms with p2, PDE/Build installs the product into a temporary directory, zips it up, deletes that directory, and then repeats for the next platform using the same temporary directory. If there is a problem deleting the directory then we are in trouble because even if we could ignore the problem, the next platform will be contaminated with contents from the previous one.<br /><br />In order to work around the problem, we need to modify a target named <tt>cleanup.assembly</tt> which simply performs an ant <tt><delete/></tt> on the temporary directory. The problem is, that this target is in the middle of the PDE/Build generated configuration specific packaging scripts. A deeper understanding of how these scripts work is required.<br /><br /><h2>Package Script Overview</h2><br />When running a product build, the generated package scripts are organized per platform that we are building for. As an example, if we are building for windows, mac and linux, then we would have the following scripts:<br /><div><pre>package.org.eclipse.pde.build.container.feature.all.xml<br />package.org.eclipse.pde.build.container.feature.linux.gtk.x86.xml<br />package.org.eclipse.pde.build.container.feature.macosx.cocoa.x86.xml<br />package.org.eclipse.pde.build.container.feature.win32.win32.x86.xml<br /></pre></div>The "<tt>org.eclipse.pde.build.container</tt>" portion of the file name comes from this being a product build. In a feature build this would be the name of the top level feature being built. The first (*.all.xml) script is the main entry point for the packaging process. Each of the other scripts do the packaging for each platform. Every one of those platform specific scripts contain a <tt>cleanup.assembly</tt> target that needs to be modified.<br /><br /><h2>Script Delegation</h2>The top level packaging scripts does not call all the others directly, rather it uses a kind of delegation through the <tt><a href="http://help.eclipse.org/topic//org.eclipse.pde.doc.user/tasks/pde_customization.htm">allElements.xml</a></tt> file. This file can be copied to your builder and modified to change the archive name or perform pre or post processing on the archive.<br /><br />For each platform, the top level packaging script will call <tt><b>allElements.xml/defaultAssemble</b></tt> (or a platform specific <tt>assemble.*.[config]</tt> target if one is defined) passing it the name of the platform specific packaging script to invoke.<br /><br />This is where we can insert our change in order to override the platform specific packaging scripts.<br /><br /><h2>The Modified allElements.xml file</h2>We copy the allElements.xml file from org.eclipse.pde.build/templates/headless-build/allElements.xml into our builder and change the "defaultAssemble" target to look like this:<br /><div name="orion" ><pre name="orion"><target name="defaultAssemble"><br /> <ant antfile="${builder}/packageOverride.xml" dir="${buildDirectory}"><br /> <property name="assembleScriptName" value="${assembleScriptName}" /><br /> <property name="archiveName" value="${archiveNamePrefix}-${config}.zip"/><br /> </ant><br /></target><br /></pre></div><br />The name of the platform specific packaging script is specified by the <tt><b>${assembleScriptName}</b></tt> property. Instead of calling this directly, we instead call a script of our own "packageOverride.xml" and pass it the script name. Product builds normally use their own allElements.xml provided by PDE/Build which also sets the archive name based on the configuration being built. Since we will be using our own allElements.xml file, we also set the archive name here.<br /><br />Product Builds (using org.eclipse.pde.build/scripts/productBuild/productBuild.xml) are hardcoded to use their own copy of the allElements.xml file. In order to change this we must set a property <tt>allElementsFile</tt> which points to our copy. This property must be set <b>before invoking productBuild.xml</b>, which means setting it on the command line, or in a wrapping ant script. This is not necessary when doing a feature build.<br /><br /><h2>The new packageOverride.xml script</h2>The allElements.xml delegation script has now been modified to invoke our own packageOverride.xml script. Our script looks something like this:<br /><tt><b>packageOverride.xml</b></tt>:<br /><div name="orion"><pre name="orion"><project name="package.override" default="main" ><br /> <import file="${buildDirectory}/${assembleScriptName}" /><br /><br /> <target name="cleanup.assembly"><br /> <condition property="doAssemblyCleanup" ><br /> <or><br /> <not><isset property="runPackager" /></not><br /> <contains string="${assembleScriptName}" substring="package." /><br /> </or><br /> </condition><br /> <antcall target="perform.cleanup.assembly" /><br /> </target><br /> <target name="perform.cleanup.assembly" if="doAssemblyCleanup" ><br /> <exec executable="mv" dir="${buildDirectory}" ><br /> <arg value="${assemblyTempDir}" /><br /> <arg value="${buildDirectory}/tmp.${os}.${ws}.${arch}" /><br /> </exec><br /> <exec executable="rm" dir="${buildDirectory}" ><br /> <arg line="-rf ${buildDirectory}/tmp.${os}.${ws}.${arch}" /><br /> </exec><br /> </target> <br /></project><br /></pre></div><br /><br />Here, we import the package script that was passed to us from allElements.xml, each time the packaging script calls us, we will be importing a different script. We inherit all the generated targets and override the <tt>cleanup.assembly</tt> target. Our modified version moves the temporary folder to a different location before trying to delete it. If the delete fails, that is ok because it is no longer in the way of the next platform. I used the native 'mv' and 'rm' hoping that they would behave better with a slow NFS server.<br /><br />The packageOverride.xml script must specify <tt>default="main"</tt> as that setting is not inherited.<br /><br />It is important to note that this override also affects the generated <tt>assemble.*</tt> scripts which are very similar to the package scripts. The assemble scripts also have an <tt>cleanup.assembly</tt> target which is getting overridden here. However, that target is only supposed to run during assembly if we are not going to be doing packaging. This is why we need a condition here to make sure the temporary folder is only deleted when it should be. The condition I used here would be wrong for feature builds where the top level feature name contains "package." because the generated scripts in a feature build contain the top level feature id.<br /><br /><h3>Final Notes</h3><br />The change I have outlined here mas made to fix a specific problem with the Orion build. Care must be taken when applying these techniques to other problems and builders.<br /><br />The exact details here have been modified from the changes I actually made, so I have not actually tested the scripts as they are written above. Specifically, the condition on the overridden target has been added.<br /><br />This specific problem can also be fixed in pde.build itself, this is tracked by <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336020">bug 336020</a>.<br /><br /><script type="text/javascript" src="http://download.eclipse.org/e4/orion/js/org.eclipse.orion.client.editor/orion-editor.js"></script><br /><script type="text/javascript">document.onload=createEditors();</script>Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com0tag:blogger.com,1999:blog-25095519.post-80917999705464419212011-01-27T14:43:00.007-05:002012-12-07T11:01:19.524-05:00Building from Git<a href="http://wiki.eclipse.org/Git">Git</a> was introduced at Eclipse about a year ago. Projects are slowly migrating over to use git as the SCM system instead of CVS or SVN. When IBM made its initial contribution for the new <a href="http://wiki.eclipse.org/Orion">Orion</a> project, we migrated from internal CVS servers to <a href="http://dev.eclipse.org/git/index.html">git at eclipse.org</a>. This post will give an overview of the changes I had to make to our releng setup to start building from git.<br />
<br />
There have been a few PDE/Build bug fixes in 3.7 to support building from Git. <b>I recommend using a <a href="http://download.eclipse.org/eclipse/downloads/">recent 3.7 build</a> as your base builder</b>. 3.7M5 is due out this week.<br />
<h3>
General Setup</h3>
The Orion releng build is a relatively standard p2 enabled <a href="http://help.eclipse.org/topic//org.eclipse.pde.doc.user/tasks/pde_p2_builds.htm">PDE/Build product build</a>.<br />
<br />
There are a few things that need to be done to get the build working with git:<br />
<ol>
<li>Bootstrapping the builder</li>
<li>Getting map files</li>
<li>Fetching source from Git</li>
</ol>
The e4 builds consume source code from git repositories, but the releng project and map files are still in CVS. Only the 3rd step here was required for e4. The entire Orion project including releng project and mapfiles is in git so we need all three.<br />
<h3>
Bootstrapping the Build</h3>
The Orion releng builds run via cron job on build.eclipse.org. We need a small shell script that can get the Orion releng project from git and start everything off. We do this using the <a href="http://www.kernel.org/pub/software/scm/git/docs/v1.7.3.5/git-archive.html">git archive</a> command:<br />
<pre>git archive --format=tar --remote=/gitroot/e4/org.eclipse.orion.server.git master
releng/org.eclipse.orion.releng | tar -xf -</pre>
The build machine has local access to the git repository, if we were running from somewhere else, this would change to something like <tt>--remote=ssh://user@dev.eclipse.org/gitroot/...</tt><br />
<br />
This will get the releng project into the current working directory, at which point we can invoke ant on it.<br />
<h3>
Getting map files from Git</h3>
PDE/Build uses <a href="http://help.eclipse.org/topic//org.eclipse.pde.doc.user/tasks/pde_fetch_phase.htm">map files</a> to fetch our code from source repositories. The first step to this is getting the map files themselves.<br />
<br />
PDE/Build comes with default support to fetch map files from CVS which is controlled by a few properties (see <a href="http://help.eclipse.org/topic//org.eclipse.pde.doc.user/reference/pde_builder_config.htm#fetchControl">Fetch phase Control</a>). This obviously doesn't apply here. However, this step is fully <a href="http://help.eclipse.org/topic//org.eclipse.pde.doc.user/tasks/pde_customization.htm">customizable</a> using the <b>customTargets.xml</b> file.<br />
<br />
All we need to do is copy the org.eclipse.pde.build/templates/headless-build/customTargets.xml file into our builder and modify the <b>getMapFiles</b> target. We can then use the git archive command to get our map files. It would look something like this:<br />
<pre><target name="getMapFiles" unless="skipMaps">
<mkdir dir="${buildDirectory}/maps" />
<exec executable="git" dir="${buildDirectory}/maps"
<b>output="${buildDirectory}/maps/maps.tar"</b>>
<arg line="archive -format=tar" />
<arg line="--remote=/gitroot/e4/org.eclipse.orion.server.git" />
<arg line="master releng/org.eclipse.orion.releng/maps" />
</exec>
<untar src="${buildDirectory}/maps/maps.tar" dest="${buildDirectory}/maps" />
</target></pre>
Because the "<tt>| tar -xf -</tt>" we used earlier is a redirection done by the shell, that doesn't work when we invoke git from ant. Here we specify a file to hold the output of the archive command, this ends up being a tar file which we can just untar.<br />
<br />
<h3>
Fetching source from Git</h3>
PDE/Build has an extension point where fetch script generators for different repositories can be plugged in. The <a href="http://eclipse.org/egit/">EGit</a> project provides an <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=289838">implementation</a> for this extension point.<br />
The org.eclipse.egit.fetchfactory bundle is available from the <b>http://download.eclipse.org/egit/pde/updates-nightly</b> p2 repository. Install that bundle into the eclipse install that is used to run your build.<br />
<br />
<h2>
Git Map Files</h2>
Once we have the egit fetchfactory, all we need to do is update our map files with entries for GIT. Here is an example map file entry from Orion:<br />
<pre>plugin@org.eclipse.orion.client.core=GIT,tag=v20110125-1800,\
repo=dev.eclipse.org:/gitroot/e4/org.eclipse.orion.client.git,\
path=bundles/org.eclipse.orion.client.core</pre>
<ul>
<li><b>tag</b> is the tag to use when fetching the bundle from git</li>
<li><b>repo</b> is the path to the git repository. In order to omit the user from the repository path, the build needs to run as a user who has ssh access to the git repo at dev.eclipse.org</li>
<li><b>path</b> is the path within the git repository to the project we are interested in.</li>
</ul>
<h3>
Final Details</h3>
<ul>
<li>The EGit fetch factory works by cloning the git repository to a local directory, checking out the tag and then copying the project over to the build Directory. Builders can set the <b><tt>fetchCacheLocation</tt></b> property to specify a local directory where the git clones can be kept. This location may be reused from build to build to avoid having to re-download the entire repository each build.</li>
<li>"Nightly" builds are set up to build the latest code from HEAD. For CVS, this is usually accomplished by setting "<tt>fetchTag=HEAD</tt>" to override the map file entries. For Git you would use "<tt>fetchTag=origin/master</tt>". If you are using both CVS and GIT you can set both with <b>"<tt>fetchTag=CVS=HEAD,GIT=origin/master</tt>"</b>.</li>
<li>The Eclipse Platform team uses the <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-releng-home/dev.html?rev=HEAD&content-type=text/html">releng tool plugin</a> to manage their map files in CVS, there is not yet an <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328745">equivalent tool</a> for git. See the <a href="http://wiki.eclipse.org/Orion/Releng_Builds">Orion Releng</a> and <a href="http://wiki.eclipse.org/E4/Git">E4/Git</a> wiki pages for instruction on how to manage map files.</li>
</ul>
Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com5tag:blogger.com,1999:blog-25095519.post-48839048294864838712011-01-20T14:48:00.005-05:002011-01-20T16:35:27.283-05:00Releng tricks from e4 and OrionIn the last couple of months I've found myself in charge of two releng builds: e4 and <a href="http://wiki.eclipse.org/Orion">Orion</a>. The e4 build is actually 2 pieces: building the Eclipse 4.1 SDK and building additional e4 bundles which are not part of the SDK by default.<br /><br />Being the PDE/Build project lead gives me a unique perspective on this entire process so I thought I would share some tip and tricks for specific problems I encountered.<br /><br />The first covers how we do signing when building the Eclipse 4.1 SDK.<br /><h2>Signing the Eclipse 4.1 SDK</h2>We produce <a href="http://wiki.eclipse.org/JAR_Signing">signed bundles</a> in our builds. The specifics of how to do this have already been <a href="http://wiki.eclipse.org/Platform-releng-signedbuild">worked out</a> by <a href="http://relengofthenerds.blogspot.com/">Kim</a>. Essentially we provide a zip file that gets sent off to eclipse.org to be signed.<br /><br />For the 4.1 SDK there is a slight twist to the problem. The 4.1 SDK is mostly composed of binary bundles we reconsume from 3.7 together with some new e4 bundles that we compile ourselves. We really only want to sign the bundles that we compiled ourselves and avoid resigning the binary bundles.<br /><br />The trick for creating an archive containing only the bundles we compiled works best for <a href="http://help.eclipse.org/topic//org.eclipse.pde.doc.user/tasks/pde_p2_builds.htm">p2 enabled</a> builds (using <tt>p2.gathering=true</tt>).<br /><br /><h3>Custom Assembly Targets</h3>PDE/Build supports <a href="http://help.eclipse.org/topic//org.eclipse.pde.doc.user/tasks/pde_customization.htm">customization</a> of your build using provided template files. In particular we are interested in the <b>customAssembly.xml</b> script. This provides targets that will be invoked by PDE/Build during the packaging and assembly phases of the build.<br /><br />Specifically, there is a target <tt><b>gather.bin.parts</b></tt> which is invoked for every bundle that we are building immediately after the contents for that bundle are published into the p2 repository. There is another target <tt><b>post.gather.bin.parts</b></tt> which is called after we are finished with all the bundles.<br /><br />The idea is that we use the <tt>gather.bin.parts</tt> target to record which bundles we compiled, and the post.gather.bin.parts to sign these bundles and update the p2 repository. At the time post.gather.bin.parts is called, the p2 repository will contain binary bundles as well as the compiled ones which is why we need a record of which ones to sign.<br /><br />The script looks something like this:<br /><pre><br /><project name="CustomAssemble.overrides" default="noDefault"><br /><import file="${eclipse.pdebuild.templates}/headless-build/customAssembly.xml" /><br /><br /><!-- every time gather.bin.parts is called, we will record the project being built --><br /><target name="gather.bin.parts" ><br /> <echo append="true" file="${buildDirectory}/built.list"<br /> message="<b>**/${projectName}.jar${line.separator}</b>" /><br /></target><br /><br /><target name="post.gather.bin.parts" ><br /> <property name="signingArchive" value="${buildDirectory}/${buildLabel}/sign-${buildId}.zip" /><br /> <zip zipfile="${signingArchive}" basedir="${p2.build.repo}"<br /> <b>includesFile="${buildDirectory}/built.list"</b> /><br /><br /> <!-- sign! --><br /> <ant antfile="${builder}/sign.xml" dir="${basedir}" target="signMasterFeature" ><br /> <property name="signingArchive" value="${signingArchive}" /><br /> </ant><br /> <br /> <!--unzip signed archive over top of the repository --><br /> <unzip dest="${p2.build.repo}" src="${signingArchive}" /><br /><br /> <!--update repository with new checksums for signed bundles --><br /> <b><p2.process.artifacts repositoryPath="file://${p2.build.repo}" /></b><br /></target><br /></project><br /></pre>Some notes:<br /><ul><li><tt style="font-weight: bold;">${projectName}</tt> is a property set by PDE/Build and it contains the bundle symbolic name and the version of the bundle being built (ie org.eclipse.foo_1.0.0.v2011).</li><li>The bundles are recorded in <b>built.list</b> in the form of an ant include pattern.</li><li>The signing archive is created from the p2 repository using the generated built.list as an includes file.</li><li>The sign.xml script being used is the one from the e4 build and is available <a href="http://dev.eclipse.org/viewcvs/viewvc.cgi/e4/releng/org.eclipse.e4.builder/builder/general/sign.xml?view=co&content-type=text%2Fplain">here</a>.</li><li>The p2 artifact repository contains checksums for each artifact, so after extracting the signed archive over top of the repository, we need to update the repository to recalculate these checksums.</li><li>I have not actually tested the above ant snippet, it may require some tweaks. The general strategy is based on what we do in the e4 build but some of the details have changed.</li></ul>Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com4tag:blogger.com,1999:blog-25095519.post-21975550857771171672010-07-14T10:46:00.004-05:002010-07-14T12:08:01.783-05:00Permgen problems and Running Eclipse on Java 1.6 update 21People running Eclipse on windows using the latest Java 1.6 update 21 jvm from Oracle/Sun are <a href="http://www.eclipse.org/forums/index.php?t=msg&th=171585&start=0">noticing</a> frequent vm crashes or freezes:<br /><blockquote>Unhandled event loop exception<br />PermGen space</blockquote>As indicated in the <a href="http://wiki.eclipse.org/FAQ_How_do_I_run_Eclipse%3F">Eclipse FAQ</a>, there is a simple workaround for this problem, edit your eclipse.ini file and add <tt>-XX:MaxPermSize=256m</tt> below the -vmargs line:<br /><pre><blockquote>-startup<br />plugins/org.eclipse.equinox.launcher_1.1.0.v20100507.jar<br />--launcher.library<br />plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.0.v20100503<br />-product<br />org.eclipse.epp.package.jee.product<br />--launcher.defaultAction<br />openFile<br />-showsplash<br />org.eclipse.platform<br />--launcher.XXMaxPermSize<br />256m<br />--launcher.defaultAction<br />openFile<br />-vmargs<br /><span style="font-size:130%;"><b>-XX:MaxPermSize=256m</b></span><br />-Dosgi.requiredJavaVersion=1.5<br />-Xms40m<br />-Xmx512m</blockquote></pre><br /><h3>History and Explanations</h3>Starting as far back as <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=92250">Eclipse 3.1</a> it was noticed that Eclipse uses a lot of "PermGen" memory under Sun VMs. Permgen memory is where .class file information is stored. The way to avoid this memory problem is to increase the permgen size by using -XX:MaxPermSize. <br /><br />The problem is that this is a non-standard vm argument and can cause vms from other vendors to not start at all. We eventually <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=92250#c171">fixed</a> this by introducing a <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=186886">new argument</a> in the eclipse.ini file: <tt><b><a href="http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/misc/runtime-options.html">--launcher.XXMaxPermSize</a></b></tt>.<br /><br />When this argument is specified, the eclipse executable launcher tries to identify whether the vm is from Sun or not. If the vm is Sun, then the launcher adds the -XX:MaxPermSize vm argument. On windows, we identify Sun vms using the <a href="http://msdn.microsoft.com/en-us/library/ms647003%28VS.85%29.aspx">GetFileVersionInfo API</a>. We read the version information from the java executable (or jvm.dll) and check to see if the company name is "Sun Microsystems".<br /><br />This worked great and everyone was happy. Fast forward a few years and Oracle acquires Sun. Now starting in Java 6 update 21, the company name in the jre is Oracle. This means the launcher no longer recognizes the vm as being from Sun and the -XX:MaxPermSize vm argument no longer gets applied results once more in Permgen memory problems.<br /><br />The fix for this change is being tracked in <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=319514">bug 319514</a>.Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com5tag:blogger.com,1999:blog-25095519.post-53931172205218222282010-05-28T14:37:00.008-05:002010-05-31T16:04:45.854-05:00Opening files in Eclipse from the command lineI ran a <a href="https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced;bug_status=RESOLVED;bug_status=VERIFIED;bug_status=CLOSED;classification=Eclipse;classification=RT;product=Equinox;product=JDT;product=PDE;product=Platform;target_milestone=3.6;target_milestone=3.6%20M1;target_milestone=3.6%20M2;target_milestone=3.6%20M3;target_milestone=3.6%20M4;target_milestone=3.6%20M5;target_milestone=3.6%20M6;target_milestone=3.6%20M7;target_milestone=3.6%20RC1;target_milestone=3.6%20RC2;target_milestone=3.6%20RC3;target_milestone=3.6%20RC4">query</a> to see all the bugs fixed in the Eclipse Platform in 3.6; it is a long list (4309 and counting). Felipe gets credit for the <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=4866">oldest bug fixed</a> (raised in 2001), but in a close second is <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=4922">bug 4922</a> (raised only a day later).<br /><br />This bug is about opening files in eclipse from the command line. Fixing it required a coordinated effort between Platform UI, <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=201154">SWT</a>, and the <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=178927">Equinox launcher</a>. A lot of the credit for what was done goes to Kevin Barnes.<br /><br />This post is an effort to explain some of the technical details of what is going here.<br /><br /><b>On the Mac...</b>: On the mac all we do is handle the apple event "<a href="http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man3/Mac__AppleEvents.3pm.html">kAEOpenDocuments</a>", most of the rest of this post doesn't apply to the mac.<br /><br /><b>Windows and GTK... </b> Everything below applies to Windows and GTK, though there are some differences in the implementation details.<br /><br /><b>On Motif...</b> Sorry, this doesn't work on motif.<br /><h2>The Launcher</h2>Everything starts in the eclipse launcher. We added a few new command line options:<br /><ul><li><tt style="font-weight: bold;">--launcher.openFile</tt> : obvious enough, specifies the file we want to open.</li><li><tt style="font-weight: bold;">--launcher.defaultAction</tt> : less obvious, specifies the action to take when the launcher is started without any '-' arguments on the command line. Currently the only support value is "<tt>openFile</tt>".<br /></li><li><tt style="font-weight: bold;">--launcher.timeout</tt> : a timeout value for how long we should spend trying to communicate with an already running eclipse before we give up and just open a new eclipse instance. Default is 60 (seconds).<br /></li></ul>The first argument is obvious enough, open the specified file in eclipse.<br /><div style="text-align: center;"><pre>eclipse --launcher.openFile myFile.txt<br /></pre></div>This is great, but it is a bit much to type on the command line and is <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=301033">not quite enough</a> to make everyone happy. We introduced the "default action" argument. This goes in the eclipse.ini file, the value should be "<tt>openFile</tt>":<br /><blockquote><pre>...<br />-showsplash<br />org.eclipse.platform<br /><span style="font-weight: bold;">--launcher.defaultAction</span><br /><span style="font-weight: bold;">openFile</span><br />-vmargs<br />-Xms256m<br />-Xmx768m<br /></pre></blockquote>This tells the launcher that if it is called with a command line that only contains arguments that don't start with "<tt>-</tt>", then those arguments should be treated as if they followed "<tt>--launcher.openFile</tt>".<br /><div style="text-align: center;"><pre>eclipse myFile.txt<br /></pre></div>This is the kind of command line the launcher will receive on windows when you double click a file that is associated with eclipse, or you select files and choose "Open With" or "<a href="http://www.microsoft.com/windowsxp/using/setup/tips/advanced/sendtomenu.mspx">Send To</a>" Eclipse.<p><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=300532">Relative paths</a> will be resolved first against the current working directory, and second against the eclipse program directory.<br /><br /></p><h2>Talking to SWT</h2>The launcher talks to SWT through the use of a hidden window. <b>The launcher and SWT both need to agree on the name of this window</b>. This allows the launcher to find an already running eclipse and tell it to open the file. Any RCP application will need to ensure they get this right for things to work.<br /><br />The launcher bases this on its "official name". The official name can be set with the <a href="http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/misc/runtime-options.html"><tt>-name</tt></a> argument. If <tt>-name</tt> is not set, then the official name is derived from the launcher executable, the extension is removed and the first letter is capitalized: <tt>rcp.exe</tt> becomes <tt>Rcp</tt>.<br /><br />SWT bases this on the value set with the <tt>Display.setAppName()</tt> function. Normally, this is set by the Workbench when it creates the display and the value is the "appName" taken from the product extension point.<br /><br /><h2>Listening to SWT</h2>To take advantage of this, an RCP Application will need to register a listener for the SWT.OpenDocument event. It should register this listener before calling <tt>PlatformUI.createAndRunWorkbench</tt> so that the listener is in place before the workbench starts running the event loop. <br /><br />The event loop will start running while the splash screen is still up, so events may arrive before the workbench is ready to actually open an editor for the file. This means that the listener should save the file paths it gets from the OpenDocument events so they can be opened at some later time. <tt>WorkbenchAdvisor#eventLoopIdle</tt> can be a good place to check for saved open file events.<br /><br /><h2>Implementation details</h2>Here is an overview of the flow of events in the launcher when processing --launcher.openFile on windows.<br /><ol><li>Get the Official Name. As mentioned above, this is the "-name" argument, or derived from the executable name. For this explanation, we will be using "<span style="font-weight: bold;">OfficialName</span>".</li><br /><li>Create and lock a <a href="http://msdn.microsoft.com/en-us/library/aa914601.aspx">mutex</a> named "SWT_Mutex_OfficialName".<br /><ul><li> If multiple files are selected and opened on windows, then a seperate eclipse process will be created for each one. The mutex allows us to ensure only one eclipse instance is actually started.</li><li>One process will win the race to acquire the mutex, at this point, there will be no eclipse instance running that has the SWT window available. This process will start normally and eventually create the SWT window at which point it will release the mutex.</li><li>All the other processes wait trying to acquire the mutex, once the original process releases it, they will be able to find the SWT window and post their open file message there.</li><li>Each process only waits for <tt>--launcher.timeout</tt> seconds (default 60 seconds) before giving up and just starting its own full eclipse instance.</li></ul><br /></li><br /><li>Find the window named "SWT_Window_OfficialName"<br /><ul><li>If no such window exists, we are the first eclipse instance. In this case, we set a timer to look again later and then proceed with starting eclipse.</li><li>The timer fires every second for <tt>--launcher.timeout</tt> seconds.</li><li>If we don't find the SWT window before the timeout (perhaps it took too long for the workbench to create the display), then we will be unable to open the file.</li><br /></ul><br /></li><li>Send a message to the SWT window<br /><ul><li>Once we've found the SWT window, we create a <a href="http://msdn.microsoft.com/en-us/library/ms644947%28VS.85%29.aspx">custom message</a> named "SWT_OPENDOC". We <a href="http://msdn.microsoft.com/en-us/library/ms644950%28v=VS.85%29.aspx">send</a> this message with wParam & lParam specifying a shared memory id.</li><li>We write to the name of the file to open into shared memory, and when SWT receives the SWT_OPENDOC message, it uses that id to read the shared memory.</li><li>The launcher has long used shared memory on all platforms for the splash screen, restarts and exit messages.</li><li>Once SWT reads the file name from shared memory, it posts its own SWT.OpenDocument event.</li></ul></li></ol>On GTK, things happen in a similar manner with a few differences:<br /><ol><li>We use <a href="http://linux.die.net/man/3/sem_open">semaphores</a>.<br /><ul><li> Semaphores are not cleaned up automatically if the process exits unexpectedly. So we try to hold the semaphore for as short a time as possible and we install SIGINT and SIGQUIT signal handlers for the time we hold the semaphore.<br /></li><li>The launcher creates a hidden GTK window named <tt>SWT_Window_Launcher<b>OfficalName</b></tt> which is used in the same way as the mutex on windows. This lets us avoid holding the semaphore for an extended time while the first eclipse process starts up.<br /></li></ul></li><br /><li>We use a <a href="http://library.gnome.org/devel/gdk3/stable/gdk3-Properties-and-Atoms.html#gdk-property-change">property</a> instead of a message.<br /><ul><li>The property is named <tt>org.eclipse.swt.filePath.message</tt>.</li><li>The value is a colon separate list of file paths to open. Shared memory is not used like it is on windows.</li></ul></li></ol>Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com7tag:blogger.com,1999:blog-25095519.post-16869714854737144192009-08-06T14:08:00.003-05:002009-08-06T17:41:20.441-05:00Versioning & p2, slides from EclipseConThis year at EclipseCon, I presented a <a href="http://www.eclipsecon.org/2009/sessions?id=585">10 minute talk</a> on the importance of versioning with p2. I have posted the slides <a href="http://eclipse.org/equinox/documents/EclipseCon2009/p2Versioning.pdf">here</a>. Because this was only a 10 minute talk, there is not a lot of content in the slides, so this post is an attempt at an overview.<br /><br /><h3>id + version == 1 set of bytes</h3>Hopefully by now everyone has heard this before. In the world of p2, an id and a version represent a particular set of bytes. If multiple copies of a given artifact exist in multiple places, and they all have the same id and version, they are assumed to be the same (or equivalent) bytes.<br /><br />In particular, this means that if your user already has a bundle org.foo_1.0.0 on his machine, and you are trying to deliver an update, then the user will not download your updated org.foo if the version number is still 1.0.0.<br /><br />So make sure you increase your version numbers, it is hard to support a customer when you can't tell if his org.foo_1.0.0 is the broken version or the fixed version!<br /><br /><h3>We tend to version sources</h3>The process we follow in Eclipse tends to version sources. We tag our source code with the version qualifier which determines the version of the resulting binary. The idea is this leads to reproducible builds.<br /><br />However, we must realize that there is more than just the source code that affects what the resulting binary looks like. These are things like what compiler was used, the build scripts, and most importantly the dependencies that were on our build-time classpath.<br /><br />If some bundle <tt>B</tt> depends on bundle <tt>A</tt> and <tt>A</tt> changes in some way, then recompiling <tt>B</tt> can potentially result in different byte-code even though the source code did not change. In this case, <tt>B</tt> deserves to have its version number increased.<br /><br /><h3>Mirroring with a baseline and comparator</h3>This scenario of a bundle changing without having its version incremented has happened more than once in the Eclipse SDK releng builds. In order to detect this, we use a previous build as a baseline in a mirror operation. If the baseline already contains a bundle with the same version as the one that was just built, then we mirror the old bundle and discard the new one.<br /><br />We install our product using the mirrored results which ensures that our new install contains the same old bundles that already exist out on user's machines. The unit tests run against these old bundles.<br /><br />In order to detect when a bundle actually changes and needs its version number increased, the mirror operation supports a comparator. <a href="http://olivier-eclipse.blogspot.com/">Olivier</a> kindly contributed some code to p2 that can do a semantic compare on java class files to see if they are equivalent. Similarly, things like manifests and properties files can be compared for semantic instead of bitwise equivalence.<br /><br /><h3>Example Build</h3>I put together an example feature build that uses a comparator to detect if a bundle has changed when the version hasn't. The projects are in <a href="http://dev.eclipse.org/viewcvs/index.cgi/pde-build-home/examples/comparator/">CVS</a> under <tt>dev.eclipse.org:/cvsroot/eclipse/pde-build-home/examples/comparator</tt>. There are 4 projects to check out:<br /><ul><li>example.Builder - the builder project, contains a runBuild.xml</li><li>org.example.a - a project that we will change between builds</li><li>org.example.b - depends on <tt>a</tt>, won't change source between builds</li><li>org.example.feature - the feature to build</li></ul>To run the example, just run <tt>runBuild.xml</tt> script as an Ant Build using the same JRE as the workspace. The build will mirror the results into <tt>example.Builder/composite/I<timestamp></tt>. You can run the build multiple times, and each time the results will be added to the composite repository.<br /><br />The mirror call is done in <tt>example.Builder/customTargets.xml/postBuild</tt>. It looks like this:<br /><pre name="xml" class="xml:nocontrols:nogutter"><br /><target name="postBuild"><br /> <antcall target="gatherLogs" /><br /><br /> <!-- mirror from build results, comparing against previous builds that are in the composite repo --><br /> <p2.mirror><br /> <source location="file:${assemblyTempDir}/${buildLabel}"/><br /> <destination location="file:${builder}/composite/${buildLabel}"/><br /> <comparator comparator="org.eclipse.equinox.p2.repository.tools.jar.comparator" comparatorLog="${buildDirectory}/comparator.log"><br /> <repository location="file:${builder}/composite" /><br /> </comparator><br /> </p2.mirror><br /><br /> <!-- add the new build to the composite --><br /> <p2.composite.repository destination="file:${builder}/composite"><br /> <add><br /> <repository location="file:${builder}/composite/${buildLabel}"/><br /> </add><br /> </p2.composite.repository><br /></target><br /></pre><br />Each build uses the previous contents of the composite repository as a baseline, and then adds itself to the composite.<br /><br />To see the comparator in action, edit <tt>org.example.a.Sub</tt> and uncomment the <i>doSomething</i> method:<br /><pre name="java" class="xml:nocontrols:nogutter"><br />public void doSomething(List o) {<br /> for (Iterator iterator = o.iterator(); iterator.hasNext();) {<br /> super.doSomething(iterator.next());<br /> }<br />}<br /></pre><br /><br />This change to the source code of <tt>org.example.a</tt> will change which <i>doSomething</i> <tt>B</tt> ends up calling:<br /><pre name="java" class="xml:nocontrols:nogutter"><br />public class B {<br /> public void method() {<br /> ArrayList list = new ArrayList();<br /> list.add(this);<br /> <br /> Sub d = new Sub();<br /> d.doSomething(list);<br /> }<br />}<br /></pre><br /><br />That is, recompiling <tt>B</tt> against the new <tt>A</tt> results in different byte-code for <tt>B</tt>. If we run the build again with the changed source, then it will now fail with an error message:<br /><pre><br />[p2.mirror] Messages while mirroring artifact descriptors.<br />[p2.mirror] Compare and download of canonical: osgi.bundle,org.example.b,1.0.0 from baseline.<br />[p2.mirror] Difference found for org/example/b/B.class within [canonical: osgi.bundle,org.example.b,1.0.0]<br /> from file:/C:/workspace/example.Builder/composite/I20090806060019/<br /></pre><br />When the build fails in this manner, it means we need to increment the version for <tt>org.example.b</tt><br /><br /><h4>Build Notes<br /></h4><ol><li>The builder's <tt>build.properties</tt> sets <tt>pluginPath</tt> and <tt>elementPath</tt> to enable the build to use the sources in the workspace without copying them to the <tt>buildDirectory</tt>. <tt>elementPath</tt> points to the top level feature that we are building.</li><li>The build is using <tt><a href="http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.pde.doc.user/tasks/pde_p2_builds.htm">p2.gathering=true</a></tt>, for feature builds, this groups the configurations, we set <tt>archivesFormat</tt> to leave the results as a folder.</li><li><tt>runBuild.xml</tt> automatically refreshes the workspace when it finishes, however when the build fails after changing the source in <tt>org.example.a</tt>, this refresh doesn't happen and you need to refresh the workspace manually to see the new results.</li><li>In <tt>customTargets.xml/preGenerate</tt> we create an empty composite repository if there wasn't already one there.</li><li>We changed the default <tt>customTargets.xml/gatherLogs</tt> to use <tt>elementPath</tt> since the top level feature is not under <tt>buildDirectory</tt>.</li><li><tt>org.example.a</tt> has version <i>1.0.0.qualifier</i> where the qualifier gets replaced each build with the timestamp. <tt>org.example.b</tt> just has version <i>1.0.0</i>. In a releng build, the CVS tag from a map file would be used instead of the timestamp.<br /></li></ol>Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com0tag:blogger.com,1999:blog-25095519.post-14786073188630625832009-07-08T10:48:00.004-05:002013-07-03T14:44:09.504-05:00ADT Part 2: More like the EPP<a href="http://aniefer.blogspot.com/2009/07/composing-and-updating-custom-eclipse.html">Yesterday</a>, I posted an example of how to compose a product made up out of updatable sub-components. The first question there was about how this relates to the <a href="http://www.eclipse.org/downloads/">packages</a> built by the <a href="http://eclipse.org/epp/">EPP</a>. The EPP packages are just products, much like my ADT. They use their own feature and plugin to brand the Eclipse package and do things like open a different default perspective.<br />
<br />
The EPP packages are built slightly different from my first example. They use feature requirements to get version ranges for the sub-components, but they don't currently perform the extra director calls to make those sub-components into updatable roots.<br />
<br />
Here is another example that is structured a bit more like the EPP packages.<br />
This example is also available in <a href="http://dev.eclipse.org/viewcvs/index.cgi/pde-build-home/examples/">cvs</a> with the first (dev.eclipse.org:/cvsroot/eclipse/pde-build-home/examples/adt.feature.builder).<br />
<br />
[Edit 2013/07/03: Eclipse CVS has migrated to git starting in 2010. The
examples are now available under the examples folder in <a href="http://git.eclipse.org/c/pde/eclipse.pde.build.git/" rel="nofollow" target="_blank">http://git.eclipse.org/gitroot/pde/eclipse.pde.build.git</a>. The example has not been updated to work with git and may require modifications.]<i></i><br />
<br />
<h3>
Features instead of p2.inf</h3>
<br />
In our first example, we used a <a href="http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/p2_customizing_metadata.html">p2.inf</a> file to add requirements with version ranges to our product. I did it this way because I didn't have anything to add to the product, and didn't want to bother creating a feature.<br />
<br />
Perhaps a more familiar way of doing things would have been to use a feature. So we create a feature "<tt>adt.feature</tt>", and instead of including our sub-components, we require them using a "compatible" match rule:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw_m-E_RaI-C8u3jtKJoq8Fc_U3LCOHhM7NMU3tIQr2ne8l5ua512VrNYwqmTUk0VwcKSIFjR_1qOczhyR-mHX0JyjbhT5hSklEDoUaNj6jm7ufSzprbyRBaRDcXpCUUzyh6VkRA/s1600-h/screen1.PNG" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5356120629852369154" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw_m-E_RaI-C8u3jtKJoq8Fc_U3LCOHhM7NMU3tIQr2ne8l5ua512VrNYwqmTUk0VwcKSIFjR_1qOczhyR-mHX0JyjbhT5hSklEDoUaNj6jm7ufSzprbyRBaRDcXpCUUzyh6VkRA/s320/screen1.PNG" style="cursor: pointer; display: block; height: 166px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a><br />
<br />
I also made my feature include the "<tt>org.eclipse.platfom</tt>" feature. The adt.product file then just includes <tt>adt.feature</tt>. We no longer need the p2.inf to add requirements to our product.<br />
<br />
<h3>
Adding Branding</h3>
<br />
Since we created our own feature for this product, we may as well take the next step and add our own branding plug-in. The first thing I did way create my own product extension in the plugin.xml:<br />
<pre>
<extension id="product" point="org.eclipse.core.runtime.products">
<product application="org.eclipse.ui.ide.workbench" name="ADT Product">
<property name="aboutText" value="Andrew's Development Tools"/>
<property name="windowImages" value="icons/icon.gif"/>
<property name="aboutImage" value="product.gif"/>
</product>
</extension></pre>
<br />
<br />
<i>Note that the word 'product' here is slightly overloaded. There is a 'org.eclipse.core.runtime.products' extension point that defines branding for eclipse, and there is the product itself which is what we are building using the .product file. </i><br />
<br />
This product is just running the normal workbench application, but it uses my own icons and images. We then change our adt.product file to use <tt>adt.plugin.product</tt> instead of the <tt>org.eclipse.platform.ide</tt> product extension we were using before.<br />
<br />
In my <tt>adt.feature</tt> I set the branding plug-in to be my new <tt>adt.plugin</tt>. I also provide the normal about.* files so that my feature shows up in the about dialog.<br />
<br />
As a final touch, I made my own splash screen.<br />
<br />
<h3>
Building the new Product</h3>
<br />
The build script is essentially unchanged from the first example. So I won't bother explaining the details again. The only difference is that I made some minor changes to the builder's build.properties file so that pde.build can find our feature and plugin.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidQUJXPk0V3Q9FqKSJGUkw4DgTw96Ksc_ouUEL3yLP8cqYVvQXHr9SnqqjIELEirP_ttCUG2nRzOq78jAbLE21qSKk0jhd-DyPomymdMuKAvmfJtFE9DN6S0fBYUfBJ5FRYZvNWg/s1600-h/screen2.PNG" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5356140532393315346" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidQUJXPk0V3Q9FqKSJGUkw4DgTw96Ksc_ouUEL3yLP8cqYVvQXHr9SnqqjIELEirP_ttCUG2nRzOq78jAbLE21qSKk0jhd-DyPomymdMuKAvmfJtFE9DN6S0fBYUfBJ5FRYZvNWg/s320/screen2.PNG" style="cursor: hand; cursor: pointer; display: block; height: 176px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a><br />
<br />
Note that PDE/Build does not follow feature requirements when performing a build and publishing metadata. This means that for the director install to work, you need to have pre-existing metadata for the things that you are requiring. This same requirement exists with the first example where we used a p2.inf file.Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com22tag:blogger.com,1999:blog-25095519.post-10577501664730057052009-07-07T15:01:00.008-05:002013-07-03T14:43:27.751-05:00Composing and updating custom Eclipse distrosI've recently seen a <a href="http://www.eclipse.org/forums/index.php?t=msg&th=41383&start=0&S=5763840b219361fc591b43e71884b82b">couple</a> of <a href="http://www.eclipse.org/forums/index.php?t=tree&th=41087&start=0&S=47c495d41f26650fc5964f406daf6b70">different</a> posts to the newsgroups dealing with problems updating RCP applications using p2. <span style="font-size: small; font-style: italic;">[edit 2009/10/21, update links to forums]</span><br />
<br />
As an example, I've created my own Eclipse product. It is composed of the <a href="http://www.eclipse.org/platform/">Eclipse Platform</a>, <a href="http://eclipse.org/eclipse/platform-cvs/">CVS support</a>, the <a href="http://eclipse.org/cdt/">CDT</a> and <a href="http://eclipse.org/mylyn/">Mylyn</a>. I'm calling it the ADT (Andrew's Development Tools).<br />
<br />
It's not hard to create a feature based product that includes these things, and do a <a href="http://aniefer.blogspot.com/2009/03/building-p2-rcp-products-in-eclipse.html">product build</a> to end up with something like this:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2AzqIarw69L1sa46BKsJyV_JbfwmkpiBLFtJNhLzeqPauf84Vv7uej01-v3WuF6FelKMZzV-BJO5qGoGGrCGLvvizYy0L-kwMb1PvVx7VDsZU7SKnG59FR_2XgmPr0HZ3lYbEnw/s1600-h/screen1.PNG" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5355816291891409650" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2AzqIarw69L1sa46BKsJyV_JbfwmkpiBLFtJNhLzeqPauf84Vv7uej01-v3WuF6FelKMZzV-BJO5qGoGGrCGLvvizYy0L-kwMb1PvVx7VDsZU7SKnG59FR_2XgmPr0HZ3lYbEnw/s400/screen1.PNG" style="cursor: pointer; display: block; height: 281px; margin: 0px auto 10px; text-align: center; width: 400px;" /></a><br />
<br />
As explained in <a href="http://www.eclipse.org/newsportal/article.php?id=81809&group=eclipse.platform#81809">this newsgroup post</a>, there are two kinds of things that are included in an Eclipse install:<br />
<ol>
<li>Things that are explicitly installed</li>
<li>Things that are required by the things that are installed.</li>
</ol>
Here in my example, only my development tools "org.example.adt" is installed, the rest (CDT, CVS, Mylyn) are required by my product.<br />
<br />
Only things that are explicitly installed will be searched for when you look for updates. Also, the installed things generally specify the versions of things they require, which makes it hard to install/update those required items independently of the root product. In both the newsgroup postings I referred to above, the problem was trying to install/update one of the required items without updating the root product.<br />
<br />
So the question becomes how to allow updating sub-components of the product without updating the product itself.<br />
<br />
<h3>
Composing for Updatability</h3>
What we want to do is to update sub-components of the product without updating the root product itself. In this example we do not to allow updating the Eclipse Platform independently, to do that, the user will need to update the product itself.<br />
<br />
I have created a example builder to do this. Get it from <a href="http://dev.eclipse.org/viewcvs/index.cgi/pde-build-home/examples/"><b>cvs</b></a> (dev.eclipse.org:/cvsroot/eclipse/pde-build-home/examples/adt.builder).<br />
<br />
[Edit 2013/07/03: Eclipse CVS has migrated to git starting in 2010. The
examples are now available under the examples folder in <a href="http://git.eclipse.org/c/pde/eclipse.pde.build.git/" rel="nofollow" target="_blank">http://git.eclipse.org/gitroot/pde/eclipse.pde.build.git</a>. The example has not been updated to work with git and may require modifications to run properly.]<br />
<br />
We need to do two things:<br />
<ol>
<li>Use version ranges to include sub-components in our product so that we allow upgrading those components.</li>
<li>Explicitly install those sub-components so they will be found when checking for updates. This is essentially a book-keeping step.</li>
</ol>
<h4>
The ADT .product File</h4>
There is a <tt>adt.builder/product/adt.product</tt> file which we will use to run a product build. If we were to include the features for our sub-components in the .product file, then we would end up with requirements on specific versions of those components. Instead we only include the platform feature <span style="font-size: 85%;"><a href="http://www.blogger.com/post-create.g?blogID=25095519#note_1">[1]</a></span>.<br />
<br />
To get requirements to our sub-components, we use a <a href="http://wiki.eclipse.org/Equinox/p2/Customizing_Metadata">p2.inf</a> file to <a href="http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/p2_customizing_metadata.html">customize</a> the metadata. We add requirements with entries that look like this:<br />
<pre>
requires.1.namespace = org.eclipse.equinox.p2.iu
requires.1.name = org.eclipse.cvs.feature.group
requires.1.range = [1.1.100, 1.2.0)
requires.2.namespace = org.eclipse.equinox.p2.iu
requires.2.name = org.eclipse.mylyn_feature.feature.group
requires.2.range = [3.2.0, 3.3.0)
...</pre>
<br />
The <tt>.feature.group</tt> suffix is the name of the p2 <a href="http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.pde.doc.user/tasks/pde_p2_featuremetadata.htm">Installable Unit</a> corresponding to the features we are interested in. We specify the version ranges in which we will allow those components to be updated.<br />
<h4>
The ADT Builder</h4>
The adt.builder project includes a <tt>buildADT.xml</tt> ant script which will run a headless product build for us. The first thing it does is download zips containing the things we need. This example illustrates three different ways of <a href="http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.pde.doc.user/tasks/pde_p2_reusingmetadata.htm">reconsuming metadata</a>.<br />
<ol>
<li>The <a href="http://download.eclipse.org/tools/cdt/releases/galileo/dist/cdt-master-6.0.0.zip">CDT</a> and <a href="http://download.eclipse.org/eclipse/downloads/drops/R-3.5-200906111540/org.eclipse.cvs-p2repo-3.5.zip">CVS</a> both come as zipped p2 repositories. Things that are not referenced directly by the .product file only need to be available as repositories. We can reuse these zips directly by specifying them as context repositories using jar: urls. See the <tt>p2.context.repos</tt> property in the <tt>adt.builder/build.properties</tt> file.</li>
<li><a href="http://download.eclipse.org/tools/mylyn/update/mylyn-3.2.0-e3.4.zip">Mylyn</a> is not a p2 repository, it is a zipped old style update site. For this, we use a <a href="http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/p2_publishingtasks.htm">publisher task</a> to generate p2 metadata for it. <span style="font-size: 85%;"><a href="http://www.blogger.com/post-create.g?blogID=25095519#note_2">[2]</a></span></li>
<li>The <a href="http://download.eclipse.org/eclipse/downloads/drops/R-3.5-200906111540/org.eclipse.platform-p2repo-3.5.zip">Eclipse Platform</a> is a p2 repository just like the CDT and CVS. It is similar to the <a href="http://aniefer.blogspot.com/2009/06/using-deltapack-in-eclipse-35.html">delta pack</a> in that it contains the org.eclipse.equinox.executable feature that is need to get launchers in product builds. Because the platform feature is included directly in the product, we can't just specify the platform as a context repository, we need the bundles available to pde.build like in a normal headless build. To do this we transform the repository using the <tt><a href="http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/p2_repositorytasks.htm#p2_repo2runnable">p2.repo2runnable</a></tt> task. See the <tt>transformedRepoLocation</tt> and <tt>repoBaseLocation</tt> properties in the build.properties file. The transformed repository automatically gets included along with the <tt>pluginPath</tt> property used by pde.build.</li>
</ol>
<h4>
Adding additional director calls</h4>
In order for our sub-components to be independently updatable, they need to be explicitly installed in our resulting product. By default PDE/Build performs a <a href="http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/p2_director.html">director install</a> for just the product being built. We can use a <tt><a href="http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.pde.doc.user/tasks/pde_customization.htm">customAssembly.xml</a></tt> script to perform additional director<span style="font-size: 85%;"><a href="http://www.blogger.com/post-create.g?blogID=25095519#note_3">[3]</a></span> calls before the final archive is created.<br />
<br />
It looks like this:<br />
<pre><target name="pre.archive">
<ant antfile="${genericTargets}" target="runDirector" inheritAll="true">
<property name="p2.repo" value="${p2.build.repo}"/>
<property name="p2.director.iu" value="org.eclipse.cvs.feature.group"/>
<property name="p2.director.installPath" value="${eclipse.base}"/>
</ant>
...
</target></pre>
We make director calls for each of the sub components we allow to be updated. In the example we do CVS, Mylyn, CDT, and the CDT-Mylyn bridge.<br />
<br />
<h3>
The final result</h3>
Run the adt.builder by right-clicking on buildADT.xml and choosing Run As -> Ant Build... Be sure to run in the <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ2GIjxbBXh3lOw0WvTiEwQ57R0JE2P8duWn3J0A_XrjA9PlbqXyjW8XXHTUFvF6JZbG_43LEXDtIGSvQUDPpX6MmcOl3Cl4W-LfDVSTt1RcmKYDiKKNdJpyP88iEwG5PXDNhCEg/s1600-h/screen2.PNG" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}">same JRE</a> as the workspace. After running the build, the results are available under <tt>adt.builder/buildDirectory/I.<timstamp></tt>.<br />
<br />
Running the resulting product, we see that the CDT, Mylyn and CVS are all showing up as installed roots, and are therefore independently updatable.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaDvKaMMj0EMxLq3uQ_qg5HM8bAjwoRagMZ9BaVSExSrMP2GRmuBfh1eB9SJu0HPrkLUSU18yvubDa_X_-iFH7ZZNqdyB3za6vHRCFl-nEnhjr0EUPQXjfkcDzyFQn5NHE9luLiQ/s1600-h/screen3.PNG" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img alt="" border="0" id="BLOGGER_PHOTO_ID_5355847021800846850" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaDvKaMMj0EMxLq3uQ_qg5HM8bAjwoRagMZ9BaVSExSrMP2GRmuBfh1eB9SJu0HPrkLUSU18yvubDa_X_-iFH7ZZNqdyB3za6vHRCFl-nEnhjr0EUPQXjfkcDzyFQn5NHE9luLiQ/s320/screen3.PNG" style="cursor: pointer; display: block; height: 211px; margin: 0px auto 10px; text-align: center; width: 320px;" /></a><br />
<br />
<h4>
Notes</h4>
<ol>
<li><a href="http://www.blogger.com/null" name="note_1"></a>PDE/Build will automatically generate start level configuration information, but only for things that are included in the .product file. If we didn't include the platform feature, or at least the bundles that need start level information, then this would not happen automatically and we would need to handle start levels ourselves. See the help page <a href="http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.pde.doc.user/tasks/pde_p2_configuringproducts.htm">here</a> for more information of configuring start levels.</li>
<li><a href="http://www.blogger.com/null" name="note_2"></a>We publish the p2 metadata for mylyn into <tt><a href="http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.pde.doc.user/tasks/pde_p2_builds.htm">${p2.build.repo}</a></tt>. This property specifies the location of the p2 repository that will be used internally by the build. Publishing the mylyn metadata here instead of some location specified as a context repository saves the build from mirroring the required IUs into the build repository.</li>
<li>PDE/Build provides a "<tt><a href="http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse.pde.doc.user/tasks/pde_p2_productbuilds.htm">runDirector</a></tt>" target that can be used to invoke the director. This works by executing the director application in a new process. Normally, this requires setting the "<tt>equinoxLauncherJar</tt>" property specifying the location of the equinox launcher to use, but because we are calling the director from customAssembly.xml, we inherit this property from the generated assembly scripts.</li>
<li>Running this build produces a properly p2 enabled product. It does not produce a corresponding repository for that product other than the build time repository <tt>${p2.build.repo}</tt>. To produce a final repository containing the final product, define the properties <tt>p2.metadata.repo</tt> and <tt>p2.artifact.repo</tt> in the build.properties. The product and its requirements will then be automatically mirrored into that repo.</li>
</ol>
Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com5tag:blogger.com,1999:blog-25095519.post-23780418756774987652009-06-25T12:10:00.007-05:002009-06-25T12:43:23.572-05:00Using the deltapack in Eclipse 3.5<a href="http://eclipse.org/galileo/">Eclipse Galileo</a> was released yesterday and I have already seen a couple of questions on the newsgroups regarding how to install the delta pack.<br /><br /><h3>What's a delta pack?</h3>For those who don't know what it is, the delta pack is a zip file provided by the Eclipse Platform and it is used for developing RCP applications for multiple platforms. The delta pack archive contains all the platform specific fragments from the Eclipse SDK. It also includes a feature "<tt>org.eclipse.equinox.executable</tt>" which contains binary launchers for all the platforms. The archive is available for <a href="http://download.eclipse.org/eclipse/downloads/drops/R-3.5-200906111540/download.php?dropFile=eclipse-3.5-delta-pack.zip">download</a> through the Eclipse Classic "Other downloads" page.<br /><p>The delta pack is required if you want to do headless product builds, or to export products from the UI:</p><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ_SSVWEI4HAx6uTHp9Gom9h8Vm6qbMOKqeYxJWKx54AXJ7yMtvDebAhjZeykFcFMDDzbwOWImKDbxjYxbPgemc40uk1dhAXxTT8mHQ8Vqy55KE8tGDCDPW07SJeq5D-525u_kNQ/s1600-h/export.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 263px; height: 320px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ_SSVWEI4HAx6uTHp9Gom9h8Vm6qbMOKqeYxJWKx54AXJ7yMtvDebAhjZeykFcFMDDzbwOWImKDbxjYxbPgemc40uk1dhAXxTT8mHQ8Vqy55KE8tGDCDPW07SJeq5D-525u_kNQ/s320/export.jpg" alt="" id="BLOGGER_PHOTO_ID_5351316788758618114" border="0" /></a><br />If you don't have the delta pack installed, then the option to export your product for multiple platforms will not appear in the wizard.<br /><br /><h3>How to install the delta pack</h3>Ian Bull blogged about the improved Target Platform management system as <a href="http://eclipsesource.com/blogs/2009/06/22/eclipse-galileo-feature-top-10-list-number-3/">#3 in his Galileo Feature top ten list</a>. This is the recommended method of installing the delta pack.<br /><ol><li>Extract the delta pack archive into its own directory on disk.</li><li>Open the Target Platform preferences (Window -> Preferences -> Plug-in Development -> Target Platform).</li><li>Add a new target, or edit the active target.</li><li>Add the directory where you extracted the delta pack.</li></ol><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqlrhl5XO0D7xk_28BvdpHTw0qwPc4iVCD404aDMYNmjrV5VzlaBkXGbnOiN87gCUmtoYEdYgdO5A_MZNaoCA4Q0pR2cM4Bm-zXOXruR1lq0nsoEbdtlaYHU2Kxdd3VXIgTEwPSg/s1600-h/screen1.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 304px; height: 320px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqlrhl5XO0D7xk_28BvdpHTw0qwPc4iVCD404aDMYNmjrV5VzlaBkXGbnOiN87gCUmtoYEdYgdO5A_MZNaoCA4Q0pR2cM4Bm-zXOXruR1lq0nsoEbdtlaYHU2Kxdd3VXIgTEwPSg/s320/screen1.JPG" alt="" id="BLOGGER_PHOTO_ID_5351320217340988834" border="0" /></a><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgz6ZDMm4ykCb-EaFeGM0HmdnQNl5J0kUfyiQ2a5V4KN1MXyDIhNUh1Bmpr4vEOUJCymHjUgrzTE-b79Kz3Loi6SYs4EEfE66Kgfi6U4_j7h0Yes2JHpdsf8BV0ypR3JY2ub4WZVQ/s1600-h/screen2.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 226px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgz6ZDMm4ykCb-EaFeGM0HmdnQNl5J0kUfyiQ2a5V4KN1MXyDIhNUh1Bmpr4vEOUJCymHjUgrzTE-b79Kz3Loi6SYs4EEfE66Kgfi6U4_j7h0Yes2JHpdsf8BV0ypR3JY2ub4WZVQ/s320/screen2.JPG" alt="" id="BLOGGER_PHOTO_ID_5351321092416511794" border="0" /></a>Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com3tag:blogger.com,1999:blog-25095519.post-33864337678727909452009-06-15T12:42:00.004-05:002009-06-15T14:12:09.592-05:00Patching Features (Part 2)In my <a href="http://aniefer.blogspot.com/2009/06/patching-features-with-p2.html">last post</a> I showed how to create a simple feature patch. However, this patch leaves us in a state where we can no longer upgrade the platform because the patch itself requires a specific version of the feature it is patching.<br /><br /><h3>Making the patch Optional</h3><br />If we make the inclusion of the patch in our org.example.feature optional, then we no longer block upgrading the platform underneath us.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHwJNUKC6CL2xJvFFaVdnSQkzBRVfK6ss8KOYigMai4ctFNI32cgOMzuSMeBzr5GEcmAt0nK6GR-Xst4UPwq9e1PVApVqzlgaU5x6pEWlFIT3c754d9EoZ1h8zSPl99KMl901N_w/s1600-h/screen3.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 235px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHwJNUKC6CL2xJvFFaVdnSQkzBRVfK6ss8KOYigMai4ctFNI32cgOMzuSMeBzr5GEcmAt0nK6GR-Xst4UPwq9e1PVApVqzlgaU5x6pEWlFIT3c754d9EoZ1h8zSPl99KMl901N_w/s320/screen3.JPG" alt="" id="BLOGGER_PHOTO_ID_5347614189643291554" border="0" /></a><br /><br />When a new version of the platform is available, there is a conflict between the version of the p2.user.ui feature required by the patch and the one required by the new platform. By making the patch optional, <b>p2 will not install the patch</b> if there is a conflict.<br /><br />This is fine if the new version of the platform includes the fix we want. But what if it doesn't? What if we need to have our patch apply to several different versions of the platform?<br /><br /><h2>Relaxing version ranges</h2>Unfortunately, currently the only way to do the following is to edit the metadata by hand. (<a href="http://pweclipse.blogspot.com/">Paul Webster</a> uses <a href="http://www.eclipse.org/newsportal/article.php?id=6375&group=eclipse.technology.equinox#6375">XSLT transforms</a>, I have also raised a <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280314">bug</a> to allow changing things using the <a href="http://wiki.eclipse.org/Equinox/p2/Customizing_Metadata">p2.inf</a> file.)<br /><br />Looking at the metadata for the patch, we see a few interesting sections:<br /><br /><h3>The Patch Scope</h3><br />The scope section of the patch's metadata specifies which feature(s) the patch applies to:<br /><pre><br /><patchScope><br /><scope><br /> <requires size='1'><br /> <required namespace='org.eclipse.equinox.p2.iu'<br /> name='org.eclipse.equinox.p2.user.ui.feature.group'<br /> <b>range='[1.1.0.v20090605-1440-7u6Fb3FbPbJP5MiKiZgpdl,1.1.0.v20090605-1440-7u6Fb3FbPbJP5MiKiZgpdl]'</b>/><br /> </requires><br /></scope><br /></patchScope><br /></pre><br /><br />Here we see the patch applies to a specific version of the org.eclipse.equinox.p2.user.ui feature. By relaxing the version range here we can make the patch apply to other versions of the platform. For example, say we knew our bug was fixed on June 11, but there were several version between June 5th and the 10th that still contained the bug. We could instead use a version range like <tt>[1.1.0.v20090605-1440,1.1.0.v20090611)</tt> (the upper end of the range is open, it includes everything up to but not including v20090611).<br /><br />Note that the patch Installable Unit also has normal requirements on the feature it is patching. When widening the scope range, the regular requirements should also be widened to match.<br /><h3>Change From / Change To</h3>The 'changes' section of the patch's metadata specifies which plug-in we are patching, and the version to change it to.<br /><pre><changes><br /><change><br /> <from><br /> <required namespace='org.eclipse.equinox.p2.iu'<br /> name='org.eclipse.equinox.p2.touchpoint.eclipse'<br /> <b>range='0.0.0'</b>/><br /> </from><br /> <to><br /> <required namespace='org.eclipse.equinox.p2.iu'<br /> name='org.eclipse.equinox.p2.touchpoint.eclipse'<br /> <b>range='[1.0.101.v20090611,1.0.101.v20090611]'</b>/><br /> </to><br /></change><br /></changes><br /></pre><br />In the above example, we are changing the org.eclipse.equinox.p2.touchpoint.eclipse bundle from any version (<tt>"0.0.0"</tt>) to version <tt>1.0.101.v20090611</tt>.<br />We could imagine changing these ranges in the following ways:<br /><ul><li>Change the <span style="font-style: italic;">"scope</span>" range to <tt>"0.0.0"</tt> to match any version of the p2.user.ui feature, and then change the "<i>change from</i>" range to <tt>[1.0.101, 1.0.101.v20090611)</tt>. This would result in patching any version of the p2.user.ui feature that includes any 1.0.101 versioned bundle up to v20090611 (which is the version with the proper fix).</li><li>Change the "<span style="font-style: italic;">change to</span>" range to something like <tt>[1.0.101.v20090611, 1.0.102)</tt>. We know v20090611 contains the fix we want, but the in the future there will be more bug fixes before the maintenance stream is released. By widening the range here, we allow future bug fixes to also be included in our patch.<br /></li></ul>Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com2tag:blogger.com,1999:blog-25095519.post-43806194936960569872009-06-12T12:36:00.006-05:002009-06-12T16:17:18.260-05:00Patching features with p2The <a href="http://eclipse.org/galileo/">Galileo</a> release of Eclipse is in its final days. The eclipse SDK itself is effectively done and the current build is <a href="http://dev.eclipse.org/mhonarc/lists/platform-releng-dev/msg14902.html">under consideration</a> to be the final release.<br /><br /><h3>Imagine This...</h3><p>Say I have a feature that I build, it runs on top of the Eclipse Platform. I know Eclipse Galileo is coming out soon, so I download it and try it out with my feature.</p><p><b>Oh No! It doesn't work!</b> I've found a bug in the platform, and its a major blocker for me. (Oops, maybe I should have tried this a couple of months ago when there still would have been time to fix the bug.)</p><p><i>Meta-Comment: The Eclipse Platform Project has a reputation for shipping on time (even if that means there are unresolved bugs). There is a strict <a href="http://eclipse.org/eclipse/development/freeze_plan_3.5.php">end game plan</a> that is followed for the release, lock down started back at the beginning of May. The further we are along in the plan, the harder it is to get a fix approved for release. A lot of people don't seem to relealize this happens, and perhaps wonder why their important bugs are defered with the comment "Its too late".</i></p><p>Ok, I need to patch the platform. How do I do this?</p> <h3>The Example Feature</h3><p>To work through the steps of patching the platform, I created my own example feature:</p><ol><li>Create a New Plug-in Project "<tt>org.example.plugin</tt>". The plug-in is not a "Rich client Application". On the templates page of the wizard I chose "Plug-in with a view".</li><li>Create a New Feature "<tt>org.example.feature</tt>". Add org.example.plugin to the feature.</li><li>Export the feature, and on the Options tab in the export wizard check "Generate metadata repository". </li></ol>For the purposes of the example, I'm starting from the <a href="http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/S-3.5RC4-200906051444/eclipse-platform-3.5RC4-win32.zip">Eclipse Platform Runtime 3.5RC4</a>. Because I want to strictly control the upgrade path in the example, I removed the Galileo and Eclipse Project repositories from the available sites (Window -> Preferences -> Install/Update->Available Software Sites).<br /><br />Unzip the platform, and installed the feature from the exported repository. I didn't create any categories for the feature, so "Group items by category" must be unchecked.<br /><div style="text-align: center;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgskz6wQ2JcE6q26DCY3AIQnyqv6nLfgA5GWPYm4HvrUM9EsOhDdzF-uUskpGNsvBH6Zo1XnZKQAo2Xv7ZMZ8KDjOH8_w1f194DglMkc4ZnTRxLrLLeBZNlHy-CVs5r1y7rHp99Hg/s1600-h/screen1.JPG"><img style="margin: 0pt 0pt 10px 10px; cursor: pointer; width: 320px; height: 308px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgskz6wQ2JcE6q26DCY3AIQnyqv6nLfgA5GWPYm4HvrUM9EsOhDdzF-uUskpGNsvBH6Zo1XnZKQAo2Xv7ZMZ8KDjOH8_w1f194DglMkc4ZnTRxLrLLeBZNlHy-CVs5r1y7rHp99Hg/s320/screen1.JPG" alt="" id="BLOGGER_PHOTO_ID_5346512543944136082" border="0" /></a><br /></div><br /><h3>The Patch<br /></h3>For the example, I am inspired by <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=279542">bug 279542</a> which came in very late and almost was not fixed in 3.5. The bundle org.eclipse.equinox.p2.touchpoint.eclips has the bug and this plugin is included by the feature org.eclipse.equinox.p2.user.ui.<br /><br />Say we have a fix with touchpoint.eclipse version 1.0.101.v20090611. (<i>When following the <a href="http://wiki.eclipse.org/Version_Numbering">eclipse versioning guidelines</a>, the maintenance version of this bundle should be 1.0.101 and the version for the next year's release will probably be 1.0.200</i>).<br /><br />We can easily create a new Feature Patch with the wizard:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpj55WE9E226YXgQw1GZrfbjSP6-ISyZP8VJboKYaxoRLYlgrecKo_yT4kcbyvkxOjU-SI5yxUl2ZXz4bMYi6ohjJqlFtYhOB4622La5TzSLkzEtVpN9JzCuxzULlDXgkocpuCqA/s1600-h/screen2.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 287px; height: 320px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpj55WE9E226YXgQw1GZrfbjSP6-ISyZP8VJboKYaxoRLYlgrecKo_yT4kcbyvkxOjU-SI5yxUl2ZXz4bMYi6ohjJqlFtYhOB4622La5TzSLkzEtVpN9JzCuxzULlDXgkocpuCqA/s320/screen2.JPG" alt="" id="BLOGGER_PHOTO_ID_5346532150562894882" border="0" /></a>We specify the version of p2.user.ui that we are patching (here the one shipped in 3.5RC4). In the feature patch, include org.eclipse.equinox.p2.touchpoint.eclipse with the specific version containing the fix. Then, add the feature patch as an inclusion in our org.example.feature:<br /><pre name="code" class="xml:nocontrols:nogutter"><br /><feature id="org.example.feature" label="Feature" version="1.0.0.qualifier"><br /> <includes id="org.example.patch" version="0.0.0" /> <br /> <plugin id="org.example.plugin" version="0.0.0" unpack="false"/><br /></feature><br /><br /><feature id="org.example.patch" label="Patch" version="1.0.0"><br /> <requires><br /> <import feature="org.eclipse.equinox.p2.user.ui" version="1.1.0.v20090605-1440-7u6Fb3FbPbJP5MiKiZgpdl" patch="true"/><br /> </requires><br /> <plugin id="org.eclipse.equinox.p2.touchpoint.eclipse" version="1.0.101.v20090611" unpack="false"/><br /></feature><br /></pre><br /><br />If we have the bundle containing the fix in our target platform, we can now export a new version of our example feature that includes it. And we can update the platform where our feature is installed to get the new version that brings the patch with it.<br /><br />The metadata for the Patch installable unit looks like this:<br /><pre name="code" class="xml:nocontrols:nogutter"><br /><unit id='org.example.patch.feature.group' version='1.0.0' singleton='false'><br /> <patchScope><br /> <scope><br /> <requires size='1'><br /> <required namespace='org.eclipse.equinox.p2.iu' name='org.eclipse.equinox.p2.user.ui.feature.group' range='[1.1.0.v20090605-1440-7u6Fb3FbPbJP5MiKiZgpdl,1.1.0.v20090605-1440-7u6Fb3FbPbJP5MiKiZgpdl]'/><br /> </requires><br /> </scope><br /> </patchScope><br /> <changes><br /> <change><br /> <from><br /> <required namespace='org.eclipse.equinox.p2.iu' name='org.eclipse.equinox.p2.touchpoint.eclipse' range='0.0.0'/><br /> </from><br /> <to><br /> <required namespace='org.eclipse.equinox.p2.iu' name='org.eclipse.equinox.p2.touchpoint.eclipse' range='[1.0.101.v20090611,1.0.101.v20090611]'/><br /> </to><br /> </change><br /> </changes><br />...<br /><requires size='2'><br /> <required namespace='org.eclipse.equinox.p2.iu' name='org.eclipse.equinox.p2.user.ui.feature.group' range='[1.1.0.v20090605-1440-7u6Fb3FbPbJP5MiKiZgpdl,1.1.0.v20090605-1440-7u6Fb3FbPbJP5MiKiZgpdl]' greedy='false'/><br />... <br /></pre><br /><br />This says, in org.eclipse.equinox.p2.user.ui.feature.group version 1.1.0.v20090605-1440-7u6Fb3FbPbJP5MiKiZgpdl, change whatever version of org.eclipse.equinox.p2.touchpoint.eclipse is there to version 1.0.101.v20090611.<br /><h3>It works! Except...</h3>It works, except that we notice that the patch IU has hard requirements on the version of the p2.user.ui feature. This would prevent upgrading the underlying platform because the feature patch has locked down the version of the p2.user.ui feature.<br /><br />p2 is much more flexible about patches than the old Update manager was, so there are a few different ways to address this, and I will write another post covering this soon. <br /><span style="font-size:85%;"><br />(Right now its Friday after 5pm, and time to go home for the weekend :) )</span>Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com0tag:blogger.com,1999:blog-25095519.post-39957754260902691922009-03-26T15:37:00.003-05:002013-07-03T14:41:15.239-05:00Building p2 RCP products in Eclipse 3.5M6We can also call this "Building for the Cloud" just to take advantage of the newest buzz word.<br />
<br />
<a href="http://wiki.eclipse.org/User:Susan_franklin.us.ibm.com">Susan Franklin McCourt</a> put together a nice <a href="http://wiki.eclipse.org/Equinox/p2/Adding_Self-Update_to_an_RCP_Application">wiki page</a> covering how to add p2 self-updating support to your RCP application. One of those examples was called <a hef="http://wiki.eclipse.org/Equinox/p2/Adding_Self-Update_to_an_RCP_Application#Updating_from_the_Cloud" href="http://www.blogger.com/null">"Updating from the Cloud"</a>.<br />
<br />
As part of preparing for EclipseCon, I put together a simple releng product build that builds this cloud product for p2. The cloud bundle "<tt>org.eclipse.equinox.p2.examples.rcp.cloud</tt>" is available in <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.equinox/p2/examples/?root=RT_Project">CVS</a> together with a releng project that I created.<br />
<br />
[Edit 2013/07/03: Eclipse CVS has migrated to git starting in 2010. The examples are now available under the examples folder in <a href="http://git.eclipse.org/c/pde/eclipse.pde.build.git/" rel="nofollow" target="_blank">http://git.eclipse.org/gitroot/pde/eclipse.pde.build.git</a>. The example has not been updated to work with git and has an obsolete CVS entry in the .map file.]<br />
<br />
To run this example, check both projects out into your workspace, and read the rcp.cloud.releng/readme.txt.<br />
<br />
<h3>
Builder Setup</h3>
The releng project serves at the builder for a headless build. The build.properties file is a copy of the template provided by PDE/Build with some things we don't need removed. We modified the following properties:<br />
<ul>
<li><span style="font-weight: bold;">product</span> : This defines the .product file which specifies how to create the cloud product. The first segment of this path is the plug-in id for the cloud project that contains the file.</li>
<li><span style="font-weight: bold;">configs</span> : Here we define the platforms we are building for. This is currently set to build windows, other platforms can be added. (The default here is *,*,* which is platform independent pieces, which doesn't make sense for a product).</li>
<li><span style="font-weight: bold;">J2SE-1.5</span> : The cloud project has a Bundle-RequiredExecutionEnvironment of 1.5. We set this property to be the bootclasspath to use for compiling 1.5. See the <a href="http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.pde.doc.user/tasks/pde_compilation_env.htm">eclipse help</a> for more details on these properties. We also set <span style="font-weight: bold;">CDC-1.1/Foundation-1.1</span> because we had the org.eclipse.osgi bundle in our workspace (and so were compiling it for the product) and osgi requires that EE defined in order to compile properly.</li>
<li><span style="font-weight: bold;">p2.gathering</span> : We set this to true to use the new support for publishing metadata directly from source. This will also automatically install the product using the p2 director. More details on this below.</li>
<li><span style="font-weight: bold;">p2.metadata.repo</span>, <span style="font-weight: bold;">p2.artifact.repo</span> : In addition to the installed product, we also want a p2 repository.</li>
</ul>
<br />
We also provide a simple ant script named "buildProduct.xml". This is a very simple script that does the following:<br />
<ol>
<li>Set the <span style="font-weight: bold;">baseLocation</span>. This is the location of your target binaries against which you want to compile. In the script we set it to ${eclipse.home} which is a property that is automatically set to be the eclipse that is running the build.</li>
<li>Find the <span style="font-weight: bold;">delta pack</span>. The delta pack is required for headless product builds because it contains all the platform specific fragments, and org.eclipse.equinox.executable feature which contains launchers for all the platforms. Download the 3.5M6 deltapack from <a href="http://download.eclipse.org/eclipse/downloads/drops/S-3.5M6-200903130100/download.php?dropFile=eclipse-3.5M6-delta-pack.zip">here</a>. The deltapack location will be added to the pluginPath property.</li>
<li><span style="font-weight: bold;">builder</span> : the location of the build configuration files (ie: build.properties). We set it to be the directory containing the buildProduct.xml script.</li>
<li><span style="font-weight: bold;">buildDirectory</span>: the directory where everything happens, set it to a subfolder of our builder.</li>
<li><span style="font-weight: bold;">pluginPath</span>: the location to find more plugins and features. Here we add the workspace (one level up from the builder), and the deltapack.</li>
<li><span style="font-weight: bold;">Run the build</span>. The property ${eclipse.pdebuild.scripts} is automatically set to the location of the PDE/Build scripts directory. Here we call the <a href="http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.pde.doc.user/tasks/pde_compilation_env.htm">product build</a>.</li>
<li><span style="font-weight: bold;">Victory!</span> : copy the resulting archive into the root of the releng product.</li>
</ol>
The results of this build is a fully provisioned, p2 enabled product with an accompanying repository.<br />
<br />
<br />
<h3>
p2.gathering</h3>
In 3.4, p2 metadata was generated by running the metadata generator on the binary jars that were the result of the build. At the end of the build you were left with a repository and you need to perform a director install for get a fully p2-enabled product.<br />
<br />
In 3.5 we have this new property p2.gathering. Setting this to true does a couple of things:<br />
<ul>
<li>Generate metadata from source. PDE/Build extends the p2 publisher to publish metadata and artifacts directly from source (and the compiled .class files) into a repository. There are no intermediate steps. (This also has the side effect of increased performance).</li>
<li>Feature Builds result in a repository that is a group of all the platforms that were built. (This is an implicit groupConfigurations=true).</li>
<li>Product Builds result in a fully installed p2 enabled product. This removes the need for a manual director call after the build is complete. The product build can also create a repository containing the IUs required to install the product.</li>
</ul>
The 3.4 properties still work for doing the old style generation.Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com12tag:blogger.com,1999:blog-25095519.post-81418870281265061862009-02-25T09:30:00.009-05:002009-03-01T20:00:32.378-05:00Installing and running plugins in Eclipse applicationsA common question on the newsgroups is: "I copied new plug-ins into my RCP application but they are getting ignored, what's the problem?". The answer to this is really quite fundamental and is something I think every RCP developer should understand.<br /><br />My answer here is about the <a href="http://www.eclipse.org/equinox/">Equinox runtime</a> which is used in Eclipse and is the reference implementation of the <a href="http://www.osgi.org/Specifications/HomePage?section=2#Release4">OSGi spec</a>.<br /><br /><h3>Installing into the OSGi Runtime</h3>Every plug-in (or bundle, I use the terms interchangeably), must be installed into the OSGi runtime before you can even think about it running. There are two main ways to install a bundle: programmatically through the <a href="http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/runtime_model_bundles.htm">BundleContext API</a>, or declaratively through the <tt>osgi.bundles</tt> property in the config.ini file.<br /><br />The <tt>osgi.bundles</tt> property is read at startup. It is a list of bundles that are automatically installed and optionally started once the framework is up and running. The format of each entry is<br /><pre><URL | simple bundle location>[@ [<start-level>] [":start"]]<br /></pre><h4>Starting your bundles</h4>It is not enough to simply have your plug-in installed, it must also be started. When the OSGi framework starts up, it increments through the start levels starting bundles as it goes. A bundle won't be started until its start level is reached, and to get started it must be marked as such, or be marked as <a href="http://wiki.eclipse.org/Lazy_Start_Bundles">lazy start</a>. A lazy start bundle will be started when something tries to load a class from that bundle (and once the start level has been reached for that bundle).<br /><br />[Edit:] In most cases, marking a bundle as Lazy-Start is sufficient and one need not worry about starting bundles explicitly. See Neil's comment attached to this post.<br /><br />The default start level for bundles is 4.<br /><br /><h3>Managing installed bundles</h3><br />There are 2 strategies here, one is to list all of your bundles on the <tt>osgi.bundles</tt> list, the other is to list only a few bundles that can bootstrap the rest of the application. I will call this kind of bootstrap bundle a "configurator".<br /><br />If you list all your plug-ins on the <tt>osgi.bundles</tt> property, then it can be painful to maintain and add new plug-ins to your application. I won't try to make arguments for or against any particular way of managing your system, but it a large way it often comes back to the differences between the old update manager and the new p2 provisioning system.<br /><h4>Update Configurator</h4><br />In Eclipse 3.3 and earlier, there was the update configurator (org.eclipse.update.configurator). It was installed on the osgi.bundles list and started at level 3. It would scan the plugins directory and automatically install everything it found there.<br /><br />This is where the magic ability to just copy things into the plugins directory and have them work came from. However, update configurator is essentially forcing the found bundles into the framework with no regard to any conflicts or unresolved dependencies that may result.<br /><br /><h4>Simple Configurator</h4>In Eclipse 3.4, with the advent of p2, update configurator is replace with simple configurator (org.eclipse.equinox.simpleconfigurator). As the name suggests, it is quite simple: it installs everything it finds listed in its configuration file (specified by the <tt>org.eclipse.equinox.simpleconfigurator.configUrl</tt> property, usually bundles.info).<br /><br />Editing the bundles.info file to add plug-ins to your product is not really any easier than editing the osgi.bundles list. The difference here is that p2 manages bundles.info for you. In fact, if your product is p2 enabled for updating and installing plug-ins, then any changes made manually are likely to be lost when p2 updates or installs new software.<br /><br /><h4>Dropins</h4>Whatever the other problems update has with respect to avoiding conflicts and ensuring that dependencies are satisfied, it is hard to ignore the simplicity of just copying new bundles into your install. p2 has support for <a href="http://wiki.eclipse.org/Equinox_p2_Getting_Started#Dropins">dropins</a> (provided by org.eclipse.equinox.p2.reconciler.dropins).<br /><br />Like the update configurator, the dropins reconciler will automatically watch a directory and install things it finds there. However, unlike the update configurator, it will ensure that the bundles found will not conflict with others in the system and that all dependencies are satisfied.Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com6tag:blogger.com,1999:blog-25095519.post-45678979568553189872008-10-28T16:39:00.005-05:002008-10-28T17:06:43.585-05:00Headless build problems with Grouped ConfigurationsPDE/Build has a property named <tt>groupConfigurations</tt>. If you set this property, build will group all the configurations (ie win32,win32,x86 & gtk,linux,x86) into one archive instead of creating a separate archive per configuration.<br /><br /><a href="http://relengofthenerds.blogspot.com/">Kim</a> & I, while working to get the <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=245693">performance baselines</a> going, found a couple of gotchas/bugs around the use of this property.<br /><br /><h4>Unexpected archive format for the group</h4>The first thing we noticed was that the group archive was being created using ant's zip task instead of using the native zip as expected. Our builder's build.properties specified the following:<br /><pre style="margin-left: 1in;">configs = *,*,*<br />archivesFormat = *,*,*-zip<br />groupConfigurations = true<br /></pre>If we had read the <a href="http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.pde.doc.user/tasks/pde_controlling_output.htm">documentation</a>, we would have seen that the archivesFormat is ignored for groups. However, this is not strictly true, and we can instead set a format for the group directly:<br /><pre style="margin-left: 1in;">configs=*,*,*<br />archivesFormat = group,group,group-zip<br />groupConfigurations = true<br /></pre>This results in the zip format as desired.<br /><br /><h4>The directory group.group.group does not exist</h4>We also ran into the following error:<br /><pre>/builds/src/assemble.org.eclipse.sdk.tests.group.group.group.xml:257: The directory<br />/builds/src/tmp/eclipse/group.group.group does not exist<br /></pre>This turns out to be a rather <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=127747">old bug</a>. The problem is that when features gather together the rootfiles they contribute, they copy them into platform specific folders. In this case, building the <tt>*,*,*</tt> configuration, the rootfiles were copied into <tt>tmp/ANY.ANY.ANY</tt>. However, because of the way the grouped configurations feature is implemented, the assembly scripts end up looking for the rootfiles in the <tt>group.group.group</tt> folder.<br /><br />There are a few workarounds to this problem. One is to stick a mkdir in your customTarget/allElements <tt>assemble.<feature-id><feature>.group.group.group</feature></tt> target. This avoids the error, but you don't get the rootfiles in your group archive.<br /><br />If you are using 3.4, then you can use the pre.archive target in customAssembly.xml to collect all the rootfiles into the correct folder:<br /><pre name="code" class="xml:nocontrols:nogutter"> <target name="pre.archive"><br /> <!-- for each config being built --><br /> <move file="${eclipse.base}/ANY.ANY.ANY/${collectingFolder}"<br /> todir="${rootFolder}" failonerror="false"/><br /> <move file="${eclipse.base}/win32.win32.x86/${collectingFolder}"<br /> todir="${rootFolder}" failonerror="false" /><br /> <move file="${eclipse.base}/linux.gtk.x86/${collectingFolder}"<br /> todir="${rootFolder}" failonerror="false" /><br /> </target><br /></pre><br />The <tt>${rootFolder}</tt> property is defined by the caller of the pre.archive target, and in this case will be <tt>${eclipse.base}/group.group.group/${collectingFolder}</tt>.<br /><br /><span style="font-size:85%;">As usual, I have not actually tried running the above ant, the details may be different.</span>Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com0tag:blogger.com,1999:blog-25095519.post-83334220571685023002008-10-15T12:21:00.004-05:002009-01-08T11:18:11.138-05:00Sorting Bundles and Parallel Compilation in PDE/BuildIn PDE/Build the compile order for bundles has always been based on the feature structure. Features are visited depth first, and for each feature the included bundles are sorted according to their dependencies. Dependencies outside the given feature are not considered, and must be included in a previously visited feature.<br /><br />This can lead to some less than ideal feature structures as releng teams try to ensure that everything that a bundle depends on is included in a "deeper" feature.<br /><br />This has been <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=212467">fixed</a> for 3.5 M3. You can now define a property "<tt>flattenDependencies=true</tt>" in your build configuration build.properties file. This will result in bundles being sorted across feature boundaries.<br /><br />Previously, bundles got compiled by delegation through the build.xml scripts for the containing features. When using the new <tt>flattenDependencies</tt> option, a new compilation xml script will be generated in the build directory. This only affects compilation, other build stages (ie gather.bin.parts) will still be delegated through the feature structure.<br /><br /><h3>Parallel Compilation</h3>With the above changes in compile order, it turns out to be a small step to get <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=238177">parallel compilation</a>. Set both <tt>flattenDependencies</tt> and "<tt>parallelCompilation=true</tt>" in your build configuration. The result is that the compilation xml script will then group bundles using ant's <a href="http://ant.apache.org/manual/CoreTasks/parallel.html">parallel task</a>. The result is something that looks something like this:<br /><pre name="code" class="xml:nocontrols:nogutter"><br /><target name="main"><br /> <parallel threadsPerProcessor="3"><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.swt" target="build.jars"/><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.swt.win32.win32.x86" target="build.jars"/><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.osgi" target="build.jars"/><br /> </parallel><br /> <br /> <parallel threadsPerProcessor="3"><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.osgi.util" target="build.jars"/><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.equinox.transforms.xslt" target="build.jars"/><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.equinox.supplement" target="build.jars"/><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.equinox.simpleconfigurator" target="build.jars"/><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.equinox.p2.jarprocessor" target="build.jars"/><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.equinox.launcher" target="build.jars"/><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.equinox.launcher.win32.win32.x86" target="build.jars"/><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.equinox.common" target="build.jars"/><br /> </parallel><br /> <br /> <parallel threadsPerProcessor="3"><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.update.configurator" target="build.jars"/><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.equinox.frameworkadmin" target="build.jars"/><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.cvs" target="build.jars"/><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.core.runtime.compatibility.auth" target="build.jars"/><br /> <ant antfile="build.xml" dir="plugins/org.eclipse.core.jobs" target="build.jars"/><br /> </parallel><br />....<br /></pre><br />Each group depends only only bundles that appeared in a previous group. You can control the ant threading attributes by setting <tt>parallelThreadCount</tt> and <tt>parallelThreadsPerProcessor</tt>.<br /><br />We <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=249868">tested</a> this by using it to compile the Eclipse SDK. Compile time dropped from 6:53 to 4:54, while this is only a 2 minute savings, it is a 29% improvement.Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com4tag:blogger.com,1999:blog-25095519.post-15058382754691994252008-09-26T15:05:00.008-05:002010-07-14T13:19:11.340-05:00Custom Compiler Arguments in PDE/Build[Edit 2010/07/14: As of the Helios release, PDE/Build now supports per bundle custom compiler arguments using "compilerArg" in the bundle's build.propeties file.]<br /><br />The other day there was a <a href="http://dev.eclipse.org/mhonarc/newsLists/news.eclipse.platform.pde/msg00485.html">post </a>to the eclipse.platform.pde newsgroup asking how to include debug information for classes compiled with PDE/Build. The answer is to use the <tt><a href="http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.pde.doc.user/reference/pde_builder_config.htm">compilerArg</a></tt> property.<br /><br />This property sets compiler arguments to use when compiling all your bundles. This got me wondering: What if I wanted to set custom compiler arguments for just one bundle, or if different bundles needed different arguments?<br /><br />There is no explicit support in PDE/Build to do this, but a little digging shows the way!<br /><h3>The Generated Compilation Target<br /></h3>First, take a look at the javac task in the generated build.xml for a bundle. For a typical jar shaped bundle, it looks something like this:<br /><pre name="code" class="xml:nocontrols:nogutter"><javac destdir="${temp.folder}/@dot.bin" [...]><br /> <compilerarg line="${compilerArg}" compiler="${build.compiler}"/><br /> <classpath refid="@dot.classpath" /><br /> <src path="src/" /><br /> <compilerarg value="@${basedir}/javaCompiler...args"<br /> compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/><br /> <compilerarg line="-log '${temp.folder}/@dot.bin${logExtension}'"<br /> compiler="org.eclipse.jdt.core.JDTCompilerAdapter"/><br /></javac><br /></pre>Notice the first <tt><compilerarg/></tt>, it is passing the <tt>${compilerArg}</tt> property that will affect all bundles. More importantly, notice the second <tt><compilerarg/></tt> whose value starts with '@'. A quick peek at the <a href="http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.jdt.doc.isv/guide/jdt_api_compile.htm">jdt docs</a> reveals that this specifies a file where more command line arguments will be read.<br /><br /><h3>javaCompiler.<library>.args</h3>For each library specified in the bundle's build.properties file, PDE/Build generates a corresponding <tt>javaCompiler.<library>.args</tt> file. For most jar shaped bundles, this will be "<tt>javaCompiler...args</tt>".<br /><br />We use this file to pass access rules (and custom file encodings) to the compiler. Access rules tell the compiler which packages you are allowed to see for each classpath entry; this is what allows PDE/Build to ensure that your compile-time classpath is as close as possible to the OSGi runtime classpath. The actual <tt>#ADAPTER#ACCESS#</tt> entries in this file are instructions to the JDT compiler adapter to modify the classpath with the given access rules.<br /><br />The contents of this file are too ugly to bother pasting here, but the point is that this file is just additional compiler arguments. We can append to this file and insert whichever arguments we like.<br /><br /><h3>Appending to the arguments file<br /></h3>We can use <a href="http://help.eclipse.org/ganymede/index.jsp?topic=/org.eclipse.pde.doc.user/tasks/pde_custom_callbacks.htm">custom callbacks</a> to append to the arguments file. For each library being compiled we can specify a target that will be called just before compilation. Here it is simple to append whatever we like to the arguments file:<br /><pre name="code" class="xml:nocontrols:nogutter"><target name="pre.@dot"><br /> <concat append="true" destfile="${basedir}/javaCompiler...args"><br />-g<br />-preserveAllLocals<br /> </concat><br /></target><br /></pre><br /><br /><br />I haven't actually tried this for myself, so you may need to twiddle with the details a little. Note also that because the <tt><compilerarg/></tt> entries have<br /><div style="text-align: center;"><tt>compiler="org.eclipse.jdt.core.JDTCompilerAdapter"</tt><br /></div>this will only work with the JDT compiler.Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com0tag:blogger.com,1999:blog-25095519.post-715927916781119412008-06-18T14:37:00.001-05:002008-09-17T12:24:48.905-05:00Example Headless build for a RCP product with p2*UPDATE* For best results, I would suggest using the upcoming 3.4.1 release. Candidate builds are available from <a href="http://download.eclipse.org/eclipse/downloads/">the download page</a> under "3.4.1 Stream Builds", RC3 is available now.<br /><br />I have prepared an example build setup that builds the RCP Mail Template and produces a p2-ized product. All the files needed for this are provided <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=237537">HERE</a>.<br /><br />The first step is to set up Eclipse with the RCP Delta pack which is required for the headless build of RCP products:<br /><ol><li>Get the Eclipse SDK and the RCP Delta pack and unzip into the same location on disk. </li><li>Start Eclipse and go to Window -> Preferences -> Plug-in Development -> Target Platform.</li><li>Uncheck the option "Build target platform based on the target's installed plug-ins."</li></ol>Create a new plug-in "com.acme.rcp" based on the RCP Mail Template. Create a new Product Configuration file "acme.product" for this plug-in. On the overview tab of the product editor, I set the id "com.acme.rcp.product" and the application "com.acme.rcp.application". I also set the version to be "1.0.0.qualifier".<br /><br />The p2 Installable Unit (IU) that will be created for this product will take its id and version from the product id and version set here. I am setting the version to end in "qualifier" so that I can replace the qualifier at build time with the build id.<br /><br />The product configuration for this example is based on plug-ins. On the configuration tab remove all plug-ins, add the plug-ins listed below and click <b>Add Required Plug-ins</b>.<br /><ul><li>com.acme.rcp</li><li>org.eclipse.equinox.p2.exemplarysetup</li><li>org.eclipse.equinox.p2.ui.sdk</li><li>org.eclipse.equinox.p2.touchpoint.eclipse</li><li>org.eclipse.equinox.p2.touchpoint.natives</li><li>org.eclipse.ecf.filetransfer</li><li>org.eclipse.ecf.provider.filetransfer<br /></li></ul>The product can now be run from overview tab of the product editor. If you do so you will notice the Help -> Software Updates... menu item. Selecting Software Updates at this time gets you a "This installation has not been configured properly for Software Updates" message.<br /><br /><h2>Setting up the headless build</h2>I like to run the headless build from inside Eclipse using a launch configuration. To do this, first import (Import... -> Plug-in Development -> Plug-ins and Fragments) "org.eclipse.pde.build" from the target platform into your workspace as a binary project.<br /><br />Next, create a new general project named "Builder" and copy<br /><pre>org.eclipse.pde.build/templates/headless-build/build.properties"<br /> /customTargets.xml"<br /></pre>into the builder project.<br /><br />I want my headless build to do 3 things differently from a normal build:<br /><ol><li>Set the version number in the product file to match the build id.</li><li>Generate p2 metadata</li><li>Use the generated metadata to perform p2 installs to get the final archives</li></ol><h3>1: Set the version number in the product file.</h3>See the Build/customTargets.xml/preSetup target. We copy the "acme.product" file out of the com.acme.rcp bundle and into our buildDirectory. We then use the ant replace task to replace the version qualifier based on the time stamp. This uses a "acmePlugin" property which we will define separately. We also save the time stamp to a properties file that we read later when calling the p2 director.<br /><h3>2: Generate p2 metadata</h3>PDE/Build provides integration with p2 to automatically generate p2 metadata. See Builder/build.properties where the following properties have been set:<br /><pre> generate.p2.metadata = true<br />p2.metadata.repo=file:${buildDirectory}/repo<br />p2.artifact.repo=file:${buildDirectory}/repo<br />p2.flavor=tooling<br />p2.publish.artifacts=true<br /></pre><h3>3: Perform p2 installs and archive the results</h3>We do this in the Builder/customTargets.xml/postBuild target. We exec a new instance of eclipse to run the director application to install the product into a temporary directory and then we zip up the results.<br /><br />We are running the same eclipse install again to do this. This means that any repositories that the eclipse install is set up with will also be considered during the director call (in addition to the repositories we pass on the command line).<br /><h3>The rest: build.properties</h3>There are a few other properties to set in the build.properties file. We also set a number of properties on the command line in the launch configuration.<br /><br />In the build.properties we set the product property to be the one that has the modified version qualifier. We also set the configuration we are building for.<br /><pre> product=${buildDirectory}/acme.product<br />configs=win32,win32,x86<br /></pre>On the command line we are setting:<ul><li><tt>pluginPath</tt>: allows us to not copy the com.acme.rcp plugin into the buildDirectory.</li><li><tt>buildDirectory</tt>: where all scripts will be generated and the location of our modified acme.product file.</li><li><tt>baseLocation</tt>: We use the eclipse install we are running as our base.</li><li><tt>acmePlugin</tt>: Define the location of the acme plugin for our custom task.</li></ul>All these properties are set in the provided "Build Acme Product.launch" launch configuration and values are set at launch time using variables.<br /><br /><h3>Results</h3>Go to the Run Configurations... dialog and run the "Build Acme Product" launch config. The resulting zip should be under Builder/result. The project may need to be refreshed to see the results.<br /><br />Running the build multiple times will result in the repository containing multiple versions of the product. You can then use that repository to update the product from one version to the next.<br /><br /><h2>Problems Encountered</h2>I did encounter some problems while creating this example.<br /><ul><li><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=237662">Bug 237662</a>: The metadata generator currently does not properly handle the new p2 simpleconfigurator style of config.ini and loses some start level information. This causes the installed product to not start. Workaround for this example is to not include org.eclipse.equinox.simpleconfigurator in the product. I will provide another example later to work around this problem.</li><br /><li><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=222969">Bug 222969</a>: When including the org.eclipse.equinox.simpleconfigurator bundle in the product, the install is getting a bad relative path in the config.ini. Since we are excluding the simpleconfigurator because of the previous bug, this doesn't affect our example.</li><br /><li><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=237647">Bug 237647</a>: NullPointerException in the director. This only occured once, workaround was simply to remove the bad profile directory under my eclipse install (eclipse/p2/org.eclipse.equinox.p2.engine/profileRegistry/ACMEProfile.profile)</li><br /></ul>Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com25tag:blogger.com,1999:blog-25095519.post-40138723476710343982008-05-28T14:59:00.006-05:002008-06-18T13:24:32.896-05:00Doc Time (with a little help from p2)It is that time of year again: documentation time. Irrespective of any personal feeling towards writing documentation, I do realize that it is quite important for something like PDE/Build.<br /><br />I will start with the eclipse help itself and then perhaps write some blog posts with small examples and how-tos. I may even take a look at the venerable <a href="http://www.eclipse.org/articles/Article-PDE-Automation/automation.html">Build and Test Automation</a> article. It was written for 3.0, now that we are hitting 3.4 I'm sure it could use an update.<br /><br />And a little p2 plug: <br />I used to use mozilla to write the html help docs, but I decided I'd like to stay within Eclipse. I'm sure there has to be a decent html editor somewhere in <a href="http://www.eclipse.org/downloads/packages/">Ganymede</a>.<br /><br />So, to the Software Updates dialog, I add the Ganymede update site (http://download.eclipse.org/releases/ganymede/). "Web and Java EE Development -> WTP Web Page Editor" looks promising. I click the checky box and install. p2 downloaded a bunch of stuff, and after a restart, voila! : A webpage editor, easy as pie.Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com0tag:blogger.com,1999:blog-25095519.post-70548330934604069262008-01-23T11:57:00.000-05:002008-01-28T18:42:00.249-05:00Examples of using PDE/BuildIt can be very useful to have an example when setting up your first headless build. It occurs to me that there is a growing number of relatively simple examples: the pde.build junit tests.<br /><br />The org.eclipse.pde.build.tests project can be checked out of cvs from dev.eclipse.org/cvsroot/eclipse/org.eclipse.pde.build.tests. The main test suite is PDEBuildTestSuite.<br /><br />If you run the tests with the vm argument pde.build.noCleanup=true then the tests will run without deleting any files and you can then go take a look at the setup for each test.<br /><br />Not every test is a full build, but many are. Generally the tests consist of generating some features and plugins, then generating the build.properties and allElements.xml configuration files and then running the build.<br /><br />Of particular interest would be the generation of the build.properties file. This is done by loading the template file and then setting just a handful of the properties. See BuildConfiguration.getBuilderProperties(IFolder). This should give a good idea of what properties you need to change for your build.<br /><br />*Edit 1/28/08 : The "pde.build.noCleanup" argument was added on 1/23/08, you must use a build N20080124-0010 or newer. The first I-Build containing these changes will be I20080129.Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com1tag:blogger.com,1999:blog-25095519.post-8074766945521002222008-01-18T18:04:00.001-05:002008-01-18T18:46:42.832-05:00On Building CyclesOne of the enhancements I am considering for pde.build in 3.4 is partial handling of cycles.<br /><br />The latest idea is allowing a cycle that contains at least one binary bundle. The presence of the binary bundle could be enough to break the cycle and allow us to compile the remaining bundles.<br /><br />Consider the following:<br /><pre><br /> A <- B <- C <- D <- E<br /> ----------^<br /></pre><br /><br />Where we have a cycle between B, C, and D. If C is binary and does not need to be compiled, we may be able to compile the remaining bundles in the order A, D, B, E.<br /><br />However, there are cases where this would not work. It could be that allowing this wouldn't actually help and would simply be giving people rope to hang themselves with.<br /><br />If you have an opinion on this, please go comment on the <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=208011">bug</a> and give the patches there a try.Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com0tag:blogger.com,1999:blog-25095519.post-22185816371253143032007-10-04T09:10:00.000-05:002007-10-04T09:41:55.792-05:00Selecting Plug-in Versions in a Headless Product BuildAs <a href="http://lenettoyeur-on-eclipse.blogspot.com/">Pascal</a> likes to say: "PDE.Build is an onion." Don't be afraid to reach in and savor those inner layers. Here is an example:<br /><br />We support building from a .product file. Generally, people base their product files on a list of plug-ins. There is currently no way to specify plug-in versions in the product file. If you have a requirement on a specific version of some bundle and for some reason there are multiple versions in your target, then you may be stuck with pde.build choosing the wrong version for you.<br /><br />In a product build, a container feature is generated based on the contents of the .product file and the build is run using this generated feature. Features can specify the versions of the plug-ins they want to include, or they can specify "0.0.0" which means any version. They can also specify a version like "3.2.1.qualifier" which means any version starting with "3.2.1". (Though beware of <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=203270">this bug</a>). The generated feature simply specifies "0.0.0" for each plug-in from the .product file.<br /><br />PDE.Build provides an eclipse.idReplacer ant task. It uses this task to replace versions in the feature.xml with the actual versions that are built. It is easy to imagine using this task to modify the generated feature.xml to specify the plug-in versions you want before fetching or generating scripts.<br /><br />In your customTarges.xml preFetch (or preGenerate) task, do something like this:<br /><pre><br /> <eclipse.idReplacer<br /> featureFilePath="${buildDirectory}/features/org.eclipse.pde.build.container.feature/feature.xml"<br /> selfVersion="1.0.0"<br /> featureIds=""<br /> pluginIds="org.eclipse.foo:0.0.0,1.3.0.qualifier,org.bar:0.0.0,3.2.0.qualifier," /><br /></pre>Beware of <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=198536">this bug in 3.3.0</a>, and <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=205230">this bug in 3.3.1</a>.Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com3tag:blogger.com,1999:blog-25095519.post-26154723501375417382007-09-13T21:37:00.000-05:002007-09-13T22:25:24.096-05:00Eclipse launcher is losing its headThe Eclipse launcher has always required a graphics library (ie GTK, Motif) to show error messages and display the splash screen. It can't even start if the library is not found. This is a problem for people who have headless Eclipse applications that run in places without such luxuries.<br /><br />I raised a <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=201414">bug</a> to track this issue. Though I should point out that bug is incorrect in its description of the launcher's linking: the launcher <span style="font-weight: bold;">is</span> <a href="http://en.wikipedia.org/wiki/Library_%28computer_science%29#Dynamic_linking">dynamically linked</a> to the graphics libraries, (not statically linked as the bug says). The problem is that these dependencies are resolved at <a href="http://en.wikipedia.org/wiki/Loadtime">loadtime</a>, not runtime. The fix is to load the graphics libraries at runtime using dlopen and lookup all the functions we need to call using dlsym.<br /><br />I have created launchers for GTK and Motif that do this and <a href="https://bugs.eclipse.org/bugs/attachment.cgi?id=78349">attached</a> them in bugzilla. These changes require more testing before I release them to CVS. People should try them out and give feedback on the bug.<br /><br /><br />One thing to note is that the Motif version is using a DT_RPATH tag to help find the libXm.so.2 library that ships on linux in the root of Eclipse. Most of what I've read suggests this is obsolete and not a good idea, so that will probably change.Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com0tag:blogger.com,1999:blog-25095519.post-5269920159438300792007-08-23T12:17:00.000-05:002007-09-07T10:06:53.727-05:00PDE Build Slides from EclipseCon 2007The slides we (Sonia Dimitrov, Pascal Rapicault, and myself) presented at <a href="http://www.eclipsecon.org/2007/index.php?page=sub/&id=3635">EclipseCon 2007</a> are now posted online. We're only about 6 months late putting them up.<br /><br />They are attached to the <a href="http://eclipsezilla.eclipsecon.org/show_bug.cgi?id=3635">Eclipsezilla</a> entry for the tutorial. If you want to run the examples, you will need the Eclipse SDK and the RCP delta-pack. The examples were tested against an old integration build which is no longer available, but using 3.3 should work just fine.Anonymoushttp://www.blogger.com/profile/10918930759740557341noreply@blogger.com2