User Tools

Site Tools


Sidebar

Dave Orme muses about agile and functional programming.

My current work emphasizes SOA applications using Scala, Kubernetes, and AWS with a React-based SPA front-end. I'm also interested in progressive web applications and developer tools.


Blog

Scala, Clojure, and FP

Agile

The Cloud

Data-First Development

Older work

Coconut Palm Software home


Donate Bitcoin:

1Ecnr9vtkC8b9FvmQjQaJ9ZsHB127UzVD6

Keywords:

Kubernetes, Docker, Streaming Data, Spark, Scala, Clojure, OSGi, Karaf, GCP, AWS, SQL

Disclaimer:

Everything I say here is my own opinion and not necessarily that of my employer.

blog:using_scala_to_create_eclipse_rcp_applications

Using Scala to Create Eclipse RCP Applications

There have been previous descriptions of how to use Scala to create an OSGI bundle, how to configure the PDE for building Scala-based plugins, and how Scala integrates very cleanly with Java.

Here, we will describe a pragmatic approach for developing real-world RCP applications using the current Scala and PDE tooling. We will see that if we follow some common-sense coding guidelines that incorporating Scala code into an RCP application is not very different from creating our plug-ins in Java.

Architectural options

If we want to create an Eclipse RCP application using Scala, we have several options:

  • 100% Scala
  • Mixed Scala and Java

If we're a bit clever, we can get the PDE to generate most of the boilerplate code in an RCP application. There is little benefit in rewriting that code in Scala, since the PDE generates it for you anyway and there is no equivalent PDE code generator for Scala.

So until someone invents a DSL for specifying all of this Java boilerplate more easily, we might as well leave it in Java and use the tooling that Eclipse supplies us. I've taken the same attitude regarding tooling plugin.xml and MANIFEST.mf. Eclipse already tools these these things pretty well, so there's no point in repeating it.

What does that leave us to do in Scala? Right now, Scala is ideally suited for simplifying:

  • User interface development
  • Modules that can benefit from greater abstraction or simplification than easily possible in Java.
  • Wrapping JDBC (Note: referenced blog assumes fairly mature Scala knowledge.)
  • Algorithmic code that can benefit from a functional style of expression.

For the purposes of this article, we will create an RCP application with a single View. The RCP application and its main perspective will be in Java. The View's boilerplate will be the standard boilerplate that is generated by the PDE.

We will write the view's actual content as a custom SWT control that is implemented in Scala using a 1:1 translation of the usual Java SWT code into Scala. In the next article, we will show how to use Scala's powerful abstraction abilities to radically simplify this SWT code.

Install the Scala Development Tools

There have been several recent improvements in the Scala tooling so that the steps are a bit simpler and more intuitive. My experience has been that the Scala tools are still pretty immature, but they are starting to be usable now for small-scale production work.

For reference, I am using Eclipse 3.4.1 and Scala Development Tools 2.7.3final.

If you do not have these, you can get Eclipse from your favorite Eclipse mirror. The Scala plugin's update site URL is: http://www.scala-lang.org/scala-eclipse-plugin.

Create the RCP application project

We'll use the PDE wizards to create the base RCP application.

Select “File|New Project|Plug-in Project” from the menu.

Click “Next”.

On the next page, give your project a name and click “Next”. I used: “com.coconut_palm_software.scalarcp”

The following page controls some aspects of the Java code that PDE will generate for you. Make sure that the highlighted options are selected and click “Next”:

Finally, choose the “RCP application with a view” template and click “Finish”.

We now have a basic RCP application. Once the PDE Manifest editor has appeared, you can click “Launch an Eclipse Application” to see it run.

It should look something like this:

The last thing we want to do is to rip out the demo RCP code that we don't need to make a place for our Scala user interface.

Open View.java, and remove all of the TableViewer code so that it reads as follows:

package com.coconut_palm_software.scalarcp;
 
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
 
public class View extends ViewPart {
	public static final String ID = "com.coconut_palm_software.scalarcp.view";
 
	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	public void createPartControl(Composite parent) {
	}
 
	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
	}
}

Running our RCP application will now result in the following:

Create the Scala-based Eclipse Plugin

We now want to use Scala to create a new user interface for this application. First we use the “New Project” wizard to create a new Scala project:

On the next wizard page, we give the project the name “com.coconut_palm_software.scalarcp.view” and click “Finish”.

We now have a Scala project, but we want this project to also be an Eclipse plugin. So we right-click the project and select “PDE Tools|Convert Projects to Plug-in projects”, make sure that our Scala project is selected in the resulting dialog box, and click “OK”.

We're now ready to add a new user interface to our Eclipse RCP application using Scala.

Hello, Scala

First, we need to add the Eclipse and Scala dependencies to our Scala plugin so that the OSGI runtime will be able to find them. Open the MANIFEST.mf editor, switch to the “Dependencies” tab, and add SWT (because we're creating an SWT control) and the Scala library there.

Now let's create a package (just like we would in Java) to hold our class.

Create a package in the Scala project's src folder called “com.coconut_palm_software.scalarcp.view”

Since we have a package, we can now use the “File|New…” wizard to create a shiny new Scala class called “Hello”

The result (for starters) will look rather uninteresting…

package com.coconut_palm_software.scalarcp.view
 
class Hello {
 
}

…so let's make our UI do something. Just to prove that we can easily run a Scala user interface inside our RCP application, we will start by creating a basic “Hello, world” message. Edit the code to read as follows:

package com.coconut_palm_software.scalarcp.view
 
import org.eclipse.swt.SWT
import org.eclipse.swt.widgets._
import org.eclipse.swt.layout.FillLayout
 
class Hello(parent : Composite, style : Int) extends Composite(parent, style) {
  setLayout(new FillLayout())
  new Label(this, SWT.NULL).setText("Hello, Scala.")
}

Here we take advantage of the power of Scala's default constructors. Code that is inside the body of a Scala class is actually placed inside the class's default constructor. The default constructor is the one with the argument list corresponding with the class's argument list.

Since standard SWT classes have a single constructor with a (parent, style) argument list, we can avoid some of Java's boilerplate by making our default constructor correspond with SWT's standard constructor form.

Add our Scala user interface to the RCP application and run it

We now have a user interface written in Scala. We would like this user interface to appear inside our RCP application. The cool thing is that everything else we must do is all standard OSGI programming. None of this is different from what you would do if you wrote the Hello class in Java. For the sake of completeness, we'll list the steps and run through them:

  1. Export the package containing Hello.scala from our OSGI bundle
  2. Import the bundle containing Hello.scala into our RCP application
  3. Instantiate the Hello class inside our Java-based RCP View
  4. Adjust the plug-ins included by the RCP application launcher to include Scala plus our bundle with Hello.scala

Export the package containing Hello.scala

First we must make the package containing the Hello class visible to OSGI bundles that import our UI bundle.

Switch back to the MANIFEST.mf editor, go to the “Runtime” tab, and add the “com.coconut_palm_software.scalarcp.view” package to the list of exported packages:

Import the "MVC View" bundle into our RCP application

Now our original RCP application can import and use the Scala-based class. First, we must open the RCP application's MANIFEST.mf editor and add the new dependency on the Scala bundle:

Use our Scala-based Hello class inside View.java

With the Scala bundle imported into our RCP application, we can now update View.java to use it. Change createPartControl to instantiate a “Hello” object and run the “Organize Imports” function, and you should wind up with the following code:

package com.coconut_palm_software.scalarcp;
 
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
 
import com.coconut_palm_software.scalarcp.view.Hello;
 
public class View extends ViewPart {
	public static final String ID = "com.coconut_palm_software.scalarcp.view";
 
	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	public void createPartControl(Composite parent) {
		parent.setLayout(new FillLayout());
		new Hello(parent, SWT.NULL);
	}
 
	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
	}
}

Notice how Scala classes appear to Java as if they were Java classes?

This is because Scala classes are compiled to Java classes at the bytecode level–using similar bytecode to what would appear if they actually were written in Java. Cool! For more information on this neat Scala feature, see http://www.codecommit.com/blog/java/interop-between-java-and-scala.

Adjust the launcher and run the application

Now we're ready to adjust our RCP application's launcher to include our new Scala-based OSGI bundle and run the application.

Click the little arrow next to the “Run” button on the toolbar, and then select “Run configurations…” from the drop-down menu.

In the “Run Configurations” dialog box, switch to the “Plug-ins” tab. On this tab, click the check box next to the com.coconut_palm_software.scalarcp.view plug-in, click the “Add Required Plug-ins” button, and click the “Run” button to apply all changes and run the application.

After a short pause, you should see your first mixed Scala/Java RCP application running!

Conclusion

In this article, we have seen:

  • How to create an OSGI bundle using the current Scala Development tooling
  • That once we have created a Scala-based OSGI bundle, there is no difference between this bundle and a bundle written in Java, as far as our Java code is concerned
  • That even with the simplest Hello, world example, we are already starting to see a glimmer of Scala's potential to simplify RCP application development.

In the next article, we will show how Scala can be used to radically simplify SWT coding.

~~LINKBACK~~ ~~DISCUSSION:closed~~

blog/using_scala_to_create_eclipse_rcp_applications.txt · Last modified: 2014/10/17 22:08 (external edit)