Thursday, February 23, 2012

Creating a headless application

There are times when you might want to run your RCP application in headless mode. While this is typically not the default mode for applications it might still be useful as an alternative launch option. Eclipse comes with a wizard for this. let' see how it works.

Source code for this tutorial is available on github as a single zip archive, as a Team Project Set or you can browse the files online. 


Step 1: Create the Application

Create a new Plug-in Project called com.codeandme.headless. Eclipse allows to register applications, classes that implement IApplication. At startup eclipse allows to launch exactly one of these classes which is the main entry point to your application.

Lets build such an application: first lets create the extension point for it.
Therefore open the MANIFEST.MF file and switch to the Extensions tab. Add a new org.eclipse.core.runtime.applications extension. Create a new run subnode and set the class name to com.codeandme.headless.Application. The ID of our application will be comprised of the plugin name followed by the ID of the root node of the extension. So lets set the ID to application. The final plugin.xml should look like this:
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>

   <extension
         id="application"
         point="org.eclipse.core.runtime.applications">
      <application
            cardinality="singleton-global"
            thread="main"
            visible="true">
         <run
               class="com.codeandme.headless.Application">
         </run>
      </application>
   </extension>
</plugin>
Clicking on the class link creates the java class:
package com.codeandme.headless;

import java.util.Map;

import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;

/**
 * This class controls all aspects of the application's execution
 */
public class Application implements IApplication {

 @Override
 public Object start(final IApplicationContext context) throws Exception {
  System.out.println("Hello RCP World!");
  final Map<?,?> args = context.getArguments();
  final String[] appArgs = (String[]) args.get("application.args");
  for (final String arg : appArgs) {
   System.out.println(arg);
  }

  return IApplication.EXIT_OK;
 }

 @Override
 public void stop() {
  // nothing to do
 }
}

Instead of a java main() we now have to implement start() and stop(). We are not interested in UI here, so we simply print some messages to the console and finish.

Step 2: A simple test run

Open the Launch Configurations and add a new Eclipse Application launch. On the main tab activate Run an application and select com.codeandme.headless.application. Make sure all required plug-ins are selected and give it a try. You should get some print outputs on the console.


Step 3: Create a Product Configuration

We will create a very basic product configuration here just to get a working runnable.

Select our Plug-in com.codeandme.headless, and select New -> Product Configuration from the context menu. Set the File name to "Headless" and select "Create a configuration file with basic settings".



On the Overview tab find the section Product Definition and hit the New... button on the righthand side of the Product line.

Enter a nice Product Name and a unique Product ID. Make sure the Application is set to com.codeandme.headless.application. The Defining Plug-in needs to be part of your exported RCP, in our case we will simply use com.codeandme.headless for this purpose.


Switch over to the Contents tab and add com.codeandme.headless. Further add the plugin org.eclipse.core.runtime, then select Add Required Plug-ins to automatically resolve all dependencies. Save your Product Configuration and test it by selecting Launch an Eclipse application on the Overview tab. Again you should see the output on the Console view.

Step 4: Exporting the RCP Product

Start the Eclipse Product export wizard from the Overview tab of the Product Configuration. Just select an appropriate destination Directory and let the wizard do the rest. In case you do this multiple times it might help to manually wipe the destination directory before starting a new export.

This way of building products is fine for a test run, if you are interested in a more  professional way of building products, have a look at my tycho tutorials.

Step 5: Running the Application

To run the application just double click eclipse.exe in the destination directory. Still this won't give you any output. So fire up a console and enter

eclipse -application com.codeandme.headless.application -consoleLog -noExit first second last
  • -application
    will tell eclipse which application to start. You might omit this if you want to run the default application you exported. It makes sense for RCPs with multiple applications though.
  • -consoleLog
    opens a dedicated eclipse console and should be well known already.
  • -noExit
    will keep eclipse running even if our application finished. It keeps the console open to examine output 
The other parameters are passed to our application and therefore will be parsed and printed.

7 comments:

  1. thanks. very helpful.

    ReplyDelete
  2. I am using eclipse Luna. it does not have Headless Hello RCP selection. The screen shots are a bit different.
    I tried selecting other options but could not get it to be created. Would you please show the screen shots for Luna?

    ReplyDelete
    Replies
    1. Did not test it on luna. Try to download or browse the example code. Even if the wizards change, the code should run and give you an idea how it works.

      Delete
  3. This tutorial is Well-intentioned but has a lot of holes. First, it's required to add the necesary plugins in order to run. Second, you must configure your application to be headless. Only after that you can export as a product

    ReplyDelete
  4. Is there any way to write the console output to the same shell from where the program is launched? i.e. -consoleLog will open a new command prompt? How can we write to System.out so that it displays the output in the same command prompt instead of displaying in the new prompt?

    ReplyDelete
    Replies
    1. Running eclipsec.exe instead of eclipse.exe should do the trick

      Delete
  5. The simplest working tutorial for creating a headless application. Thanks a lot!

    ReplyDelete