This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information

Category: Development

VisionX 2.3 - Feb, 5th

The next version of our flagship VisionX will be available tomorrow - Feb 5th, 2016. The version number is nice because 2 could be the month and 2+3 = 5 :)

We invest more time/resources/work than ever before in this version. It has many new features and great improvements. All included open source libraries were updated and offer additional features because not all available library features/APIs are covered by VisionX.

So what's new?

  • Vaadin 7.5.7

    The open source project JVx Vaadin UI was updated to Vaadin 7.5.7 and the UI implementation got many performance tunings. It's now significant faster than before - up to 5 times faster. The performance boost depends on your UIs because it makes no difference if you only have two input fields in your screen. But if you have large screens with Tabs and many input fields, it will rock. The API got support for FontAwesome and Vaadin font icons.

  • HTML5 Live Preview

    The live preview now supports an external CSS file. It's super easy to change the style of your application while creating it with VisionX.

  • HTML5 Live Reload

    This feature automatically reloads changed screens in the browser after you've changed it with VisionX. Simply use add URL Parameter liveReload=true. This features save click time and is great if you have multiple screens conntected to your workstation.

  • Responsive coporation layout

    Our corporation application layout is now responsive and fully customizable.

    full mode

    full mode

    small mode

    small mode

    mini mode

    mini mode

    mini mode (menu)

    mini mode (menu)

    Use the API to show/hide the menubar or the sidebar. Add custom or remove default buttons.

  • Support for custom code format rules

    It's possible to use your custom code formatting rules. The rules are based on Eclipse Code Formatter and all Eclipse (Luna) options will work with Eclipse.

  • Morph Panel improvements

    The Morph Panel is a one-for-all solution. It was introduced in VisionX 2.2. We improved the popup mode, e.g. if you double click the table, the popup will be opened if you don't use the navigation. We added more APIs for power users.

  • No more automatic database changes

    VisionX doesn't change the database objects automatically. It's your decision:

    Modify fields

    Modify fields

    Delete screen

    Delete screen

  • Java 8 u60

    VisionX runs with Java8 update 60.

  • Action editor automatic scrolling

    The action editor now automatically scrolls to the input field if it's not visible. It's not a big thing but creates great UX.

  • Automatic import organisation

    VisionX automatically removes unused imports from the source files. This is an optional feature and can be disabled.

  • Single line javadoc for fields

    The Javadoc for fields will be written in a single line (if possible). This feature is optional an can be disabled.

  • Better customizing support

    VisionX changed the class loading mechanism of customizers and controls. It'll be possible to use your custom controls without any tricks. It's possible to customize VisionX for your needs.

  • Mobile application creation (optional AddOn needed)

    This feature is awesome because it makes it be possible to create a mobile app from your application in under 5 minutes.

    JavaFX mobile LIVE CSS hacking

  • Additional licensing options

    User based, Subscription based, Floating, individual.

    Please contact our Sales Team for more details.

All customers will find the new version in their download area!

Release day - Merry Christmas

Yesterday, we've released JVx 2.4, VaadinUI 1.4, HeadlessUI 1.1 and JVx vert.x 3.0.

Headless UI and JVx vert.x are maintenance updates because of JVx changes. JVx 2.4 is a bugfix release with some new cool features and VaadinUI is a performance tuning and bugfix release.

JVx and VaadinUI are available on Maven central. The other releases are hosted on SourceForge.

What's new in JVx 2.4?

  • Thread safety

    DataBook (MemDataBook, RemoteDataBook) are now Thread safe. It wasn't guaranteed before 2.4.

  • Support for Boolean and Arrays (Oracle)

    JVx' OracleDBAccess supports Boolean DataTypes via JDBC calls and Arrays as well. We wrapped the functionality in our existing API and it makes no difference for you. Arrays are wrapped as List of IBeans.

  • Parameter changed event in WorkScreen

    The WorkScreen class got a new event: eventParameterChanged. It enables notification about parameter changes.

  • New AbstractFactory

    We introduced AbstractFactory and changed all factory implementations. With AbstractFactory, it's possible to set custom factory properties. We use this new feature for vaadin UI. With new Vaadin UI it's possible to use the old Table or the new Grid implementation. Simply set a property for that.

  • API change: IFactory

    The invokeInThread method now returns the Thread instance.

  • FontAwesome support
  • Automatic Record translation

What's new in Vaadin 1.4?

  • Based on vaadin 7.5.7
  • FontIcon support
  • Grid support (experimental)

    Set the factory property: vaadin.component.legacy_table to true (via web.xml as init parameter or as URL parameter).

  • Lazy loading of LinkedCellEditor

    Before 1.4, all LinkedCellEditors were loaded immediate. This was a performance impact. With 1.4 this was changed and data will be loaded, when needed.

  • Performance tuning

    The performance is now about 5 times faster than before. We improved the performance because we reduced our CssExtension and reduced the database calls. You can feel the new performance :)

What's new in JVx vert.x 3.0?

It's based on Vert.x 3 and works with JVx 2.4.
(JVx vert.x is hosted on GitHub)

You can find all changes in the project Changelogs.
Happy coding!

Using Boolean Datatype with Oracle and JDBC

Oracle doesn't use/define the SQL Type Boolean. You can't define a column in a table as Boolean. It's possible to use boolean in PL/Sql e.g. for procedures or functions but you can't call the function from SQL.

Example functions

It's possible to call:

SELECT bfunc('Hello') FROM dual;

but it's not possible to call:

SELECT afunc(true) FROM dual;

or

SELECT afunc(1) FROM dual;

(1 = true, 0 = false; boolean is mapped to integer in Oracle)

If you want to call a procedure or function which defines boolean parameters, it's not possible without tricks with Oracle JDBC driver. This is annoying.

We solved the problem in JVx 2.4 and it's now possible to call functions or procedures without tricks. Here's a "more complex" example. We define a function with an input parameter and a procedure with an input/output parameter in a package:

CREATE OR REPLACE PACKAGE TestBoolean IS
 
  FUNCTION test(pOutput BOOLEAN) RETURN BOOLEAN;
  PROCEDURE testBoolOut(pOutput IN OUT BOOLEAN);
 
END;
/

CREATE OR REPLACE PACKAGE BODY TestBoolean IS

  FUNCTION test(pOutput BOOLEAN) RETURN BOOLEAN IS
  BEGIN
    IF (pOutput) THEN
      RETURN FALSE;
    ELSE
      RETURN TRUE;
    END IF;
  END;

  PROCEDURE testBoolOut(pOutput IN OUT BOOLEAN) IS
  BEGIN
    IF (pOutput) THEN
      pOutput := FALSE;
    ELSE
      pOutput := TRUE;
    END IF;
  END;

END;
/

Now we use JVx' DBAccess to call the function and procedure.

//DB connection
DBAccess dba = new OracleDBAccess();
dba.setUrl("jdbc:oracle:thin:@oravm:1521:XE");
dba.setUsername("test");
dba.setPassword("test");
dba.open();

//Function call
Assert.assertEquals(Boolean.TRUE, dba.executeFunction("TESTBOOLEAN.TEST", Types.BOOLEAN, Boolean.FALSE));

//Procedure call
InOutParam param = new InOutParam(Types.BOOLEAN, Boolean.FALSE);
dba.executeProcedure("TESTBOOLEAN.TESTBOOLOUT", param);

Assert.assertEquals(Boolean.TRUE, param.getValue());

The whole type mapping was done in OracleDBAccess and it's invisible for you. Simply use the API to call procedures or functions.

eTV in Action

Some days ago, I wrote about our eTV project. The blog post had some pictures but no more details. I want to tell you some details about this project because it's simply awesome.

The project was a research project of our framework team and was started just for fun. The use-case was simple: Our room had 4 walls and 3 were full with pictures and world maps. Only one wall was empty. Why not using a flat TV for showing different content like livestreams, comic strips, images.

The idea was great and some days later, the last wall was full. A nice 43" flat TV was mounted.

We thought that a RaspberryPi could bring the content to the TV because it's a small device and fits behind the TV. Java works without problems on the Pi and JVx as well.

After all hardware pieces were ready, it was time to think about the software because a sort of control center was needed to implement some features. The plan was to write a simple server which has a set of commands like: open website, show image, play livestream, execute command, upload file, download file.

The server was implemented as simple socket server, with JVx. It executes pre-configured commands and has some important control features: take screenshot, next - previous window, get window list, close window. The server has no GUI and is more or less a window/process manager.

The server has no GUI, but we need a GUI to control the server. We wrote a simple JVx application as remote control. The remote control application was deployed on a Jetty application server (on the RasPi, with vaadin UI) and as mobile JavaFX application. Jetty runs fine on the RasPi and our vaadin UI as well.

The TV with RaspberryPi, streaming a Video from YouTube:

eTV YouTube Stream

eTV YouTube Stream

After we were ready with the server, we tried to create a simple JVx demo application to demonstrate JVx on embedded devices. It was funny to use eTV for live streams or to show images, but what about real-world use-cases?

The idea was about a JavaFX application, running on the RasPi. The application could be a monitoring app for a warehouse with a nice looking frontend and a backoffice view for administration. It's usual to have a nice looking frontend and a not so nice looking backoffice part.

We've implemented an application for a big assembly hall. The application is a styled JVx application but still 100% JVx. We've used VisionX to create the UI:

VisionX design mode

VisionX design mode

TV mode

TV mode

The application in VisionX is not 100% the same as on the TV because of the screen resolution, but it's the same source code and VisionX works with this application. The application on the TV hides the application frame and only shows the screen content, but this is a supported feature.

The UI technology is not JavaFX! We tried to use JavaFX but it wasn't possible because the RasPi had performance problems with the amount of nodes. It wasn't possible to reduce the amount of used nodes with standard JavaFX controls. Overclocking the Pi didn't solve the problem.

We simply switched to Swing and didn't have any performance problems. So, the UI technology is good old Swing. It works great in combination with the RasPi and we think the result is also nice!

The application is a monitoring application for different events, like performance, effort, pressure, temperature, aerodynamics, alerts. We did connect a temp sensor and two buzzers to get a better real-world experience and because it was easy to support with a RasPi. Initial setup:

Initial setup

Initial setup

The backoffice/backend was deployed as web application (Jetty on RaspberryPi, JVx vaadin UI) because it should be possible to use it on tablets or smartphones without native apps:

Backend view

Backend view

The same UI on mobile phones:

Mobile view

Mobile view

Mobile view (no menu)

Mobile view (no menu)

The application is a 100% JVx application with Swing UI and vaadin UI. Everything runs directly on the RaspberryPi.

We've used the whole eTV system as showcase application at DOAG conference in November:

eTV @ DOAG 2015

eTV @ DOAG 2015

The results of our "research project" are awesome and eTV is a ready-to-use product. We didn't code one line of code to support different UI technologies and didn't have problems with resolutions of tablets, smartphones or the TV (#responsive).

Thanks to JVx it was super easy to create an amazing application.

Our nice JavaFX mobile applications

Our (research) projects with JavaFX are almost finished. We have awesome results and everything is production ready. The only drop of bitterness is the performance of JavaFX on desktops and mobile devices, but this can be improved by Oracle. It's not in our hands.

What do we have?

We have

  • a complete JavaFX UI for JVx
  • a custom application frame for mobile applications
  • Live CSS manipulation of installed apps (needs debug build)
  • Complete Project export for JavaFX mobile projects (JavaFXPorts based gradle project),
    integrated in upcoming VisionX 2.3
  • Remote Work-screen loading (via VisionX)
  • JVx server runs without limitations on mobile devices
  • JVx client runs on mobile devices (for network clients)

How does it look like?

I have some screenshots from two applications. The first one is a standalone JVx application. The whole JVx framework runs on the mobile device. The app is a remote control for our eTV project (it's a brand new side project of our research team).

The app was inspired by MS Metro style ... Windows8 style ... Modern ... Universal ... Windows Store ... Windows apps.

The main screen has some buttons to control our eTV and some buttons open a "popup" with additional options:

eTV Dashboard

eTV Dashboard

eTV Window view

eTV Window view

eTV Gallery

eTV Gallery

The second app will be shown as Video, because we want to demonstrate how we use VisionX to create backoffice apps in under 5 minutes! The app itself isn't complex and does "nothing special", but the same mechanism works for complex applications like our Demo ERP system (read our Code once. Run anywhere post).

Our JavaFX mobile project was based on the great work of Gluon and their JavaFXPorts OpenSource project and also on RoboVM.

JavaFX mobile LIVE CSS hacking



(The video lasts 05:19 but it should be 07:30 because the build process takes 02:50. We shortened the build process because it's boring to wait.)

Details about LIVE css hacking

We have a short video about our LIVE css hacking feature for mobile JavaFX applications on YouTube:

JavaFX mobile LIVE CSS hacking


We demonstrate a mobile JavaFX application, running on a Nexus 9 Tablet. It's a pure JavaFX application with our mobile application frame and it was deployed with JavaFXPorts. In the video, we change some styles on our Laptop and the application updates its styles on demand. This is really useful because resolution/screen size can be different. Sometimes the background color looks different than on a Desktop, ... And it's easy to try out new styles without application restarts - same principle as developer tools for Chrome or FireBug for Firefox.

But how did we implement this feature?

It was too easy :)

Here are the "secrets":

  • A simple socket server for the application
  • A custom URL handler for loading remote-retrieved styles
  • A simple File watcher for the client

That's it!

But to be honest, the custom URL handler was very tricky, because we tried to find a very smart, non-static, solution. And every platform has its specific handling and URL loading mechanism. But one step after another.

I guess you know that a socket server isn't a real problem. We wrote our own "generic" socket server some years ago, for JVx and it's not tricky. In principle, it works like this snippet:

ServerSocket serverSocket = new ServerSocket(9999);
Socket clientSocket = serverSocket.accept();

PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

The problem is that you need a sort of protocol for the content. We've used our UniversalSerializer and send simple POJOs. The stylesheet POJO contains the css file as byte[]. Here's our server code:

CommunicationServer server = new CommunicationServer(findHost(), 9999);
server.addReceiver(r ->
{
    javafx.application.Platform.runLater(() ->
    {
        synchronized (oSync)
        {
            if (sLastCss != null)
            {
                logger.info("Remove remote CSS file ", sLastCss);

                launcher.getScene().getStylesheets().remove("remotecss://" + sLastCss);
               
                ObjectCache.remove(sLastCss);
            }

            sLastCss = ObjectCache.createKey() + ".css";
       
            ObjectCache.put(sLastCss, r.getObject(), -1);

            logger.info("Install remote CSS file ", sLastCss);
       
            launcher.getScene().getStylesheets().add("remotecss://" + sLastCss);
        }
    });
   
    return null;
});
server.start();

We add custom stylesheets with remotecss as protocol. The resource loading mechanism of Java(FX) tries to load the URL automatically. The protocol isn't a standard protocol and so we had to create a custom URL handler. The problem wasn't the handler itself because it's straight forward:

public class Handler extends URLStreamHandler
{
    @Override
    protected URLConnection openConnection(URL url) throws IOException
    {
        if (url.toString().toLowerCase().endsWith(".css"))
        {
            return new CssURLConnection(url);
        }
       
        throw new FileNotFoundException();
    }
}

And the CssURLConnection also wasn't a problem:

private class CssURLConnection extends URLConnection
{
    public CssURLConnection(URL pUrl)
    {
        super(pUrl);
    }

    @Override
    public void connect() throws IOException
    {
    }

    @Override
    public InputStream getInputStream() throws IOException
    {
        Object oCss = ObjectCache.get(getURL().getHost());
       
        if (oCss instanceof String)
        {
            return new ByteArrayInputStream(((String)oCss).getBytes("UTF-8"));
        }
        else if (oCss instanceof byte[])
        {
            return new ByteArrayInputStream((byte[])oCss);
        }
       
        throw new FileNotFoundException();
    }    
}

The problem was that the JVM didn't know how to load remotecss:// URLs because it doesn't have a default handler. The JVM offers different solutions for this problem and the well known is:

URL.setURLStreamHandlerFactory(factory);

But this is a static mechanism and we didn't know if another library uses the same method. There's no getURLStreamHandlerFactory in URL and the solution wasn't good enough for us. For a simple test application this restriction shouldn't be a problem, but we didn't like it because we're framework developers.

There's another solution for the problem, because the source code of URL contains the static method:

static URLStreamHandler getURLStreamHandler(String protocol)

This method tries to load protocol handlers automatically, if definded via system property java.protocol.handler.pkgs or from package: sun.net.www.protocol.protocolname.Handler

After reading the source code, we found a blogpost about this feature, read more. It was easy to search with the right keyword after we knew the solution.

...be careful with security manager, but this shouldn't matter.

The URL implementation for Android is a little bit different because but if you set the system property, it'll work as expected.

The hardest parts were done and the last thing was the file watcher client because we planned to send the changed CSS file(s) to the app automatically. Here's our solution (Java8 style):

thWatcher = new Thread(() ->
{
    File fi = ResourceUtil.getFileForClass("/live.css").getParentFile();

    FileSystem fsys = FileSystems.getDefault();

    Path pathCss = fsys.getPath(fi.getAbsolutePath());

    try
    {
        try (final WatchService service = fsys.newWatchService())
        {
            WatchKey wkey = pathCss.register(service, StandardWatchEventKinds.ENTRY_MODIFY);

            while (!ThreadHandler.isStopped(thWatcher))
            {
                WatchKey key = service.take();

                for (WatchEvent<?> event : key.pollEvents())
                {
                    Kind<?> kind = event.kind();

                    if (kind == StandardWatchEventKinds.ENTRY_MODIFY)
                    {
                        Path changed = (Path)event.context();

                        if (changed.toString().equals(FileUtil.getName(CSS)))
                        {
                            File fiModified = new File(fi, changed.toString());

                            if (fiModified.lastModified() > 0)
                            {
                                if (lLastModified != fiModified.lastModified())
                                {
                                    try
                                    {
                                        client = getClient();
                                        client.send(FileUtil.getContent
                                           (ResourceUtil.getResourceAsStream("/live.css")));

                                        lLastModified = fiModified.lastModified();

                                        System.out.println("Sent CSS to application");
                                    }
                                    catch (Exception e)
                                    {
                                        // next try
                                        client = CommonUtil.close(client);
                                    }
                                }
                            }
                        }
                    }
                    else if (kind == StandardWatchEventKinds.OVERFLOW)
                    {
                        continue;
                    }
                }

                if (!key.reset())
                {
                    thWatcher = ThreadHandler.stop(thWatcher);
                }
            }

            wkey.reset();
        }
    }
    catch (Exception e)
    {
        e.printStackTrace();

        synchronized (TestCommunication.this)
        {
            TestCommunication.this.notify();
        }
    }
});

thWatcher.start();
ThreadHandler.add(thWatcher);

The source code examples aren't complete but I guess you can implement your own solution based on them. We made tests with iOS, Android and Desktop applications and didn't have any problems. The CSS editing feature would be a very useful extension for ScenicView but it's not available right now.

Our test devices:

Test devices

CSS hacking - test devices

Code once. Run anywhere.

It's some time since my last post about JVx. But I have a good excuse - Coding :)

I tried to improve our JavaFX UI for mobile devices. It was a hard fight but I won. Not everything is done right now, but the result is soo awesome!

Many of you know that JVx is an Application Framework. It's small and simple but still very powerful. It follows the convention over configuration principle and it was designed to be UI technology independent. Oh, it follows the Single sourcing principle too, it's a Full-Stack-Framework, contains a very smart persistence implementation, and so on.

What means UI technology independent?

We define the term as follows:

Code an application once and use it on different platforms and with different devices and different technologies.

As platform, we recommend Windows, Linux or MacOS. Devices are Desktop PCs/Notebooks, Smartphones, Tablets or embedded Hardware like RaspberryPi. We use the term technology for UI toolkits/standards like HTML5, Java Swing or JavaFX.

JVx isn't a JavaScript framework or library because it supports every platform with maximum power. This means that a desktop application runs as standalone application on your desktop computer with full access to connected hardware. A HTML5 application runs in a web browser and has limited access to the device but you have full css features and websockets. If your application runs on mobile devices, simply use all available hardware features and gesture support.

All the platform/device/technology specific problems were solved in JVx and a developer simply has a standard API to create applications. If the standard API isn't enough, it's easily possible to access the technology features without limitations. JVx encapsulates but doesn't hide anything.

With JVx you can code desktop applications, browser based HTML5 applications or native mobile applications without know-how of every platform/device/hardware.

I guess it's time for facts and some screenshots should clarify what I mean.

Desktop Swing UI

Desktop Swing UI

Desktop JavaFX UI

Desktop JavaFX UI

vaadinUI corporate

vaadinUI corporate

vaadinUI simple

vaadinUI simple

vaadinUI legacy

vaadinUI Legacy

mobile fxUI

mobile fxUI

mobile fxUI menu

mobile fxUI menu

mobile fxUI legacy

mobile fxUI legacy

All screenshots show the same application (same source code) with different UI technologies and on different devices. We have UI implementations for vaadin, JavaFX, Swing. We have different application styles because the application shouldn't look like a desktop application, on mobile devices or in your browser (but it's possible).

The application style itself is fully customizable and it's only one possible implementation. It's not a problem to change it or create a new one from scratch. We've defined that our standard applications have a menu, a toolbar a content are (for screens) and an authentication mechanism (login).

If you compare the vaadinUI with Swing or JavaFX UI, you'll see that the vaadin style has a completely different menu. There's also a legacy mode which shows windows for every screen, but this style isn't the preferred one. Sure, sometimes this style makes sense but it's not very user-friendly. If you have an application with few screens, a simple menu would be useful and if your application has many screens, the corporate style could be better because it has a menubar and a sidepane for quick navitation.

The mobile variant is our latest style and it's really different. You won't use apps in MDI style. Sure, we have this style but it's ugly. We like hamburger menus as shown in the screenshots.

JVx is very fast, flexible and powerful. Don't waste time for platform problems, simply implement your requirements by using JVx.

Official FontAwesome support in JVx

We're happy to announce that JVx got "official" (experimental) support for FontAwesome icons. We made some changes to our internal image management but it wasn't a big change and no API was touched!

How it works?

Simple, as usual :)

An example:

UIButton button = new Button("Press me");
button.setImage(UIImage.getImage(IFontAwesome.USER_SMALL);

But that's not all because we support special things like coloring, e.g.:

UIButton button = new Button("Press me");
button.setImage(UIImage.getImage(IFontAwesome.USER_SMALL + ";color=orange");

and it's also possible to set the size:

UIButton button = new Button("Press me");
button.setImage(UIImage.getImage(IFontAwesome.USER_SMALL + ";size=24;color=orange");

The support was split in different parts. JVx got the IFontAwesome interface which defines FontAwesome icon names. This doesn't mean that every UI implementation supports FontAwesome!

Every UI has to support FontAwesome because it's UI dependent how font icons will be rendered.

We have support in our Swing UI and vaadin UI, but currently we don't have support in our JavaFX UI (not yet). This means, that you can use FontAwesome directly in your JVx application out-of-the-box without manual configuration and without accessing resources directly.

Pure Swing

We have a read-to-use FontAwesome ImageIcon for Swing developers. It's called JVxFontAwesome. It's easy to use this icon in your Swing application, also without JVx UI.

vaadinUI

There are some limitations in Vaadin, because it's not possible to add custom style properties to menu items via API calls. It's possibel via css files, but this is a limitation you should know. Sure, it shouldn't be a big problem but vaadin doesn't support this feature right now.

Vaadin up to 7.5.6 has support for FontAwesome 4.1.0 and JVx has support for 4.4.0. Not all icons are available in vaadin UI right now! There's a ticket about an update to 4.4.0.

JavaFX UI, native mobile clients

We didn't implement FontAwesome in JavaFX UI or our Android, iOS clients - not yet. It shouldn't be a big problem to implement the support but we're still in an experimental phase ;)

JVx' vaadinUI supports FontAwesome and VaadinIcons

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)

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.