JVx' vaadinUI supports FontAwesome and VaadinIcons

Post to Twitter

Vaadin has support for FontIcons since release 7.2. The first supported FontIcon was FontAwesome. Vaadin has a nice description in their book.

It's straight forward:

button.setIcon(FontAwesome.SAVE);

Since June 2015 vaadin also supports their own Font Icons: Vaadin Font Icons.

In our JVx' VaadinUI, it wasn't possible to use FontIcons without accessing the real vaadin resource, e.g.

((com.vaadin.ui.Button)button.getResource()).setIcon(FontAwesome.SAVE);

With next release, we'll allow FontAwesome and VaadinIcons out-of-the-box, without accessing the ressource and without manual installation of font icons, because our UI has everything included.

It will be possible to write:

button.setImage(UIImage.getImage("FontAwesome.SAVE"));

or

button.setImage(UIImage.getImage("VaadinIcons.ARROW_CIRCLE_DOWN_O"));

This feature is not official because it's not technology independent, but it's already available in our nightly builds :)

Eclipse MARS with ANT and JRE 6 (story)

Post to Twitter

Eclipse Mars is available since June 25th. We didn't update our IDEs because it wasn't needed.

Some days ago we played around with JavaFXPorts Eclipse plugin. This plugin requires Eclipse Mars. So far so good. We made some tests with Mars, and everything was fine. We installed all required plugins for our internal and customer projects and configured a first workspace....
After everything was done, we tried to work with Eclipse Mars - no problems... BUT we have many projects with Java 6 compatibility.

Why Java 6?

Some big legacy projects/applications and Oracle Forms compatibility. There are more reasons, but it's not unusual to be backwards compatible, especially for frameworks and libraries!

Long story, short: It's not possible to start an ANT task with Java 6, because Java 7 is required. A nice error message appears:

JRE version less than 1.7 is not supported.

BUT it's still possible to choose any JRE in Runtime configuration dialog.
Why shouldn't it be possible to start ANT with "any" JRE?

We tried to find help in the world wide web and found some postings about our problem:

http://stackoverflow.com/questions/31052878/run-eclipse-mars-with-java-1-6
http://stackoverflow.com/questions/31808102/eclipse-mars-ant-doesnt-support-jdk-1-6-anymore

And two bug database entries:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=474386
https://bugs.eclipse.org/bugs/show_bug.cgi?id=461031

It's absolutely incomprehensible why the first ticket is in state: RESOLVED INVALID and the
second one: VERIFIED FIXED.
OK, the second one was for a different requirement, but the first one explains the problem.

Why did the developer ignore the user requirement?

It's possible to call ANT with "any" JRE, without Eclipse and other IDEs don't have such crazy limitations! We didn't plan to use another IDE just for building our software!

I can't live with recommended workarounds because suggested steps were not usuable with big projects!
So, we tried to solve the problem for us. The source code of the ANT plugin is available here, so it shouldn't be a problem to "fix" the problem.

After reading source code, we found that the only reason why it's not possible to use JREs < version 7, is Java 7 Syntax:

  • Diamond operator, e.g. List<MyObject> list = new ArrayList<>();
  • try-with-resources, e.g. try (InputStream stream = createInputStream()) { ...}

And of course, the plugin was configured for execution environment JavaSE-1.7.

Our solution: Removed Java version check in class org.eclipse.ant.internal.launching.launchConfigurations.AntLaunchDelegate, method launch:

//String path = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH, new String("")); //$NON-NLS-1$
//if (!path.isEmpty()) {
//      IPath jrePath = Path.fromPortableString(path);
//      IVMInstall vm = JavaRuntime.getVMInstall(jrePath);
//      if (vm instanceof AbstractVMInstall) {
//              AbstractVMInstall install = (AbstractVMInstall) vm;
//              String vmver = install.getJavaVersion();
//              // versionToJdkLevel only handles 3 char versions = 1.5, 1.6, 1.9, etc
//              if (vmver.length() > 3) {
//                      vmver = vmver.substring(0, 3);
//              }
//              int ver = (int) (CompilerOptions.versionToJdkLevel(vmver) >>> 16);
//              if (ver < ClassFileConstants.MAJOR_VERSION_1_7) {
//                      // IStatus status = new Status(IStatus.ERROR, AntLaunching.PLUGIN_ID, 1,
//                      // AntLaunchConfigurationMessages.AntLaunchDelegate_Launching__0__2, null);
//                      // throw new CoreException(status);
//              }
//      }
//}

We set the execution environment for org.eclipse.ant.launching, org.eclipse.ant.core and org.eclipse.ant.ui to JavaSE-1.6 and made the source code compatible with Java 6 syntax.

After we built the required jar files, we had problems with Eclipse, because there was something like a plugin cache (not sure what exactly). We made a test with -clean command line parameter and were happy. It was possible to start ANT tasks - with JRE 6 - without modifications, directly via Eclipse.

It's not difficult to create your own ANT plugin, but here are our jar files.
The libs were built for

Version: Mars Release (4.5.0)
Build id: 20150621-1200

The tag-id of the ANT plugin source code: I20150430-1445.

Installation?

  • Download the zip archive, extract the content to <eclipse_dir>/plugins.
  • Start eclipse with parameter -clean (only once)
  • Configure JRE6 for your ANT task, via Externals Tool configuration...

Feel free to use our changed files but we don't guarantee that it doesn't destroy your Eclipse Mars installation :)
We didn't have any problems so far, but send us your impressions.

We didn't publish the changed source code right now, but let us know if you need it - it's still under EPL.

JavaFXPorts with Eclipse

Post to Twitter

Some weeks ago, Gluon released the first version of their Eclipse plugin for creating/building mobile applications with Java(FX).

We had some experience with their NetBeans plugin but our preferred IDE was Eclipse. So, an Eclipse plugin was good for us :)
The NetBeans version worked without bigger problems and we expected the same quality for the Eclipse plugin.

We followed the official installation instructions and didn't have any problem. But the problems started after we tried to create Android or iOS specific code. It wasn't possible to access javafxports, android or robovm classes, because the jar files weren't found. The classpath with NetBeans had references to all libraries, but the Eclipse project didn't have such references.

We tried to find some information in the documentation and found the NFC example application. The build file had additional dependencies for android and javafxports. We changed the build file of our Eclipse project:

dependencies {
    compile files("C:/tools/android/android-sdk_r04-windows/platforms/android-21/android.jar")
    compile "org.javafxports:jfxdvk:8u60-b3"
       
    compile fileTree(dir: 'libs', include: '*.jar')
    runtime fileTree(dir: 'libs', include: '*.jar')
}

and after some Gradle/Refresh Dependencies, Refresh All clicks, all Errors were fixed!
It was horrible, because after clicking Refresh Dependencies, nothing happened and after some more clicks, all errors were gone. Not sure if this was a Gradle project problem, or Gluon plugin problem.

Our full build script (without robovm):

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'org.javafxports:jfxmobile-plugin:1.0.1'

    }
}

apply plugin: 'org.javafxports.jfxmobile'

repositories {
    jcenter()
}

dependencies {
    compile files("C:/tools/android/android-sdk_r04-windows/platforms/android-21/android.jar")
    compile "org.javafxports:jfxdvk:8u60-b3"
       
    compile fileTree(dir: 'libs', include: '*.jar')
    runtime fileTree(dir: 'libs', include: '*.jar')
}

mainClassName = 'com.sibvisions.mobilefx.android.DemoERPApplication'
   
jfxmobile {
    ios {
        forceLinkClasses = [ 'com.sibvisions.mobilefx.ios.**.*' ]
    }
   
    android {
      androidSdk = 'C:/tools/android/android-sdk_r04-windows'
      compileSdkVersion = 21  
    }
}

Hints
  • Enable developer options for your Android device
  • Show log messages from your Android device: \platform-tools\adb logcat

JVxEE 1.2

Post to Twitter

JVxEE version 1.2 is out!

The good news

JVxEE is now available from Maven central, that means that you can add it as dependency to your Maven projects:

<dependency>
    <groupId>com.sibvisions.jvx</groupId>
    <artifactId>jvxee</artifactId>
    <version>1.2</version>
</dependency>

The first of the two major changes are that we fixed possible exceptions that might be thrown by JPAStorage.getEstimatedRowCount(ICondition), it should now work under all situations.

The second change is the handling of foreign key columns. Previously, foreign key columns where named with the pattern "REFERENCEDTABLE_REFERENCEDCOLUMN", which can lead to collisions if there is more than one column referencing the same table and primary key. So it was possible that you would end up with two columns with the same name, which of course can't be handled by the storage and databook correctly. We devised a new naming scheme and from now on the foreign key columns are named with a combination of the referencing column and the referenced column.

An example:

@Entity public class A
{
    @Id private int id;
    private B source;
    private B target;
   
    // Getters/Setters
}

@Entity public class B
{
    @Id private int id;
    private String name;

    // Getters/Setters
}

With 1.1 the generated columns would look like this, for entity "A":

ID          BigDecimal
B_ID        BigDecimal
B_NAME      String
B_ID        BigDecimal
B_NAME      String

And with 1.2:

ID          BigDecimal
SOURCE_ID   BigDecimal
SOURCE_NAME String
TARGET_ID   BigDecimal
TARGET_NAME BigDecimal

This is definitely an improvement!

The bad news

There is always a downside :(

The changes in the foreign key column naming scheme, to avoid collisions, also mean that most foreign key columns do now have a different name. You'll have to check your code for usages of the now differently named columns.

But there is also an upside! With EPlug you will find those easily.

Usage example

JVxEE provides the possibility to utilize the Java Persistence API (JPA) as backend for storages and databooks. JPA is powered by POJOs, like these:

@Entity public class Aircraft
{
    private String country;
    private String description;
    @Id @OneToMany private String registrationNumber;
}

@Entity public class Airport
{
    @Id @OneToMany private String code;
    private String country;
    private String location;
    private String name;
}

@Entity public class Flight
{
    @OneToOne private Aircraft aircraft;
    private String airline;
    @OneToOne private Airport airportDestination;
    @OneToOne private Airport airportOrigin;
    @Id private String flightNumber;
}

This is an extremely simplified model for airline flights.

There is an aircraft that can be used, airports that can be flown to and from and the flight itself. Flight is referencing both, the aircraft and the airport. Now we only need to tell JPA about these classes by placing a persistence.xml in the META-INF directory, like this one that we use for our unit tests:

<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence              
                                 http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"

             version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">

  <persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
    <class>com.sibvisions.rad.persist.jpa.entity.flight.Aircraft</class>
    <class>com.sibvisions.rad.persist.jpa.entity.flight.Airport</class>
    <class>com.sibvisions.rad.persist.jpa.entity.flight.Flight</class>

    <properties>
      <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" />
      <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:hsql://localhost/db" />
      <property name="javax.persistence.jdbc.user" value="sa" />
      <property name="javax.persistence.jdbc.password" value="" />

      <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
      <property name="eclipselink.ddl-generation.output-mode" value="database" />
      <property name="eclipselink.logging.level" value="FINE"/>
    </properties>
  </persistence-unit>
</persistence>

(Sure, it's also possible without manual XML mapping)

Now all that is left is creating a new storage that uses the JPA:

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("test");
EntityManager entityManager = entityManagerFactory.createEntityManager();

JPAStorage storage = new JPAStorage(Flight.class);
storage.setEntityManager(entityManager);
storage.open();

And that's it! From here on there is only JVx code.

Ein GUI für alle Fälle

Post to Twitter

Es gibt seit heute einen neuen Artikel über JVx in der deutschen Presse. Hier das Intro:

Die Erstellung von modernen und optisch ansprechenden Anwendungen ist gerade ein heißes Thema. Egal welche Fachzeitschrift oder welches Onlinemagazin gelesen wird, ein Artikel über JavaFX ist immer dabei. Wer Webanwendungen bevorzugt, findet auch ganz bestimmt einen Artikel über Vaadin. Und natürlich...

Der vollständige Artikel wurde heute auf Informatik Aktuell veröffentlicht. Natürlich lesenswert :)

Jegliches Feedback ist willkommen.

DOAG 2015 - I'm a speaker

Post to Twitter

2015-K_A-Banner-Speaker-180x150-ENGL   I'm a speaker at DOAG 2015 in Nuremberg.
My talk will be about "Mobile applications with JavaFX"

Read more.


I'll show you some really cool things with JVx and JavaFX on mobile devices. Let yourself be surprised.

Create WildFly Swarm applications from existing war files [part 2]

Post to Twitter

My first steps with WildFly swarm were very successful but I didn't solve my problem completely:

I tried to create a self-contained jar (fat jar) file from an existing war file, with minimal effort. The idea was that our product VisionX could create such jar files with some mouse clicks.

This wasn't possible because the project is in a very early phase, ANT wasn't supported and it wasn't planned.

I solved the problem for my use-case and published the result at github.

The project contains an Eclipse project with an ant task and a fully functional ANT build. It has a dependency to ivy, because ivy was used for dependency resolution. Ivy is not needed if you want to work with a copy of all dependencies, e.g. our VisionX will do this.

The code isn't production ready but it works like a charm. The test war file has 56MB and the created jar is around 78MB.

Just play around with the code :)