CBI or Taking The Pain out of Eclipse Builds

20. July, 2012

When a project is young and dashing, mistakes are made. The PDE build process is such a mistake. If you ever tried to build Eclipse (or at least some of the older parts), then you know that this is brittle and the error messages are more like mysterious ramblings of an angry deity than helpful.

Enter stage CBI. From the FAQ:

 The CBI build of the Eclipse platform is intended to produce the same output as the PDE build, and thus facilitate packaging without noticeable change. The noticeable difference the CBI build of the platform makes is ease of use to build the platform. For example, the prototype has consistently demonstrated that a newcomer without prior experience can build the Eclipse platform with under 30 minutes of effort on a machine with a supported JDK & Maven.

What can I say?

Finally!


Building RCP Apps With OSGi

16. March, 2011

Dave Orme wrote a really interesting article about building blocks of a RCP application with OSGiThe OSGi Building Block Pattern: An Invitation

I agree with him: The RCP wizard should really create projects to build a p2 repo and to package the bundles and features into something that a user can download and install.

Right now one of the major stumbling blocks when starting with Eclipse projects is that they either don’t build at all or that I fail to bundle/package them into some “output.”

The typical situation is that I’ve managed to import the project into my workspace. Now I get a lot of compile errors because bundles are missing in my IDE. Problem: I see the names but I have no idea at all where to download them. (See bug 340014 – “Offer a quick fix to install missing dependencies from p2 repositories”)

After manually googling for bundle names, trying to find the p2 repo which might contain them (in former times, p2 repositories offered a way to quickly browse them with a web browser – that doesn’t work anymore, so it’s poking in the dark). After a couple of restarts, the compile errors are gone.

At long last, I can start to fix my problem.

But now what? How can I create the “thing” that I need? (where “thing” can be a RCP app, a p2 repo, a bundle, a feature). Eclipse doesn’t allow to save the final after-build-step anywhere. Users must remember the steps: Export…, select the correct tool out 500, fill out the 100+ options in the little dialogs that pop up, rinse, repeat.

Welcome bug 340018 – “Allow to save export actions in a “launch” config”


Building Eclipse from Git

16. February, 2011

Andrew Niefer blogs about Building Eclipse from Git. Unfortunately, he doesn’t explain how to do that if you’re not a committer (i.e. have a user on eclipse.org).

I’m still hoping that one day, it will be possible for people outside the Eclipse team, to be able to build Eclipse projects.


Building patches for Eclipse

10. November, 2010

Frustrated by mysterious error messages from PDE? Overwhelmed by Buckminster?

If you need to apply a simple patch to a plug-in for Eclipse, there is a more simple way. Follow this recipe:

  1. Download the source for the plug-in
  2. Create a new project
  3. Add all plug-ins in the eclipse/plugins folder to the build path. Use the variable eclipse_home. This is most simple if you use an ANT build script. If you want to waste time, try to figure out which plugins you need and only add those.
  4. Extract the few Java source files that you need to modify and copy them into your project.
  5. Copy the JARs of plugins you want to patch into your project.
  6. Fix the bugs.
  7. Use a bit of ANT magic to replace the Java classes in the JARs you copied in step #5 with the fixed versions. The trick here is that most Eclipse JARs are signed. You’ll need to remove the cryptographic keys in order to be able to load the JARs. See below for a piece of code that does the trick.
  8. Add a rule to your build.xml to copy the fixed JARs back into the plugins folder of Eclipse.
  9. Exit Eclipse (or start another instance) to test your fixes.

Here is the source to strip the SHA1-Digest keys from a MANIFEST.MF file:

// Needs commons-io 1.4
public class FilterManifest {

    public static void main( String[] args ) {
        try {
            FilterManifest tool = new FilterManifest();
            tool.run( args );
        } catch( Exception e ) {
            e.printStackTrace();
            System.exit( 1 );
        }
    }

    private void run( String[] args ) throws Exception {
        File manifestFile = new File( args[0] );
        Manifest manifest = readManifest( manifestFile );

        manifest.getEntries().clear();

        File backup = new File( manifestFile.getAbsolutePath() + ".bak" );
        if(! manifestFile.renameTo( backup ) ) {
            throw new RuntimeException( "Can't backup file" );
        }

        save( manifest, manifestFile );
    }

    private void save( Manifest manifest, File manifestFile ) throws IOException {
        FileOutputStream stream = new FileOutputStream( manifestFile );
        try {
            manifest.write( stream );
        } finally {
            IOUtils.closeQuietly( stream );
        }
    }

    private Manifest readManifest( File manifestFile ) throws IOException {
        FileInputStream stream = new FileInputStream( manifestFile );
        try {
            return new Manifest( stream );
        } finally {
            IOUtils.closeQuietly( stream );
        }
    }

}

To use this code, use this ANT code:

    <target name="fix-org.eclipse.birt.engine" depends="init">
        <unjar src="plugins/org.eclipse.birt.report.engine_2.6.1.v20100915.jar" dest="tmp">
            <patternset>
                <include name="META-INF/MANIFEST.MF"/>
            </patternset>
        </unjar>
        <java classname="tools.FilterManifest">
            <arg file="tmp/META-INF/MANIFEST.MF"/>
            
            <classpath>
                <pathelement location="target-eclipse/classes" />
                <pathelement location="target/classes" />
                <pathelement location="${m2_repo}/commons-io/commons-io/1.4/commons-io-1.4.jar" />
            </classpath>
        </java>
        <jar destfile="tmp/org.eclipse.birt.report.engine_2.6.1.v20100915.jar"
            compress="true" update="true" duplicate="preserve" index="true"
            manifest="tmp/META-INF/MANIFEST.MF"
        >
            <fileset dir="target-eclipse/classes">
                <include name="org/eclipse/birt/report/engine/**/*" />
            </fileset>
            <zipfileset src="plugins/org.eclipse.birt.report.engine_2.6.1.v20100915.jar">
                <exclude name="META-INF/*"/>
            </zipfileset>
        </jar>
    </target>

The two <pathelement> elements are necessary to make the code work from Eclipse and command line Maven (I’m using different target directories for Eclipse and Maven).

The complex <jar> target allows to copy everything from the existing plugin JAR but the crypto info.


%d bloggers like this: