e(fx)clipse and the future of e4 on JavaFX

We’ve been a bit silent in the last few months but the reason is not that our investment in e(fx)clipse has been stopped – it’s the complete opposite. We are involved in HUGE JavaFX projects built on top of e4 and JavaFX.

At EclipseCon Europe I gave a talk on the future direction of e(fx)clipse who is driven by 3 main topics who are going build the Foundation for a bright future of e4 on JavaFX:

  • Freedom of development style
  • Freedom of development tool
  • Freedom of runtime

Freedom of development style

As of today e(fx)clipse e4 development style is called “MANIFEST-first” which means you create your OSGi-MANIFEST and from there

  • Eclipse PDE derives Classpaths, … while you are in your Eclipse IDE
  • Eclipse Tycho derives Build-Paths, … to build applications on your CI-Instance

In future we are going to support other development styles as well:

  • bnd/bnd-tools for those of you who’d like to use what OSGi-gurus like Peter Kriens, Neil Bartlett, … prefer for OSGi-Development, we are already publishing an r5-index since some time. A nice side effect is that bnd support is also available eg in IntelliJ IDEA
  • pom/gradle-first for those of you who’d like to stay with maven/gradle but not all team-members are using Eclipse as their main IDE (or you are not using OSGi as the module system of choice – see more on that below)

Freedom of development tool

Since the first day I’ve spoken about “e4 on JavaFX”, I said that we – the e(fx)clipse project – don’t mind people using other IDEs like Netbeans or IntelliJ IDEA because we are an RCP framework allowing you to built sophisticated applications on top of the brand new Eclipse 4 Application Platform and if you don’t like the Eclipse IDE that’s fine with us.

Yes one part (the smaller one) of the Eclipse-project provides tooling to support developers who’ve chose Eclipse as the IDE, and yes we are an Eclipse project (like Jetty, Vert.x) and Eclipse is our primary development environment but just because it is our IDE of choice this must not mean that it is yours as well.

People already managed to use e(fx)clipse to develop application inside IntelliJ IDEA but in future we’d like to provide all developers an excellent out-of-the-box experience.

Freedom of Runtime-System

As of today you can run e4 applications only on the Eclipse Equinox OSGi-Container. In future we’d like to provide you many more options:

  • Run on ANY r5-OSGi-Container
  • Run without OSGi using NO Module-Container at all
  • Run on Java Platform Module System (JPMS)

Don’t get me wrong! We love OSGi and support for OSGi is still one of the primary targets of e(fx)clipse but we also understand the OSGi might not be the right tool for you and your team.

What’s next

As you might imagine all this is a HUGE amount of work but we (BestSolution.at) are committed to the future e(fx)clipse and we think it is crucial for e(fx)clipse’ future and initial steps have already been made.

Stay tuned for more exciting news in the next few weeks.

Advertisement
Posted in e(fx)clipse, Uncategorized | 4 Comments

Friday fun stuff – JavaFX Based Java IDE

While I’ve been working (and still work) on general IDE concept and frameworks I decided to today that I want to work on something simpler.

After having hacked the whole day I have now a basic Java IDE:

screen-light

screen-dark

Nothing fancy but something I can built upon next Friday … .

Posted in e(fx)clipse, Uncategorized | 5 Comments

e(fx)clipse support for Java9

Approximately a month ago we started to the work to run e(fx)clipse applications on Java9. We had to clean up our codebase a bit because sometimes we called into none-public API (eg impl_*) who has been made private or released as public API, used all sorts of reflection hacks (eg to get Tab-DnD working) who break on Java9 for obvious reasons.

It’s been quite some work but finally things are working!

The screenshot shows an sample e4 application I’ve written to get myself used to the new module-system API:

screen-j9

Supporting Java9 is a critical thing for the future of the e(fx)clipse platform but as important is that we won’t force you to use Java9 with JPMS but keep e(fx)clipse compatible to Java8 and Java9 for the 3.x and maybe 4.x stream.

To help us supporting both platforms we encapsulated API calls who are different in Java8 and Java9 into a small utility class you can make use of in your JavaFX applications just by adding a (maven) dependency on

...
  <repositories>
    <repository>
      <name>BestSolution e(fx)clipse releases</name>
      <id>efxclipse-releases</id>
      <url>http://maven.bestsolution.at/efxclipse-releases/</url>
     </repository>
     <repository>
       <name>BestSolution e(fx)clipse snapshots</name>
       <id>efxclipse-snapshots</id>
       <url>http://maven.bestsolution.at/efxclipse-snapshots/</url>
       <snapshots>
         <enabled>true</enabled>
        </snapshots>
      </repository>
  </repositories>
  <dependencies>
    ...
    <dependency>
      <groupId>at.bestsolution.efxclipse.rt</groupId>
      <artifactId>org.eclipse.fx.ui.controls</artifactId>
      <version>3.0.0-SNAPSHOT</version>
    </dependency>
    ...
  <dependencies>
...

in your Java code add a static import for org.eclipse.fx.ui.controls.JavaFXCompatUtil and if you eg want get all currently available windows just do it like this code snippet

import static org.eclipse.fx.ui.controls.JavaFXCompatUtil.*

// ...

JavaFXCompatUtil.getWindows();

Currently we use Reflection to switch between Java9 and Java8 APIs but in future multi-version jars might also be a solution.

To sum up I’m happy things are working so smooth on Java9, the only sad thing is that our performance hack to turn off the JavaFX-CSS-Engine under certain conditions does not work anymore in Java9 and we won’t be able to implement a replacement.

Posted in e(fx)clipse, Uncategorized | 4 Comments

e(fx)clipse runtime library – Dealing with listeners on JavaFX-Observables

Now that the e(fx)clipse runtime code base is available to any application developer (see this blog post). It is time to explore all the cool stuff it provides for Java(FX) application development.

In the next few weeks I’ll blog about new stuff and old stuff you can make use by just adding a dependency on one of our libraries. I’ll use maven in the samples because that’s what I’m most used to but IIRC things will work for gradle as well.

In this first post I’d like to draw your attention to an Utility-Class (org.eclipse.fx.core.observable.FXObservableUtil) I just checked in a few minutes ago into the repository helping you to write fewer and less error prone code:

FXObservableUtil.onChange for ObservableValue & Property

Let’s take a look at a first code-pattern, I’ve noticed frequently in my JavaFX code-bases:

private StringProperty p = ...;

void attachHandler() {
   p.addListener( this::handle );
}

void detachHandler() {
   p.removeListener( this::handle );
}

void handle(Observable ob, String ol, String ne) {
   System.out.println( ne );
}

The code above has the following problems:

  • I have to declare a method with 3 arguments although I only make use of the new value
  • I have created a huuuge listener leak (Arghhh!)

Let’s improve the situation by using one of our core-libraries org.eclipse.fx.core. Just the following to your maven build:

...
<repositories>
  ...
  <repository>
    <name>BestSolution e(fx)clipse snapshots</name>
    <id>efxclipse-snapshots</id>
    <url>http://maven.bestsolution.at/efxclipse-snapshots/</url>
    <snapshots>
      <enabled>true</enabled>
    </snapshots>
  </repository>
</repositories>
...
<dependencies>
  ...
  <dependency>
    <groupId>at.bestsolution.efxclipse.rt</groupId>
    <artifactId>org.eclipse.fx.core</artifactId>
    <version>3.0.0-SNAPSHOT</version>
  </dependency>
</dependencies>

And now we can change our code using an Utility-Class named org.eclipse.fx.core.observable.FXObservableUtil.

import org.eclipse.fx.core.observable.FXObservableUtil;

private StringProperty p = ...;
private Subscription s;

void attachHandler() {
   s = FXObservableUtil.onChange( p, this::handle );
}

void detachHandler() {
   if( s != null ) {
     s.dispose();
     s = null;
   }
}

void handle(Observable ob, String ol, String ne) {
   System.out.println( ne );
}

But we can improve the code even more because:

  • We can add static imports
  • Instead of using FXObservableUtil#onChange(ObservableValue<T>, ChangeListener<T>) we can use the overloaded method with the signature FXObservableUtil#onChange(ObservableValue<T>, Consumer<T>)
import static org.eclipse.fx.core.observable.FXObservableUtil.*;

private StringProperty p = ...;
private Subscription s;

void attachHandler() {
   s = onChange( p, System.out::println );
}

void detachHandler() {
   if( s != null ) {
     s.dispose();
     s = null;
   }
}

FXObservableUtil.onChange for ObservableList

In general the JavaFX APIs is designed very well to work with @FunctionalInterface types but IMHO there’s one big mistake that has happened when we look at the Observable-API who strikes back in case of ObservableList.

The class hierarchy in JavaFX looks like this:

+ Observable
  - addListener( InvalidationListener listener ) : void
  + ObservableValue
    - addListener( ChangeListener<? super T> listener )
  + ObservableList
    - addListener( ListChangeListener<? super E> listener )

The overloading of addListener() in case of ObservableValue is fine as ChangeListener#changed(ObservableValue<? extends T> , T , T ) requires 3 arguments wherease InvalidationListener#invalidated(Observable) takes only one.

In case of ObservableList unfortunately ListChangeListener#onChanged( Change<? extends E> c) like InvalidationListener#invalidated(Observable) accepts one argument. Because of this it’s impossible to benefit of the automatic type inference done by the compiler to remove boilerplate code for lambda expressions and you need to fill in the correct type in the lambdas argument section:

ObservableList<String> l = ...

l.addListener( (Change<? extends String> c) -> 
  { while( c.next() ) { /* ... */ } } );
// although you really wanted to write
l.addListener( c -> { while( c.next() ) { /* ... */ } } );

To make this usecase less type heavy FXObservableUtil distinguishes between

  • Invalidation: FXObservableUtil.onInvalidate(Observable,InvalidationListener)
  • Change: FXObservableUtil.onChange(ObservableList<E>,ListChangeListener<? super E>)
import static org.eclipse.fx.core.observable.FXObservableUtil.*;

ObservableList<String> l = ...
Subscription s = 
  onChange( l, c -> { while( c.next() ) { /* ... */ } } );
Posted in e(fx)clipse, Uncategorized | 3 Comments

Make it easy to consume e(fx)clipse libraries in maven (or gradle)

In the past we now and then published some of our artifacts on maven central but because this was a manual process we’ve often been too lazy leading to do it on each release. This leads frustration because while we’ve released e(fx)clipse 2.5.0 already, the maven bits are stuck on 2.2.0.

I think not being able to consume our code outside the OSGi world has led to the false impression that e(fx)clipse runtime is just about OSGi although central parts of our framework happily run outside OSGi and so can be used like any other library:

  • We have additional layout containers like RowLayoutPane, FillLayoutPane, GridLayoutPane, SashPane
  • We have additional controls like FileSystemViewers, StyledTextArea, FontIconNode
  • We have a complete code editor framework with syntax highlighting, auto-complete, line/error markers, hover-support, navigation support, …
  • A Service Registry supporting a subset of the OSGi-Declarative-Service Framework outside the OSGi world in plain Java – say good bye to ServiceLoader once you used our service stuff

Solving this problem was at the top of my list for the Q1/2017 and I’m happy to announce that the complete e(fx)clipse runtime target platform is available from a maven-repository starting from today.

We’ve chose to publish the artifacts to one of our own public servers (http://maven.bestsolution.at/) instead of maven-central and there are multiple reasons for that:

  • We need to get confidence that our OSGi-To-Maven-Dependency translation is correct
  • We need to extract more meta-information to publish accurate informations like Developers, SCM-URLs
  • We need to refine how we deal with none Eclipse dependencies like apache-commons, …

It’s a nice coincidence that Stephan Herrmann did the same for the Eclipse Platform, JDT and PDE but there are some differences (today) from what I read on his blog entry (don’t shoot me Stephan if I got it wrong):

  • Stephan uses some CBI-stuff to translate the OSGi-Dependencies to maven pom dependencies, we use a simple helper library to do the same thing
  • Stephan replaces OSS-Dependencies like Apache-Commons through the direct maven substitutions, we are republishing the dependencies as we publish them from the Eclipse Orbit Project or any other Eclipse project.
    The reason is that we want the maven artifact repository to contain 100% the same bits as our p2-update-site and r5-repository. That’s the current state and it might change in future!
Posted in e(fx)clipse | 7 Comments

Making @Service annotation even cleverer

As some of you might know e(fx)clipse provides a Eclipse DI extension supporting more powerful feature when we deal with OSGi-Services:

  • Support for dynamics (eg if a higher-ranked service comes along you get it injected, …)
  • Support for service list
  • ServiceFactory support because the request is made from the correct Bundle

Since tonights build the @Service annotation has support to define:

  • A static compile time defined LDAP-Filter expression
    public class MySQLDIComponent {
      @Inject
      public void setDataSource(
        @Service(filterExpression="(dbtype=mysql)") 
        DataSource ds) {
         // ...
      }
    }
    
    public class H2DIComponent {
      @Inject
      public void setDataSource(
        @Service(filterExpression="(dbtype=h2)") 
        DataSource ds) {
         // ...
      }
    }
    
  • A dynamic LDAP-Filter expression who is calculated at runtime and can change at any time
    public class CurrentDatasource extends BaseValueObservable<String> implements OString {
      @Inject
      public CurrentDatasource(
        @Preference(key="database",defaultValue="h2") String database) {
        super("(dbtype="+database+")");
      }
    
      @Inject
      public void setDatabase(
        @Preference(key="database",defaultValue="h2") String database) {
        setValue("(dbtype="+database+")");
      }
    }
    
    public class DIComponent {
      @Inject
      public void setDataSource(
        @Service(dynamicFilterExpression=CurrentDatasource.class)
        DataSource ds) {
        // ...
      }
    }
    

    You notice the dynamic provider itself if integration fully into the DI-Story 😉

Posted in e(fx)clipse | 1 Comment

Improving Min/Max performance in “e4-on-JavaFX” applications

When it comes to performance in JavaFX one of the biggest problems is that if you detach and reattach a big SceneGraph-Part you run:

  • CSS-Pass
  • Layout-Pass

So in general one should avoid those operations as much as possible but there are situations you can’t get something implemented without doing exactly this kind of thing.

In the current architecture of e(fx)clipse we need to use this reparenting in case of minimizing/maximizing certain areas of your e4-on-JavaFX application which might lead to a very poor user experience if you eg have a MPartStack with many complex substructures (like eg our code editor).

Today we took a closer look for one of our customers to find out if we – the e(fx)clipse – framework can do anything to fix that problem and after some experiments we managed to come up with a solution who allows us to reparent the content of an MPartStack in constant time:

In general I’d say that such optimization should not be required and JavaFX CSS and Layout performance HAS to be improved in general and JavaFX-Components have to get smarter in not running CSS-Passes on SG-Parts who are currently not showing.

Posted in e(fx)clipse, Uncategorized | 4 Comments

New SashLayout container has landed in e(fx)clipse

I just pushed a new layout-container who has a similar feature set than the JavaFX built-in SplitPane but ensures that proportions are not corrupted if you shrink the container (just watch the video below to get an idea what I mean).

The layout algorithm is not something I came up myself. I just reworked the one from SWT to be used in JavaFX.

Posted in e(fx)clipse | 8 Comments

Building e4 JavaFX applications with gitlab-ci and docker

We’ve decided internally sometime ago to use a self-hosted gitlab instance for our projects.

To get started quickly we first only used the ticket-system and keep our jenkins-instance to do our builds which works fine but it somehow bothered me that we’ve been unable to use the gitlab-ci system integrated directly into the gitlab-instance.

So yesterday we started to explore how we can do builds using the docker integration of gitlab-ci and after some troubles with FreeBSD & docker (where our gitlab instance is hosted on) we managed to get a build going.

If you want to do that as well. You can make use of a docker-image we prepared containing:

  • Maven 3.3.x
  • Oracle-JDK-8

(we unfortunately could not use the java-images provided by dockerhub because they ship OpenJDK8 who does not include JavaFX).

So if you run your e4 on JavaFX project as well on gitlab all you need to do is to add a gitlab-ci.yml to your git-repository holding the following content:

image: tomsontom/oracle-java8-mvn:latest

build:
  script: "cd my.project.app.releng; mvn clean package"
Posted in e(fx)clipse | 2 Comments

e(fx)clipse 2.4.0 & Eclipse Neon Builds available

For those who want to get an easy head start into JavaFX development with Eclipse as an IDE BestSolution provides a service many developers make use of (eg in June the IDE got downloaded 4000 times).

We provide All-in-One builds similar to the ones you can grab from Eclipse.org but we bundle even some external libraries for you with it.

We now managed to update the provided IDE to the latest and greatest:

  • Eclipse 4.6.0 SDK
  • e(fx)clipse 2.4.0
  • Xtext 2.10.0
  • EGit 4.4.0
  • WST-XML 3.8.0
  • Subclipse 1.8.20
  • m2e 1.7.0
  • bndtools 3.2.0
  • AnyEditTools 2.6.1
  • Findbugs 3.0.2
  • Eclemma 2.3.3

Finally if you like this an other services (eg. leaving no question at the newsgroup unanswered) BestSolution provides for free think about sponsoring our work.

If you rely on e(fx)clipse for your commercial product we suggest you sign a service and support contract with BestSolution.

Posted in Uncategorized | Leave a comment