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

Eclipse Oxygen.2 with ANT and JRE6

The support for ANT and JRE6 with Eclipse Oxygen.2 (December 2017).

The plugin was created for:

Version: Oxygen.2 Release (4.7.2)
Build id: 20171218-0600

Don't forget the -clean start (read the original article for more details)!

One more thing you should do:

Oxygen.1 and Oxygen.2 contain ANT 1.10.1. This version requires Java 8. In order to use Java 6, you have to download ANT 1.9.x. Simply download ANT and set the ANT Home to your version, via

Window >> Preferences >> ANT >> Runtime >> Ant Home...

If you try to use the bundled ANT with JRE 6, it will fail with an Exception.

Download the plugin from here. It works for us - no warranty!

More Details: Eclipse Oxygen.1 with ANT and JRE6

More about Application styling

We showed you the upcoming CSS edit feature of VisionX. This feature was used in our new tutorial Style Invoice application.

The standard Invoice application was more or less a standard VisionX application with some standard colors and icons. Not super fancy.

The Styled Invoice application demonstrates how easy it can be to apply your own Style to an application, created with VisionX.

The new tutorial is available in our documentation system.

The comparison of both applications

The standard application:

Standard Invoice application

Standard Invoice application

The styled application:

Styled invoice application

Styled Invoice application

VisionX CSS Styling feature

The upcoming release of VisionX will support CSS styling. We'll show you a first impression with a short video:

Vaadin AddOn for VisionX

The editor supports autocompletion and syntax highlighting:

VisionX CSS Editor

VisionX CSS Editor

We did integrat the RSyntaxTextArea for this. If you want to know how this works, check the documentation.

JVx and PostgreSQL, supporting Savepoints

Transactions are an integral mechanism of databases, without them we could hardly ensure data consistency. Well, we could of course, but it would be a lot more work. JDBC has of course support for transactions, but it also supports so called "Savepoints", which we will have a look at today.

What are transactions?

Normally, I'd assume that everyone of you knows what transactions are and what they are used for, but today I will quickly rehash it to make sure. Transactions enable us to define groups of statements to be executed on a database with all either succeeding or all failing. Imagine the following statements which might be executed on a database as one action:

1: Insert record into A
2: Update record of B
3: Update another record of B
4: Insert record into C

This might happen in the background if you click a button or do something similar. This example is straightforward but if we start thinking about possible problems we will soon realize that there is a lot of potential for things going wrong. For example if statement #3 would fail we would miss records in the tables B and C. Overall, our data would be in an inconsistent state after that. To make sure that it does not happen, we can define these statements as a single transaction.

Transaction
  |-Insert record into A
  |-Update record of B
  |-Update another record of B
  |-Insert record into C
  \-Commit

If one of these statements fail, all changes done by previous statements can be undone and the database will return to the state before we started manipulating it. That is great, because we can now guarantee that even though an error has happened, the data will remain in a consistent state.

We could even extend that with additional application logic, for example we insert three records and then we check if the values of all records add up to a certain threshold, if yes, we simply undo the changes. Or if we notice that a constraint has been violated (though, pretty much all databases support constraint definitions in one way or the other). Additionally, transactions are completely isolated from all other connected clients. That means that if we start a transaction and insert a record into table A, all other clients will not see this record until we commit our changes. So the data is never in an inconsistent state, not even temporarily or transiently.

What are Savepoints?

Savepoints are sub-transactions within another transaction. It allows to undo parts of an ongoing transaction.

Another example:

Transaction
  |-Insert record into A
  |-Insert child record into B
  |-Insert child record into B
  |-Insert another record into A
  |-Insert child record into B
  |-Insert child record into B
  |-Insert another record into A
  |-Insert child record into B
  |-Insert child record into B
  \-Commit

This is a little bit more fabricated and complicated, assume we want to insert three master records with two detail records each. The following conditions apply:

  • If a master record fails to insert, nothing should be inserted.
  • If a detail record fails to insert, the corresponding master record should also not be inserted.

This is hard to do with a simple transaction, but is quite easy when it comes to using savepoints:

Transaction
  |-Savepoint 1
  |   |-Insert record into A
  |   |-Insert child record into B
  |   \-Insert child record into B
  |-Savepoint 2
  |   |-Insert another record into A
  |   |-Insert child record into B
  |   \-Insert child record into B
  |-Savepoint 3
  |   |-Insert another record into A
  |   |-Insert child record into B
  |   \-Insert child record into B
  \-Commit

We create a savepoint before the insert of the master record, if the insert of the master record fails we rollback the transaction, if the insert of a detail record fails we rollback to the savepoint we created earlier. This allows quite complicated and nested transactions, especially because there is no defined limit to how deep savepoints can be nested.

Error behavior

Of course it can always happen that a statement fails for one reason or another, so it is important to know how the database behaves once an error occurred. We built ourselves another simple example:

Transaction
  |-Insert record into A
  |-Insert record into B (this fails)
  |-Insert record into C
  \-Commit

We insert three records, and the second one fails to insert. How should the database behave in such a situation? Turns out that this differs between different database systems.

Silent/Automatic restore to a previous state

Many databases perform a simple "silent/automatic restore to a previous state", all changes done (if any) of the current statement are undone and the transaction can be treated like the failing statement never happened. With the example above, and assuming that we do not cancel the transaction on an error, the records would be inserted into A and C.

In our tests Oracle, MySQL/MariaDB, H2 and SQLite were all behaving this way.

Requiring manual recovery

PostgresSQL requires to perform a "manual recovery" from a failed statement. So that once an error occurred during a transaction, the user has to revert to a (manually) set savepoint or rollback the complete transaction. We will go into details on that later.

Reverting everything and happily continuing

MS SQL on the other hand has a quite different approach. When an error occurs during a transaction, all changes are (automatically) rolled back but the transaction can still be used. So in our example, only the record in C would be inserted.

PostgreSQL JDBC and Savepoints

Back to PostgresSQL and how it requires manual recovery. When a statement fails within a transaction in PostgreSQL, the transaction enters the aborted state and one can then see an error like the one below if further statements are issued:

Current transaction is aborted, commands ignored until end of transaction block.

What that means is simple that the connection/server is still waiting on input on what to do with the transaction. There are three possible ways to recover from there:

  1. Rollback the complete transaction
  2. Commit, which will be transformed into a rollback at this point
  3. Rollback to a savepoint

But these actions must be initiated by the user before the transaction can be further used (or not, if it is being rolled back completely). If one wants to emulate the behavior of other databases in PostgreSQL, every statement that is executed within a transaction has to be "wrapped" with a savepoint, in pseudo-code:

begin transaction
    savepoint
    try
        execute statement
        release savepoint
    catch
        rollback to savepoint
   
    ...
commit

Even though that seems tedious, that is not the case. If you have such a requirement you already have central point through which all statements pass before being executed, so this can be implemented easily.

JVx and Savepoints

In our case it is DBAccess, our main datasource. Because every database interaction has to pass through DBAccess (in one way or the other), we could easily implement such emulation at a low-level and it is automatically available to all users. To be exact, DBAccess has received internal support to wrap all statements in savepoints when configured to do so. This configuration possibility is protected and is currently only used by the PostgresSQL DBAccess extension. It does exactly what it says on the tin and is only active when enabled and automatic commits have been turned off. So this change does have no effect on any other database but PostgreSQL.

We already have plans to extend this basic savepoint support with a public API which allows users of JVx to utilize this new functionality. One of the ideas that we are currently discussing is to provide the ability to create named savepoints. A simple mockup of that idea:

  1. // Switch off auto commit to use transactions.
  2. dbAccess.setAutoCommit(false);
  3.  
  4. // Insert some data.
  5. dbStorage.insert(aRecord);
  6. dbStorage.insert(anotherRecord);
  7.  
  8. // This part is optional.
  9. try
  10. {
  11.     dbAccess.setSavepoint("NAME");
  12.    
  13.     dbStorage.insert(yetAnotherRecord);
  14.     dbStorage.update(someOtherRecord);
  15. }
  16. catch (DataSourceException dse)
  17. {
  18.     log.error(dse);
  19.     dbAccess.rollbackTo("NAME");
  20. }
  21.  
  22. dbAccess.commit();

As said, we are currently in the process of discussing such possibilities but definitely want to provide such an API at one point.

Conclusion

As it turns out, the "special" behavior of PostgreSQL isn't as special as it seems to be. It is a design decision that was taken and that is understandable. Changing this behavior now, 20+ years in, is out of the question as it would require a substantial effort to make sure that this behavior is backwards compatible. The gains from such a change on the other hand would be very little, as it is a quite specialized case in which this behavior matters and the "fix" is rather easy.

Screen Embedding AddOn for VisionX

We have a new AddOn for all VisionX users. It's the Embedding AddOn.

The new AddOn makes it possible to embedd one work-screen into another work-screen. Simply re-use screens in other screens.

Get an impression

Vaadin AddOn for VisionX

The AddOn is commercial and not included in VisionX. Contact our sales team to get more information!

Documentation redesign

Some years ago, we put all our documentation into our Forum. This wasn't a perfect system for our documentation, but it was in one place. But now we know that the Forum was a bad idea for framework and product documentation.

Last year, we started an evaluation for a new documentation system and were shocked about the quality and features of available solutions. We found a SaaS solution but we didn't want to store our documentation elsewhere. After some research we made a decission and our new documentation system was DokuWiki. The system itself is very nice but the standard theme is not pretty. But it's pluggable and there are many nice looking themes and very useful plugins.

After some customization we were very happy with the result and the migration from our Forum to the DokuWiki was not a hard task. It's still in progress, but we're happy to announce that our new docu system is available for you!

The new link is https://doc.sibvisions.com/

The new system contains some many information about VisionX as well. We didn't publish this information in the past.

Have fun with our new documentation system!

Our Forum will be continued, but only as place for questions and answers.

DokuWiki XMLRPC with Java

DokuWiki

is a simple to use and highly versatile Open Source wiki software that doesn't require a database.

It's a really nice software for your documentation. The default theme isn't super modern, but it works. There are many custom themes available and styling is simple.

The really cool thing is the remote API of DokuWiki. It has a XML based RPC interface. Here are some details.

The documentation looks promise. There's a Java example :)
But the last update of the Java client was 2016 :(

After downloading and testing the client, it was clear that it doesn't work. It had a problem with cookie management. I tried to fix the problem in the base lib - aXMLRPC but it was tricky. The problem was the standard Http URL connection. After replacing it with Apache HttpClient, the dokujclient was working without problems.
I didn't try to find the root cause of the problem because it wasn't worth the time. It was faster to replace the communication part.

Here's a link to our patch and all required libraries (pre-built).

Here's a short snippet

DokuJClient client = new DokuJClient(url);
client.login(username, password);

client.putPage(pNamespace + ":" + pPageName, sText);

FileSearch fs = new FileSearch();
fs.search(dirImages, true);

for (String file : fs.getFoundFiles())
{
    client.putAttachment(pNamespace + ":" + pPageName + ":" + FileUtil.getName(file),
                         file, true);
}

client.logoff();

We use the remote interface for automatic article updates. It works great!

EPlug 1.2.7

We're happy to announce the release of EPlug 1.2.7. This minor update comes with a big performance improvement!

Major performance improvement

The most notable and important feature of this release is the major speed improvement when checking files. We've revisited how the build pipeline works and could determine quite a few bottlenecks which did not only encumber the build process, but also the live checks of databooks. After fixing these bottlenecks the databook live checks are blazing fast and one does not notice any more that these are active.

While reviewing the code, we also saw the possibility for a few more tweaks which we will incorporate into the next major release, to squeeze even more performance out of this.

Improved DataBook View

The DataBook view has also received some much needed attention. There is now a toolbar button which allows to sort the columns by their name (instead of their order as returned by the datasource). Additionally the view does no longer flicker when refreshing and will also clear itself when the last editor closes.

Other fixes

  1. There is no longer a sleeping EPlug job in the Progress View.
  2. The EPlug preferences are now only available on Java projects.
  3. If there is no screen lifecycle object, the session object is now used.
  4. Removed raw HTML in tooltips.

How to get it?

Simply update EPlug via Eclipse!

JVx 2.7 is available

We're happy to announce that JVx 2.7 is available. It's a bigger bugfix release with a small number of new features.

What's new?

  • Tibero Database Support
  • boolean support

    Our DBAccess implementation now supports boolean as parameter.

  • SimpleJavaSource

    It's now possible to create java objects from java source code, see our REST interface

  • Struct support

    Struct support for Oracle DB in procedures and functions.

  • Session timeouts

    We fixed the problem of session timeouts with long up/downloads.

  • WorkScreen

    It's now possible to open a work-screen with additional parameters. A new (optional) Parameter class is available.

  • Mac OS

    We fixed the problems with internal frame borders.

  • Many improvements

The full changelog is available here.

Start with JVx

VisionX, JVx and native Vaadin

If you create an application with VisionX, it's always a JVx based application. You get all advantages of JVx and its GUI independency, but sometimes the GUI indepency is not important and you want to use native GUI controls in your JVx application because JVx doesn't contain the GUI control or you need a commercial control. This is a very simple use-case and it's not a problem to mix JVx components with native components. We have different examples, with different GUI technologies, for this use-case.

Here are some links:

But we don't have a link for our Vaadin implementation. But no problem, here it is!

Simply create a new application with VisionX and a dummy screen like this one:

Simple screen

Simple screen

The screen contains a simple table and two editors. Nothing special. Now we want to add a custom Vaadin component in the empty space. It doesn't matter which component you use. Every vaadin component or AddOn component can be used. JVx doesn't do specific things, it's only an UI abstraction layer.

So, lets add an Accordion to the screen:

Integrated Accordion

Integrated Accordion

The Accordion component is a standard Vaadin component, simply added to the screen. But more... Do you see the "Show Vaadin Notification" Button? This is a standard JVx component. So we mix native vaadin components with standard JVx components and get the full power of both. One advantage of the JVx components is that the automatic translation works without additional hacks, or what about JVx' layouts, event handling, ...

Interested in the source code?

No worries, it's super simple to understand :)

Lets have a look at the custom code:

UIButton butNotification = new UIButton("Show Vaadin Notification");
butNotification.eventAction().addListener(new IActionListener()
{
        public void action(UIActionEvent arg0) throws Throwable
        {
                Notification noti = new Notification("Message",
                                                     "Description", Type.WARNING_MESSAGE);
                noti.setDelayMsec(2000);
                noti.show(Page.getCurrent());
        }
});

UIFormLayout flJVxPanel = new UIFormLayout();

UIPanel panJVxPanel = new UIPanel();
panJVxPanel.setLayout(flJVxPanel);

panJVxPanel.add(butNotification);

if (getApplication().getLauncher().isWebEnvironment())
{
        Accordion acc = new Accordion();
        acc.setHeight(100.0f, Unit.PERCENTAGE);

        for (int i = 1; i < 8; i++)
        {

                if (i >= 2)
                {
                        final Label label = new Label("Welcome sheet!", ContentMode.HTML);
                        label.setWidth(100.0f, Unit.PERCENTAGE);

                        final VerticalLayout layout = new VerticalLayout(label);
                        layout.setMargin(true);

                        acc.addTab(layout, "Tab " + i);
                }
                else
                {
                        groupPanelOverview.add(panJVxPanel);

                        acc.addTab(((Component)panJVxPanel.getResource()), "Tab " + i);
                }
        }

        groupPanelOverview.add(new UICustomComponent(acc), formLayout1.getConstraints(0, 2, -1, -1));
}

The Accordion source code was copied from Vaadin Sampler:

sample = new Accordion();
sample.setHeight(100.0f, Unit.PERCENTAGE);
 
for (int i = 1; i < 8; i++) {
    final Label label = new Label(TabSheetSample.getLoremContent(), ContentMode.HTML);
    label.setWidth(100.0f, Unit.PERCENTAGE);
 
    final VerticalLayout layout = new VerticalLayout(label);
    layout.setMargin(true);
 
    sample.addTab(layout, "Tab " + i);
}

So, what are the most interesting parts in our code?

First, we add the JVx panel to another JVx panel. This is important to get support for translation. If it's not important for your, simply ignore the line:

groupPanelOverview.add(panJVxPanel);

The groupPanelOverview is a simple UIGroupPanel with UIFormLayout:

UIFormLayout formLayout1 = new UIFormLayout();

UIGroupPanel groupPanelOverview = new UIGroupPanel();

groupPanelOverview.setText("Overview");
groupPanelOverview.setLayout(formLayout1);

groupPanelOverview.add(labelName, formLayout1.getConstraints(0, 0));
groupPanelOverview.add(editOverviewName, formLayout1.getConstraints(1, 0));
groupPanelOverview.add(labelDescription, formLayout1.getConstraints(0, 1));
groupPanelOverview.add(editOverviewDescription, formLayout1.getConstraints(1, 1, -1, 1));

Our JVx button will be added to the native vaadin Accordion with following code:

acc.addTab(((Component)panJVxPanel.getResource()), "Tab " + i);

We don't add the JVx component itself, we use the wrapped resource. This is a simple vaadin component: com.vaadin.ui.Button

And finally, we add the Accordion as custom component to our JVx group panel:

groupPanelOverview.add(new UICustomComponent(acc), formLayout1.getConstraints(0, 2, -1, -1));

This code:

if (getApplication().getLauncher().isWebEnvironment())

is important for VisionX because the vaadin components aren't available in Swing, so we use this check for the supported environment.

So far, we mixed native vaadin components with JVx components. It's super easy to use, isn't it?

But it's also possible to use CSS for JVx components:

Css style for Button

Css style for Button

The button got the friendly style, which is defined in Vaadin CSS. Check some examples.

To add the friendly style class to the JVx button, simple add:

Style.addStyleNames(butNotification, "friendly");

This example is using predefined CSS from vaadin. It's also possible to set custom styles in your own css file. Simple follow this instructions.

This article covered the integration of native vaadin components into an existing JVx application with all advantages of vaadin.