Česky   |  Deutsch   |  English   |  Español   |  Français   |  Indonesia   |  日本語   |  한글   |  Polski   |  Português (BR)   |  Türkçe   |  中文   |  正體中文   |  Your Language  
Planet NetBeans is an aggregation of NetBeans related musings from all over the Blogosphere.
[RSS 1.0 Feed] [RSS 2.0 Feed]
[FOAF Subscriptions] [OPML Subscriptions]
Do you blog about NetBeans ? Add your blog to PlanetNetBeans.
Feed Subscriptions
APIDesign - Blogs (feed)
David R. Heffelfinger (feed)
Carsten Zerbst's Weblog (feed)
Winston Prakash's Weblog (feed)
NetBeans – Michael's blog (feed)
DukeScript (feed)
ProNetBeans (feed)
Paulo Canedo » NetBeans English (feed)
Anchialas' Java Blog (feed)
markiewb's blog (feed)
Need to find a title (feed)
Category: NetBeans | Software and Science (feed)
Roger Searjeant's blog (feed)
Inspiration and Expression » Netbeans (feed)
Adam Bien (feed)
Bernhard's Weblog (feed)
Michel Graciano's Weblog (feed)
Ramon.Ramos (feed)
Ozone and Programming » netbeans (feed)
NetBeans Ruminations » NetBeans (feed)
NetBeans – Java PDF Blog (feed)
Arun Gupta, Miles to go ... (feed)
Geertjan's Blog (feed)
.JARa's Bilingual Weblog (feed)
JavaFX Composer (feed)
The Java Jungle (feed)
Jesse Glick (feed)
Martin Grebac (feed)
The NetBeans Community Podcast (feed)
NetBeans Profiler (feed)
NetBeans for PHP (feed)
NetBeans Web Client (feed)
Rechtacek's (feed)
Virtual Steve (feed)
The Aquarium (feed)
Tinuola Awopetu (feed)
Insert Witty Irony Here (feed)
Netbeans – Gualtiero Testa (feed)
netbeans – James Selvakumar’s Blog (feed)
NetBeans – nB gUru (feed)
netbeans – Newsintegrator Blog (feed)
NetBeans – Praxis LIVE (feed)
NetBeans – TechAshram (feed)
Netbeans – There's no place like (feed)
Anuradha (feed)
Netbeans6/6.5 my best practices (feed)
Java Evangelist John Yeary (feed)
Neil's Dev Stuff (feed)
Computer says null; (feed)
NetBeans Adventures, Java and more (feed)
NetBeans – John O'Conner (feed)
NetBeans Community Docs Blog (feed)
The Netbeans Experience (feed)
NbPython/ jpydbg / pymvs (feed)
Shanbag's Blog (ರಜತ ಲೋಕ) (feed)
Wade Chandler's Programming Blog (feed)
Devlin's Lab (feed)
Big Al's Blog (feed)
Code Snakes (feed)
In perfect (spherical) shape (feed)
Van Couvering Is Not a Verb (feed)
Diego Torres Milano's blog (feed)
Vroom Framework (feed)
Messages from mrhaki (feed)
Jeff's Blog (feed)
Manikantan's Netbeans (feed)
Oliver Wahlen's Blog (feed)
Shuttle between Galaxies (feed)
Welcome to my live... (feed)
Devel Blog (feed)
diamond-powder (feed)
Antonio's blog (feed)
Where's my Blog?!

Powered by:    Planet

Last updated:
August 25, 2016 10:06 PM
All times are UTC

Sponsored by
sponsored by Oracle

visit NetBeans website
NetBeans – Michael's blog - August 25, 2016 09:21 PM
NetBeans rocks JShell

Some weeks ago I posted about “Cool stuff: NetBeans and JShell” [1]. Sadly, JShell did not observe the editor if the editor (e.g. gedit) had not been started from within the shell. Thus, you could not have used NetBeans as editor if the shell had been started within the NetBeans terminal window. I discussed this … Continue reading "NetBeans rocks JShell"

Geertjan's Blog - August 25, 2016 10:10 AM
Adding Some Color to the RebelLabs Developer Productivity Report 2016

I used to have a very nice colleague who would never disagree with me. He'd never say 'I disagree with you'. Instead, he'd always say, 'let me add some color to that', after which he'd proceed to, essentially, disagree with me. :-) [I miss you, Ashwin!] But it was a nice experience. He wasn't disagreeing, he was adding color.

In that light I'd like to look at an aspect of the RebelLabs Developer Productivity Report 2016. It wasn't released very long ago and has the following results for IDE usage:

On the face of it, things aren't looking so great for NetBeans! In fact, NetBeans is doing very badly indeed. You can't really talk about "the top three IDEs" anymore, there's clearly only "the top two IDEs". However, let's look a bit more closely and ask ourselves some questions. Yes, let's add some color to that!

ZeroTurnaround & Me

Let me start by saying I love the ZT team. I have known several members of ZT for a lot of many years.

Jevgeni I remember meeting at JavaZone in Norway many years ago when he was talking about his Aranea web framework; Anton I have done several JavaOne sessions with; the JRebel plugin for NetBeans is one of the most actively developed NetBeans plugins; Igor has created the most amazing MindMap plugin for NetBeans; I've talked to Simon at several conferences; Alan and Michael I met in Denmark and I claim some role in surfacing them in the community and getting them noticed by Jevgeni (watch this cool YouTube clip with Alan, Fabrizio, and me); Oleg I spent a crazy time with in the Bering Sea; Sang, Adam, and Geert who used to work there are guys I have known forever as well. And, on top of all that, ZeroTurnaround is a NetBeans partner.

So, again, I am really adding color here and seriously not trying to do anything other than that. I love ZT, OK.

Tone & Content

In the report: "Overall we received 2044 responses." Moreover, when I see the response to "What is your job description?", I don't see anything about "I am a student". In fact, the word "student" doesn't appear in the report. Nothing at all wrong with that, of course. The survey was not aimed at students at all.

Already one can feel the kind of color that can be added here. Slightly over 2000 respondents, which seems small to me. And no students.

Plus, it took quite a bit of motivating to get those 2000 respondents. Especially the last few hundred took some work, I saw quite a bit of activity in getting those, e.g:

You know who else didn't participate? The NetBeans community. On 1 March this year, there was a brief discussion on the NetBeans Dream Team mailing list. The NetBeans Dream Team is a group of volunteers outside of the NetBeans team and outside of Oracle. They're NetBeans enthusiasts who are recognized for their activism by being invited to join the group to share insights and activities and ideas around NetBeans. We discussed the RebelLabs productivity reports. Especially the fact that the tone of the reports is definitive and assertive, despite not covering at least the simplest of these concerns, i.e., a pretty low number of self-selecting respondents, none of whom are students which is a key demographic that NetBeans has targeted from the beginning.

My suggestion was that this year, in contrast to previous years where we were a bit sceptical too, we go full on for the survey, promote it to the community, to the NetBeans enthusiasts around the world, the mailing lists, etc. However, one of the people in the discussion suggested, bearing in mind our objections: "Instead of helping them with extra data points you might just publicly ask NetBeans users to NOT respond to RebelLabs surveys." I disagreed strongly because I love ZT! And ZT is a NetBeans partner, on top of that.

So, we did nothing. We let it go, knowing that by not promoting this to the NetBeans community, the results would probably be like they turned out to be. The results of the survey provide a limited view on a self-selecting segment of the Java community.

Reap & Sow

However, let's go a bit further. Given the limitations outlined above, which in themselves disqualify the results, or should disqualify the results from being used to say anything about the actual usage of the tools, is there an explanation for those 2044 respondents having responded in the way they did? Why did only 10% of those problematic non-student 2044 respondents pick NetBeans?

JetBrains is incredibly admirable for their conviction. JetBrains supports their tools without a second of doubt. Oracle, well, not so much. Sometimes yes, sometimes no. Sometimes lots of enthusiasm, sometimes just a bit, something nothing. The last time NetBeans had an evangelism team was in the days of Roman Strobl, I guess around 2007 or so, when NetBeans was part of Sun and when there were about 10 fulltime NetBeans evangelism staff (in addition to about 6 technical writers, of which I was one) constantly and consistently promoting NetBeans. There's nothing left of that. Well, just me, plus the NetBeans Dream Team, an unpaid volunteer force to be reckoned with, but not a paid staff strategizing and planning the best way to reach developers with tools etc. Meanwhile, JetBrains has been investing in that aspect of its organization to great effect. Kudos to them.

To add some color to the results, therefore, I tentatively suggest that they are a reflection of the conviction versus the ambivalence of the organizations behind those tools, as well as the staffing and strategies for promoting them. On this basis, the percentages mirror the backing that the tools have received from the organizations that sponsor them.

Apples & Pears

We need to go further still and ask the "why" question. What's the reason for the different levels of enthusiasm of these organizations for their tools? JetBrains and Oracle have completely different aims, of course. JetBrains is explicitly a tooling company. The key slogan, a really good one, is: "Whichever technologies you use, there's a JetBrains tool to match."

Oracle, on the other hand, is historically a database company and increasingly a Cloud company. In contrast to JetBrains, for Oracle tooling plays, at best, a supporting role, and is, at worst, an after thought. Though one would expect tooling to play a bigger role, it tends to fall a bit by the wayside in the final push to a technology release.

Facebook & Twitter

So, if the ZT survey cannot accurately reflect IDE usage, is there another way to conclusively do so. No. The only thing anyone can provide are very tentative indicators.

Here are some:

What does the above show? One thing I find interesting is that JetBrains is spending a lot of energy while not getting as compelling a result as the other two IDEs. Also note that normally Eclipse doesn't have as much engagement on Facebook as this week. The last few weeks have been special because of Eclipse Che, generating a lot of engagement. NetBeans, though, is clearly on top in terms of Facebook likes. Note also that there's never more than one or two new items on the NetBeans Facebook page per day. Sometimes nothing. Because we don't want the news from yesterday to get lost. So we add one new item every other day or so. A different strategy to JetBrains, clearly, which also has to contend with the fact that IntelliJ IDEA is only one of their tools. They have a lot to talk about, though it doesn't seem to result in a lot of new Facebook likes.

Next, let's take a look at Twitter followers. Below you see NetBeans, then JetBrains, then Eclipse. Again, NetBeans has the most followers, i.e., the most people interested in receiving tweets from one of the three IDEs is from people interested in NetBeans. Again, notice the disparity between the amount of tweets from JetBrains versus the considerably lower number of followers:

Of course, someone will say, this says nothing about what people are working with. Hmmm. I wonder about that. How many Twitter accounts do you follow of tools that you're not using? And if you want to see a comparison between real tool usage, take a look at the difference between the number of people using the Chrome plugin for NetBeans versus the Chrome plugin for IntelliJ:

That's a difference of about 50,000, which has been constant, plus or minus a few thousand, over the past years.

If you were to want to reach as many developers as possible, with your message, or your technology via a plugin, which of the three IDEs would you immediately suspect could be used to reach the largest number of people? Over on YouTube, look at the marked difference in views between two different YouTube clips, about the same technology, i.e., Oracle Developer Cloud Service, installed in Eclipse vs. installed in NetBeans:

The two YouTube clips were created in the same period. The Eclipse YouTube clip has less than 300 views, while the NetBeans equivalent has around 4000 views. Neither of those numbers are very high, which is probably because Oracle Developer Cloud Service is an extremely non-sexy topic. Nevertheless, the NetBeans views are orders of magnitude higher, clearly.

Of course, I am not arguing that NetBeans is the most popular IDE. I don't believe that to be true at all, in fact. Plus, that's not the point I am making here, in any way. No one can make that claim. I am simply adding color to the survey results, since these different statistics from completely different sources appear to indicate something different to what the survey suggests.

Intention & Abuse

Where it becomes dangerous is where the ZT survey is used as a stick to beat an IDE with. That was never the intention of the awesome people at ZT, though it is exactly what happens when surveys are released.

Surveys are always flawed and never present the full picture. Like when I argued with (ah, 'added color to') the RedMonk survey a few years ago, if we don't have the full climate picture, we shouldn't be doing the weather report. At the very least we should be extremely circumspect and not assert anything at all lest our assertions be abused in contexts for which they were never intended.

Adam Bien - August 25, 2016 07:12 AM
HAProxy, TomEE 7.01 Plus, Elasticsearch -- New Docklands Images Arrived

HAProxy, TomEE 7.0.1 Plus and Elasticsearch Docker images were added to github.com/AdamBien/docklands. Docklands already comes with minimalistic images for Postgress, DerbyDB,Tomcat, Payara Server (aka commercially supported GlassFish), WildFly, Weblogic and WebSphere Liberty Profile.

Docklands layering (image inheritance) aims for build speed, low memory overhead and productivity.

I'm using docklands as base for my consulting work and many microservices projects.

See you at Java EE Workshops at Munich Airport, Terminal 2 and particularly at Java EE 7 Microservices. Is MUC too far? Checkout http://javaeemicro.services

Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - August 24, 2016 03:14 PM
Oracle JET MOOC - Tips & Tricks (Part 1)

We're really pleased with the level of activity around the Oracle JET MOOC. Monday next week, when the 2nd week starts, we'll close registration, at which point we expect to have around 2,000 participants. The MOOC will run again, for free, in October, after OpenWorld and JavaOne.

We've picked up on some common problems on the Oracle JET forum and have put together some tips and tricks, as well as news and updates, here:

<span id="XinhaEditingPostion"></span>

We expect to release a similar YouTube clip part way through the 2nd and 3rd week of the course.

Geertjan's Blog - August 20, 2016 10:33 AM
Integrating Oracle Fusion Middleware MapViewer with Oracle JET

There are many map components in the world out there—and I have documented how to integrate several of them in an Oracle JET application, e.g., 3DCityDB, Mapbox, Leaflet, and LuciadRIA, as well as Oracle JET's ojThematicMap component

However, Oracle has its own map component, as described in detail below, which includes the Oracle Maps Javascript library:


Oracle Fusion Middleware MapViewer is a development toolkit for incorporating interactive maps and spatial analyses. It is optimized for use with Oracle Spatial and Graph. (The related Oracle blog is blogs.oracle.com/oracle_maps_blog.) Here below is how it looks when integrated into an Oracle JET application, with many thanks to my colleague Jayant Sharma, who made it happen and provided the instructions that follow, which I have successfully used and I can report that it works.

Instructions for integrating Oracle Fusion Middleware MapViewer with Oracle JET, assuming you have set up an Oracle JET application, e.g., via the Oracle JET QuickStart Basic template:

  1. Add the Oracle Maps V2 kit into js/libs as a folder named 'oraclemaps'. The kit can be downloaded from here and specifically here: http://download.oracle.com/otn/other/mapviewer/12c/12211/v2_122110_full.zip

  2. Modify "main.js" to include the various Oracle map libraries, in the requires.config "path" and "shim" sections. I.e., add these entries in the "paths" section:
    //File paths for Oracle Maps HTML5 API
    'omapsv2-hammer': 'libs/oraclemaps/v2/jquery/jquery.hammer-full.min',
    'omapsv2-i18n-properties': 'libs/oraclemaps/v2/jquery/jquery.i18n.properties-min-1.0.9',
    'omapsv2-mousewheel.min': 'libs/oraclemaps/v2/jquery/jquery.mousewheel.min',
    'omapsv2-rtree': 'libs/oraclemaps/v2/rtree/rtree-min',
    'omapsv2-fortknox': 'libs/oraclemaps/v2/fortknox-libs/fortknox-canvas',        
    'omapsv2_core': 'libs/oraclemaps/v2/oraclemapsv2_core'

    ...and these in the "shim" section:

    //Oracle Maps HTML5 API dependencies
    'omapsv2-i18n-properties':  ['jquery'],
    'omapsv2-hammer': ['jquery'],
    'omapsv2-mousewheel.min' : ['jquery'],     
    'omapsv2_core': {
       deps: ['jquery','hammerjs','omapsv2-fortknox','omapsv2-rtree','omapsv2-hammer','omapsv2-i18n-properties','omapsv2-mousewheel.min'],
       exports: 'OM'
  3. Modify the view of an Oracle JET module, e.g., "home.html", in the way it's done for the MapBox example, i.e., rewrite "home.html" to be the following and include "css/styles.css" containing "#map { width:100%; height:100%; }": 
  4. <STYLE TYPE="text/css">
      @import url(css/styles.css);
    <div id='map'></div>
  5. Modify the viewModel of an Oracle JET module, e.g., "home.js", to be as follows, and read the comments below to understand the code:
    define(['ojs/ojcore', 'knockout', 'omapsv2_core'],
        function (oj, ko) {
            function mainContentViewModel() {
                var self = this;
                self.handleAttached = function () {
                    /* */
                    if (OM !== undefined) {
                        //Where to load Oracle Maps HTML5 API resource files (fonts, css and icons et al):
                        //Default http method when fetching remote geospatial contents:
                    } else
                        console.log('OM not loaded');
                    var X = -77;
                    var Y = 38.9;
                    var initialZoom = 11;
                    //This function adds various map controls to the provided OM.Map instance:
                    var addMapControls = function (myMap)
                        //defines various properties for the navigation control:
                        var navConfig = {
                            orientation: 1,
                            style: OM.control.NavigationPanelBar.STYLE_ZOOM_BUTTONS_ONLY,
                            anchorPosition: 1
                        //creates the navigation control:
                        var navigationControl = new OM.control.NavigationPanelBar(navConfig);
                        // navigation control (and other map controls) are typically added
                        //to the map as map decorations:
                        //defines the basic properties for the map scale bars:
                        var sbConfig = {
                            format: "BOTH",
                            anchorPosition: 4,
                            endMarks: false
                        //defines the display style of the scale bars:
                        var sbStyle = {
                            thickness: 5,
                            color: '#257db3',
                            shadow: true
                        //creates the actual scale bar instance and sets the display style:
                        var scaleBar = new OM.control.ScaleBar(sbConfig);
                        //adds the scale bar to the map as another map decoration:
                    var showMap = function ()
                        //This is the DIV that will display the map; it needs to be passed into
                        //the map instance:
                        var mapDiv = document.getElementById('map');
                        if (!mapDiv)
                            console.log("Map container DIV not found!");
                        //Creates a new map instance. Notice we are not supplying a Universe
                        //like in helloworld.js, since the universe will be defined when we
                        //add the tile layer to the map. Every tile layer includes its own
                        //universe definition as part of the tile layer's configuration:
                        var map = new OM.Map(mapDiv, {mapviewerURL: ''});
                        //This is how we create an Oracle eLocation tile layer: by creating
                        //a new instance of the OM.layer.ElocationTileLayer class. Check
                        //the <a href="https://apidoc/index.html">API Doc</a> for other built-in tile 
                        //layers such as Bing maps:
                        var tileLayer = new OM.layer.ElocationTileLayer("elocation");
                        //Adds the tile layer to the map:
                        //creates a point object located at the given longitude and latitude: 
                        var point = new OM.geometry.Point(X, Y);
                        //Adds various map controls to the map:
                        //console.log('adding mapControls');
                        // set the initial map zoom level and center (same as the location marker):
                        //Now we can complete the initialization of the map. You must
                        //only call this method once.  Note however map layers can
                        //be added even after calling this method:
                    }; //showMap
                    // console.log('call showMap');
                    /*  */
                }; // handleAttached
            return new mainContentViewModel();

That's it. Run the project and you'll see the same as in the screenshot above.

Geertjan's Blog - August 19, 2016 04:15 PM
Translating Oracle JET Applications

The Oracle JET MOOC starts on Monday. When we talk about Oracle JET we always say that it solves "enterprise challenges". One of these is internationalization/localization/translation of JavaScript applications. Recently I started playing with the translation features of Oracle JET and they're pretty impressive. Really, if you want to create JavaScript applications that need to be translated, you should look no further than Oracle JET.

Let's start by looking at the result of a small sample I've been working on. Here's an application that can be switched to 4 different languages, with a screenshot of 3 of them below: 

Everything to achieve the above is documented in "Internationalizing and Localizing Applications" in the Oracle JET Developer Guide. This topic is also dealt with in the 3rd week of the Oracle JET MOOC.

There are several bits and pieces involved in this sample: 

  1. Bundled translations for Oracle JET components. Oracle JET components, such as the date/time picker that you see above, have already been translated. The translations are found in libs/oraclejet/dist/js/libs/oj/resources/nls.

  2. Custom translation bundles. Aside from the Oracle JET components, which have already been translated, Oracle JET provides a facility for storing and loading your own translations. Below, you can see a folder called "resources/nls", with subfolders for each of the languages I am supporting:

    In "main.js", I have this, which registers the "resources/nls/l10" structure and merges it with the translations that are provided by Oracle JET:
    config: {
        ojL10n: {
            merge: {
                'ojtranslations/nls/ojtranslations': 'resources/nls/l10'

    The most important file in "resources/nls" is the file named "l10.js", which could be named anything at all, so long as it matches the registration in "main.js" shown above. It looks like this, in my case:

      "root": {
        "date": "Date:",
        "greeting": "Good Morning"
      "ar": true,
      "fr": true,
      "cs": true
    In each of the folders that have been enabled above, i.e., "ar", "fr", and "cs", translations of the above texts are found, e.g., in "ar":

    Now, anywhere in our viewModel, we can use this statement to retrieve the greeting of the current locale:
  3. RTL Support. Bidirectional features are included too, read here, simply by setting the "dir" attribute of the "html" element to "rtl" and back to "ltr".

  4. Dynamic Locale Switching. Via the buttons you see above, the locale can be switched, as described here.

Following from the above, the complete code for the viewModel is as follows, focused on enabling the switching between locales, which will cause the translation bundles to be loaded dynamically:

define(['ojs/ojcore', 'knockout', 'ojs/ojbutton', 'ojs/ojdatetimepicker'],
    function (oj, ko) {
        function mainContentViewModel() {
            var self = this;
            self.formats = ko.observableArray(["english"]);
            self.date = ko.observable();
            self.greeting = ko.observable("Good Morning");
            self.localeDate = ko.observable();
            self.localeGreeting = ko.observable();
            self.setLang = function (data) {
                var newLang = '';
                switch (data) {
                    case 'Arabic':
                        newLang = 'ar-EG';
                    case 'Czech':
                        newLang = 'cs-CZ';
                    case 'French':
                        newLang = 'fr-FR';
                        newLang = 'en-US';
                    function () {
                        $('html').attr('lang', newLang);
                        if (newLang === 'ar-EG') {
                            $('html').attr('dir', 'rtl');
                        } else {
                            $('html').attr('dir', 'ltr');
        return new mainContentViewModel();

And here's the view:

<div data-bind="ojComponent: {component: 'ojButtonset', checked: formats}">
    <label for="arabic">Arabic</label>
    <input data-bind="click: function(){setLang('Arabic');}" 
           type="checkbox" value="arabic" id="arabic"/>
    <label for="czech">Czech</label>
    <input data-bind="click: function(){setLang('Czech');}" 
           type="checkbox" value="czech" id="czech"/>
    <label for="french">French</label>
    <input data-bind="click: function(){setLang('French');}" 
           type="checkbox" value="french" id="french"/>
    <label for="english">English</label>
    <input data-bind="click: function(){setLang('English');}" 
           type="checkbox" value="english" id="english"/>
<span style="font-size: 50pt" id="greeting" data-bind="text: localeGreeting"></span>
<span data-bind="text: localeDate"></span>
<input id="dateInput" type="text" 
    data-bind="ojComponent: {
        value: date,
        datePicker: {changeMonth: 'none', changeYear: 'none'}

That's it. And here's the sample code shown above:


A next step is to generate all the buttons automatically from JavaScript, i.e., there should be some way to provide new buttons to switch to new languages easily, without having to code them in HTML, i.e., in the viewModel, find the lists of available translation locales and create the buttons, and their logic, based on that. 

NetBeans – Michael's blog - August 18, 2016 05:08 PM
NetBeans Evening Cologne

On Sept. 9th 2016 the NetBeans Dream Team together with the Java User Group Cologne organize the first NetBeans Evening Cologne. From 6 pm till 9 pm you’ll get an evening full with latest information about NetBeans and Java. Meet the newest new features in NetBeans IDE, see the NetBeans roadmap, learn about features related … Continue reading "NetBeans Evening Cologne"

Geertjan's Blog - August 18, 2016 06:09 AM
Sign Up Free, Today: Oracle JET MOOC

A lot of work has gone into the preparation of something completely different—an enterprise JavaScript MOOC (massive open on-line course) via Oracle JET, which will start coming Monday, 22 August. Oracle JET is a set of best practices, recommendations, architectures, templates, and components for enterprise JavaScript applications.

There are over 1,000 subscribers to the MOOC so far. The MOOC will take 3 weeks of your time, the first week starting on Monday, 22 August. Each week is defined by one lesson, which is in 10 parts, each part consisting of a YouTube clip, each clip lasting no longer than about 10 minutes, together with self-study and homework assignments. Each of the two following weeks a new lesson will be made available. Each lesson ends with a quiz. Successful completion of all quizzes results in a certificate of completion. 

Lesson 1, entitled "Taking Off with Oracle JET", takes you on a tour of the reasoning behind Oracle JET and an exploration of its underpinnings. By the end of that lesson, you're able to create Oracle JET applications. You'll have learned about Oracle JET modules, components, and layouts. You'll have a really great basis for creating enterprise JavaScript applications. Lesson 2, entitled "Exploring the Skies with Oracle JET", gives you a structured approach to learning from the Oracle JET Cookbook, which is filled with a range of enterprise components, e.g., graphs and tables, and shows you how to use them and integrate them into your Oracle JET applications. Lesson 3, entitled "Into the Clouds with Oracle JET", shows you how to integrate with the world around Oracle JET, i.e., 3rd party components, internationalization, accessibility, security, etc.

Want to get a quick feel for how the MOOC will be? Part 1 (of 10 parts, which will be released next week) of the first lesson is already available:

&amp;lt;span id=&amp;quot;XinhaEditingPostion&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;

Sign up here!

NetBeans – Michael's blog - August 16, 2016 04:02 PM
Secure passwords

Because the access to special areas of Alumni (an application described in my book “Web Development with Java and JSF”) shall be restricted to members only, we need to restrict the access to authorized persons only. During the registration process, we ask the user to enter a password. This part is yet missing in the … Continue reading "Secure passwords"

Adam Bien - August 16, 2016 12:05 PM
Angular 2: Styling The Generated Host Tag

Angular 2 replaces / generates a "synthetic" tag for each component without any styling with the name specified in the selector

The component below:

import { Component } from '@angular/core';
  selector: 'hello-app',
  template: '<h1>Styling the host component</h1>',
export class AppComponent { }

generates the following markup:

 <h1>Styling the host component</h1>

Additional styling of the "host" tag can be added with the host object:

import { Component } from '@angular/core';
  selector: 'hello-app',
  template: '<h1>Styling the host component</h1>',
  host: {"class":"nice"}
export class AppComponent { }

which generates the following output:

<hello-app class="nice">
	<h1>Styling the host component</h1>

Putting the selector into angle brackets: selector: '[hello-app]' searches for an attribute, not a tag, with the name of the selector, e.g.:

<div hello-app></div>

See you at Java EE Workshops at Munich Airport, Terminal 2 and particularly at Building Angular 2 Applications and Building React Applications.

Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - August 14, 2016 07:00 AM
What Are Your Favorite NetBeans Features?

What are your favorite NetBeans features? Damir Demirović from Serbia answers that question today in a new article on JAXenter. An extract:

Read the article here: https://jaxenter.com/netbeans/damir-demirovic-my-five-favourite-netbeans-features

Geertjan's Blog - August 12, 2016 07:00 AM
Code Sharing for NetBeans Developers!

Through the years, a recurring request by developers everywhere—not least among NetBeans users—is a facility for collaborative development. In a new article on JAXenter, I share info on two platforms for snippet sharing and how neatly they integrate into NetBeans IDE.

Some extracts: 

The full article: https://jaxenter.com/netbeans/code-sharing-for-netbeans-developers

markiewb's blog - August 11, 2016 06:56 PM
Quicktip: How to customize the names of Maven project nodes

Since NetBeans 7.4 you can configure the name of Maven-based project via options at “Tools|Options|Java|Maven|Appearance”. No additional plugin is required.


For other useful features have a look at the “New and Noteworthy” pages at http://wiki.netbeans.org/NewAndNoteWorthy

Geertjan's Blog - August 10, 2016 07:00 AM
Favorite NetBeans Features!

The full article is here on JAXenter: https://jaxenter.com/netbeans/yesaya-athuman-my-five-favorite-netbeans-features

Adam Bien - August 10, 2016 06:59 AM
Oracle on Java EE 8 News, Monitoring, Sonar Setup, BCE Entities or 29th airhacks.tv Questions and Answers

90 live attendees from all over the world (according to chat: France, Nigeria, Costa Rica, Netherlands (...)) participated in the 29th edition of airhacks.tv starting with the "Oracle and Java EE 8" discussion including press releases, then I answered questions ranging from Akka interoperability, over Java EE monitoring, to file access from EJBs and Sonar Setup:

Any questions left? Ask now and see your topic discussed at the first Monday of the month, 6 pm CET.

See you at Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.

Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - August 09, 2016 10:28 AM
Learn Oracle JET in 3 Weeks

Oracle JET, the open source toolkit for enterprise JavaScript, targeted at mobile and web applications, was announced at JavaOne and OpenWorld last year. In February, it was open sourced at github.com/oracle/oraclejet. Soon you'll be able to take a free course on-line, which will introduce you to all the key topics and give you many exercises to do to guide you through the process of creating JavaScript enterprise applications in a simple and logical way:

Click here, to sign up, today!

NetBeans Ruminations » NetBeans - August 09, 2016 10:24 AM
JavaFX and NetBeans: Dynamically Loading Windows

The Swing-based window system in the NetBeans Platform has the concept of a window that is loaded at runtime. These windows derive from the class TopComponent and are registered using annotations, and are created using a handy wizard in the NetBeans IDE. Today I am going to show you how to do something similar with JavaFX components, using the default lookup of the NetBeans platform. My aim is to load an FXML file and display it on a tabbed pane.

I am using the source code from my previous blog entry as a starting point because I already had it handy. That main fxml file already had a tabPane, which is what I require in the GUI.

Window with basic menu

Application from the previous blog entry

I created a package called za.co.pellissier.javafxwindowsystem.api where the public API of my JavaFXWindowSystem will be located. To be able to add a component to the tabbed pane, the text to be displayed on the tab as well as a javafx.scene.Node object is needed. So I created an interface that windows will need to implement:

package za.co.pellissier.javafxwindowsystem.api;

import javafx.scene.Node;

public interface IJavaFXWindow {

    public Node load();

    String getWindowName();

There is a class called FXMLLoader that is able to load an fxml file and return a Node object representing its content. To save future implementers of this API some effort, here is an abstract class that handles the loading:

package za.co.pellissier.javafxwindowsystem.api;

import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;

public abstract class AJavaFXWindow implements IJavaFXWindow {
    private final String fxmlFileName;

    public AJavaFXWindow(String fxmlName) {
        fxmlFileName = fxmlName;
    public Node load() {
        try {
            URL resource = getClass().getResource(fxmlFileName);
            return (Node) FXMLLoader.load(resource);
        } catch (IOException ex) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
        return null;

That is all that there is to the API, for now. :)

Note: Remember to export the package (set it to public) if you want it to be visible to other modules!

So lets look at how it is used by the window system. In my MainWindowController class (the JavaFX controller for the main fxml file), I added this method:

    private void loadWindows() {
        Collection<? extends IJavaFXWindow> windows = 
        for (IJavaFXWindow window : windows) {
            Node win = window.load();
            String name = window.getWindowName();
            tabPane.getTabs().add(new Tab(name, win));

I called this method in the initialize() method after the menu items are loaded.

All that remains is to see how a new window can be added to the system. First, lets create a new module called JavaFXTestWindow to contain the new window. It needs dependencies on Lookup API and JavaFXWindowSystem (the module where the API is defined).

In the JavaFXTestWindow module, I created a new fxml file called testwindow.fxml using SceneBuilder, and generated a controller class using the NetBeans IDE. Now for the most important step… implementing that brand new API!

package za.co.pellissier.testwindow;

import org.openide.util.lookup.ServiceProvider;
import za.co.pellissier.javafxwindowsystem.api.AJavaFXWindow;
import za.co.pellissier.javafxwindowsystem.api.IJavaFXWindow;

@ServiceProvider(service = IJavaFXWindow.class)
public class MyWindow extends AJavaFXWindow implements IJavaFXWindow {

    public MyWindow() {

    public String getWindowName() {
        return "Test Me!";

The most important line is the @ServiceProvider annotation – if you leave that out, the default lookup will not be able to find the window!

After cleaning and building, here is the result!

FXML file loaded

FXML file loaded

There are certainly still improvements to be made to this implementation. It only emulates a single mode in the NetBeans Platform Window System. And it requires the user to manually create an additional class. But it is a good start! :)

Adam Bien - August 09, 2016 05:57 AM
How to merge javax.json.JsonObject instances

Combining multiple javax.json.JsonObject instances requires copying their contents into a single JsonObjectBuilder instance:

public void merge() {
	JsonObject dev = Json.createObjectBuilder().
			add("developer", "duke").
	JsonObject lang = Json.createObjectBuilder().
			add("language", "java").

	JsonObjectBuilder result = Json.createObjectBuilder();
	dev.entrySet().forEach(s -> result.add(s.getKey(), s.getValue()));
	lang.entrySet().forEach(s -> result.add(s.getKey(), s.getValue()));
	JsonObject merged = result.build();
	assertThat(merged.getString("developer"), is("duke"));
	assertThat(merged.getString("language"), is("java"));

Adding additional attribute to a JsonObject instance works similarly.

See you at Java EE Workshops at Munich Airport, Terminal 2, particularly at: Effective Java EE 7! Is MUC too far? Checkout effectivejavaee.com

Real World Java EE Workshops [Airport Munich]>

DukeScript - August 08, 2016 11:46 PM
Big Data with DukeScript

At the JCrete conference last week we had some DukeScript hacking sessions, and we were was asked for best practices when you have large data sets to display in a grid. One solution is paging. If you want to load all the data at once, here’s another solution.

Let’s assume we have a model like this:

@Model(className = "BigData", targetId = "", properties = {
    @Property(name = "values", type = Row.class, array = true)
final class DataModel {

    @Model(className = "Row", properties = {
        @Property(name = "firstName", type = String.class)
    public static class RowVMD {

The first thing you can do in order to improve performance is to check if your table data needs to be mutable. Very often it’s an easy win to add a simple attribute to your tabular data:

@Model(className = "BigData", targetId = "", properties = {
    @Property(name = "values", type = Row.class, array = true)
final class DataModel {

    @Model(className = "Row", properties = {
        @Property(name = "firstName", type = String.class, mutable=false)
    public static class RowVMD {

This “mutable=false” will create a plain value instead of an Observable and thus save memory and construction time. It makes sense even if you want to edit the data in the table. (You would then create also a mutable version of “Row”, copy the data of the selected element to this “EditableRow”, edit it, and replace the old Row in the BigData ViewModel with an updated new one).

But the main problem with displaying large datasets is a slow UI. If you want to, for example, display a table with 100.000 rows, your DOM will get really big and this will kill performance.

One way to deal with that is to “virtualize” your table. That means the table will behave as if it actually has 100.000 rows, while it only displays the 20 rows that are currently visible. The best way to model that in DukeScript is to register a custom component like this:

ko.components.register('big-table', {
    viewModel: function (params) {
        var self = this;
        self.originalValues = params.value;
        self.firstIndex = ko.observable(0);
        self.numVisible = ko.observable(0);
        this.visibleRows = ko.computed(function () {
            var visibleValues = self.originalValues().slice(self.firstIndex(), self.firstIndex() + self.numVisible() + 1);
            return visibleValues;
    template: {element: 'big-table-template'}

A component consists of a ViewModel and a template. Our ViewModel has only four properties, the original values of our BigData object, the index of the first visible row, and the number of visible rows. The fourth is a computed property derived from the other three. It contains the values of the rows that are currently visible.

The template is loaded from an element in the page. This way we can modify the layout when we add more properties, or if we e.g. want to switch from a table to a list. Here’s a simple example:

<script id="big-table-template">
        data-bind = 'scroll: $data'
        style='height: 100px; overflow-y: scroll;
        overflow-x: auto;
        position: relative;
        background: grey;'>
        <div class = 'scroll-dummy' style = 'height: 110px;' > < /div>
            <div class = 'big-table-table' data-bind = 'foreach: visibleRows' style = 'position: absolute; top: 0; left: 0; background: red;' >
                <div class = 'big-table-row' style = 'height: 50px;' > <span data-bind = 'text: firstName' ></span></div >

There’s a div that wraps everything. We can set a fixed height on it. In our case it’s 100px. It contains another div that acts as a “scroll-dummy”. The only purpose of this is to make the scrollbar behave as if we have lots of elements in our table. We’ll resize it later to match the height of all rows. On top of it there’s an element that wraps the rows. It can be a list, a table, or in this case, a simple div. It uses the foreach binding to display the visible rows.

Now we need to make this dynamic. You can use a custom binding for this. It calculates how many elements are visible and listens to scroll events in order to update the firstIndex property of our components ViewModel. And it moves our “big-table-table” to the view port of our virtualized control.

ko.bindingHandlers.scroll = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        var self = this;
        self.element = element;
        self.viewModel = viewModel;
        var scrollDummy = self.element.getElementsByClassName('scroll-dummy')[0];
        self.table = self.element.getElementsByClassName('big-table-table')[0];
        var maxPos = self.element.offsetHeight;
        var els = self.element.getElementsByClassName('big-table-row');
        var rowHeight = els[0].offsetHeight;
        self.viewModel.numVisible(maxPos / rowHeight);
        scrollDummy.style.height = rowHeight * self.viewModel.originalValues().length + "px";
        self.firstIndex = viewModel.firstIndex();
        self.viewModel.firstIndex.subscribe(function (newValue) {
            var scrollTop = self.element.scrollTop;
            if (self.firstIndex > newValue) {
                scrollTop -= rowHeight;
            self.table.style.top = (scrollTop < 0 ? 0 : scrollTop) + "px";
            self.firstIndex = newValue;
        self.element.addEventListener('scroll', function (e) {
            var scrollTop = self.element.scrollTop;
            self.viewModel.firstIndex(Math.floor(scrollTop / rowHeight));

As a result, you will only have DOM nodes for the nodes that are currently visible and a nice and responsive UI.

In order to make this work, you will need to register the custom binding and custom component. I’ve put them together in a file called “bigtable.js” and register them like this:

public final class BigTableBinding {
    private BigTableBinding() {
    @JavaScriptBody(args = {}, body = "")
    public static native void init();

Now you only need to make sure you call the init method before you bind the data:

static void onPageLoad() throws Exception {
        ui = new BigData();
        for (int i = 0; i < 1000; i++) {
            ui.getValues().add(new Row("index " + i));

Enjoy coding DukeScript!

Geertjan's Blog - August 08, 2016 10:06 AM
Most Unique Feature of NetBeans IDE!

What's NetBeans all about, what makes it special, why would anyone use NetBeans rather than something else, what are its key features, what distinguishes NetBeans from other tools, etc etc etc. Set aside those questions for a moment and take a look at this photo taken last week at JCrete:

That's a small part of the NetBeans community around the world, most of the above are members of the NetBeans Dream Team. And the enthusiasm that jumps out at you is why NetBeans is special. Yes, the Maven integration in NetBeans is awesome; yes, NetBeans makes working with Git a piece of cake; yes, if you're doing Java EE then NetBeans should really be your weapon of choice, etc etc etc. And NetBeans is also awesome when you build software on top of it.

But, beneath it all, is a group of fun people from all over the world—who have all kinds of different hobbies and interests, one of which is software development, which they all do in one way or another in/with/on NetBeans IDE.

In the pic, taken by Stephen Chin, are:

  • back row: Jose Pereda (Spain), John Kostaras (Greece), Paul Anderson (USA), Gail Anderson (USA), Jaroslav Tulach (Czech Republic), Kirk Pepperdine (Hungary), Sven Reimers (Germany), Timon Veenstra (Netherlands)
  • front row: Sven Ruppert (taking the place of Ivar Grimstad, who couldn't be found), Geertjan Wielenga (Netherlands), Toni "Crazy Screaming Guy" Epple (Germany), Zoran Sevarac (Serbia)

Adam Bien - August 08, 2016 09:03 AM
How to add an attribute to javax.json.JsonObject

Although javax.json.JsonObject implements Map<String, JsonValue> -- it is immutable. Any modification attempt results in UnsupportedOperationException:

    @Test(expected = UnsupportedOperationException.class)
    public void immutable() {
        JsonObject dev = Json.createObjectBuilder().build();
        dev.put("dev", JsonValue.NULL);

To add a new attribute to an existing JsonObject instance, you will have to copy it's attributes into a JsonObjectBuilder instance, add any attributes and eventually build a new instance:

package com.airhacks.jsonp;

import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import org.junit.Test;

public class JsonTest {

    static final String STATUS_KEY = "status";

    public void addAttributeToObject() {
        JsonObject dev = Json.createObjectBuilder().
                add("developer", "duke").
        String expected = "master";

        JsonObject devWithStatus = enrich(dev, STATUS_KEY, expected);
        assertThat(devWithStatus.getString(STATUS_KEY), is(expected));

    public JsonObject enrich(JsonObject source, String key, String value) {
        JsonObjectBuilder builder = Json.createObjectBuilder();
        builder.add(key, value);
                forEach(e -> builder.add(e.getKey(), e.getValue()));
        return builder.build();


See you at Java EE Workshops at Munich Airport, Terminal 2, particularly at: Effective Java EE 7! Is MUC too far? Checkout effectivejavaee.com

Real World Java EE Workshops [Airport Munich]>

Adam Bien - August 05, 2016 10:27 AM
Using Excel As Source For Unit Tests

Sophisticated business logic requires a high amount of high quality data for test purposes. Tabular data is easier maintainable in Excel then directly in Java code.

With Java 8 it is easy to provide a function which converts an Excel Row (actually a HSSF Row) into whatever POJO you like:

 Function pojoMapper() {
        return (row) -> {
            Iterator cells = row.cellIterator();
            return new Input(

A few additional lines of code convert a Stream<Row> into a Stream<POJO>:

public static <T> Stream<T> load(Function<Row, T> mapper,...) {
        int skipCount = 0;
        if (hasHeader) {
            skipCount = 1;
        String fileName = //...
        try (InputStream inp = new BufferedInputStream(new FileInputStream(fileName));) {
            try (XSSFWorkbook wb = new XSSFWorkbook(inp)) {
                XSSFSheet sheet = wb.getSheetAt(tab);
                Stream<Row> stream = StreamSupport.stream(sheet.spliterator(), false);
                return stream.skip(skipCount).map(mapper);

        } catch (IOException ex) {
            throw new IllegalStateException("Problems processing file: " + fileName, ex);

Parameterized JUnit tests can be used to define the locations of excel files and load the sheets representing different use cases, test suites or regression tests.

Hence the code above is reusable, andit was extracted and released as: https://github.com/AdamBien/sheetfit/ (the pronunciation is semi-accidental :-)). This one-class utility is also available directly from maven central:


Example is implemented as system test: https://github.com/AdamBien/sheetfit/tree/master/sheetfit-st.

Also checkout javaeetesting.com or come to MUC: http://workshops.adam-bien.com/about-testing.htm

Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - August 04, 2016 07:00 AM
Interface-Driven Java Formatter

Today at JCrete, Dan North and others suggested a really cool feature—the ability to format a Java source file based on the interfaces that the Java source file is implementing. The "Ordering" formatting options for Java source files in NetBeans IDE are quite detailed by default:

However, the new interface-driven formatting options, which I am implementing in a new tab (since the tab above is pretty full and can't be extended externally via a plugin anyway), enable the interfaces of the implementing class to determine the ordering of class members:

Here's Dan's notes on the above options:

Here's the code providing the GUI above, as well as the registration-related code for plugging the GUI into NetBeans IDE:


Now "all" that needs to be done is implement the logic behind the above GUI. Anyone is welcome to join in with this cool JCrete-driven feature! 

Adam Bien - August 02, 2016 04:39 AM
Sending An OPTIONS Request With Angular 2

The Angular 2 Http class does not offer an OPTIONS convenience method out-of-the box. Interestingly, all the major HTTP methods are supported: GET, POST, PUT, delete, patch and head, but the OPTIONS was not implemented. To perform an e.g. POST request, you can use the built-in method:

import { Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';

export default class XYZService{
    constructor(private http:Http){}

        return this.http.post(uri,payload).
        then(r => r.json()).

        return Promise.reject(error.messages || error);

For the initiation of an OPTIONS request you will have to rely on the generic request method of the same Http class:

        return this.http.request(uri,{method:'OPTIONS'}).
        then(r => r.json()).

See you at Java EE Workshops at Munich Airport, Terminal 2 and particularly at Building Angular 2 Applications or Building React Applications.

Real World Java EE Workshops [Airport Munich]>

Adam Bien - August 01, 2016 03:04 AM
Java EE 8 Plans, Oracles Statement, Performance Smoke, Software Quality Rules, Cross-Jars Alternatives or 29th airhacks.tv Questions and Answers

Questions for the 29th a airhacks.tv, Today (August, 1st) at 6pm CET (see archives):

  1. Java EE 8 news: semi-official Oracle plans for Java EE 8, JavaOne (discussion)
  2. Serving files without a WAR
  3. Java EE performance monitoring and results interpretation
  4. Software quality with Sonar and Java EE: rules, defaults and real world
  5. Accessing EJBs from EntityListener's
  6. Running "Server Smoke" on 141 Processors and 10 TB
  7. Cross-Jar @Alternative's
  8. Referencing Entity Manager from JPA Entities
  9. JAX-RS ExceptionMappers in internet-facing API
  10. EntityManager, serialization and clustering
  11. BCE: referencing JPA entities from other components

The questions above are going to be answered during the next "Airhacks Q & A" http://airhacks.io live. You can subscribe to the channel and / or for the next event: http://www.ustream.tv/channel/adambien (both is optional, no registration required to watch this event live).

If you still miss a question, ask at https://gist.github.com/AdamBien/48148f11f649dd756993a876f7354061, write a comment on this post, tweet your question with the hashtag "#airhacks" or mention me https://twitter.com/AdamBien.

See you at Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.

Real World Java EE Workshops [Airport Munich]>

NetBeans Ruminations » NetBeans - July 26, 2016 09:55 PM
JavaFX and NetBeans Actions

I was asked some very good questions in response my post about the JavaFX makeover for the NetBeans Platform! Questions with long and interesting answers, questions that sparked more questions in my mind. So here is the first post in response to those questions. :)

Is it possible to reuse normal NetBeans Platform actions?

For the purpose of this exploration, I decided to create a simple NetBeans Platform application to work with. A newly created one, with all of the latest infrastructure available (including annotations for registration). With one action for use today, and one window for another post to follow. So, we start off with this little application:

Simple application to transform

Simple application to transform

The action that I created is registered using annotations:

        category = "Edit",
        id = "za.co.pellissier.someaction.SomeAction"
        iconBase = "za/co/pellissier/someaction/clickme.png",
        displayName = "#CTL_SomeAction"
    @ActionReference(path = "Menu/File", position = 1300),
    @ActionReference(path = "Toolbars/File", position = 200)
public final class SomeAction implements ActionListener {

At compile time, these annotations are transformed into entries in the generated layer file. And at run time that gets loaded into the System FileSystem. Most days, you would not need to know any of that to work with actions. But today is not most days… :)

If you look at the module project where the action was created in Files view (after cleaning and building the module), you will see the generated-layer.xml file:

Generated layer file

Generated layer file

Looking at the content of the generated layer file, we can see where the action will be registered at runtime:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN"
    <folder name="Actions">
        <folder name="Edit">
            <file name="za-co-pellissier-someaction-SomeAction.instance">
                    bundlevalue="za.co.pellissier.someaction.Bundle#CTL_SomeAction" name="displayName"/>
                    methodvalue="org.openide.awt.Actions.alwaysEnabled" name="instanceCreate"/>
                <attr name="delegate" newvalue="za.co.pellissier.someaction.SomeAction"/>
                <attr name="iconBase" stringvalue="za/co/pellissier/someaction/clickme.png"/>
                <attr boolvalue="false" name="noIconInMenu"/>
    <folder name="Menu">
        <folder name="File">
            <file name="za-co-pellissier-someaction-SomeAction.shadow">
                <attr name="originalFile" stringvalue="Actions/Edit/za-co-pellissier-someaction-SomeAction.instance"/>
                <attr intvalue="1300" name="position"/>
    <folder name="Toolbars">
        <folder name="File">
            <file name="za-co-pellissier-someaction-SomeAction.shadow">
                <attr name="originalFile" stringvalue="Actions/Edit/za-co-pellissier-someaction-SomeAction.instance"/>
                <attr intvalue="200" name="position"/>

An internet search for the system file system reveals this wiki page which gives us the hint that the FileUtil class is going to be a useful one. And finding usages of that class reveals the following interesting method in org.netbeans.core.windows.view.ui.MainWindow:

    private static JMenuBar getCustomMenuBar() {
        try {
            String fileName = Constants.CUSTOM_MENU_BAR_PATH;
            if (fileName == null) {
                return null;
            FileObject fo = FileUtil.getConfigFile(fileName);
            if (fo != null) {
                DataObject dobj = DataObject.find(fo);
                InstanceCookie ic = (InstanceCookie)dobj.getCookie(InstanceCookie.class);
                if (ic != null) {
                    return (JMenuBar)ic.instanceCreate();
        } catch (Exception e) {
        return null;

This method is a great and simple example of how to call instanceCreate() for an item registered on the file system. So together with the information from last time, we now have the pieces of information to start implementing the solution. This time I created a file called mainwindow.fxml (remember to update JavaFXWindowManager to load this file):

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<AnchorPane prefHeight="371.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="za.co.pellissier.javafxwindowsystem.MainWindowController">
      <MenuBar fx:id="menuBar" prefHeight="25.0" prefWidth="600.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
      <TabPane fx:id="tabPane" layoutY="25.0" prefHeight="350.0" prefWidth="600.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="21.0" />

The easiest place to call the code that loads the menu items is in the initialize() method of the controller class. Note that some of the menus, like Window, causes a StackOverflowException when being loaded in this context. It happens because it in turn calls on the Window System that is being loaded. So for now, lets exclude those menus. I also created a layer file and removed some of the File menu actions (see below) for the same reason.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
    <folder name="Menu">
        <folder name="File">
            <file name="Separator3.instance_hidden"/>
            <file name="Separator4.instance_hidden"/>
            <file name="org-netbeans-modules-print-action-PageSetupAction.shadow_hidden"/>
            <file name="org-netbeans-modules-print-action-PrintAction.shadow_hidden"/>
            <file name="org-openide-actions-SaveAction.shadow_hidden"/>
            <file name="org-openide-actions-SaveAllAction.shadow_hidden"/>
            <file name="org-openide-actions-SaveAsAction.shadow_hidden"/>

So here is the controller class that does the basics of loading the actions and adding them to the JavaFX GUI, after a lot of debugging and hunting for ways to access the user friendly names for the actions.

You will notice several TODOs in the code, and there are probably more things to implement that I haven’t thought of yet. But at least it will point you in the right direction.

public class MainWindowController implements Initializable {

    private MenuBar menuBar;
    private TabPane tabPane;

     * Initializes the controller class.
    public void initialize(URL url, ResourceBundle rb) {
        FileObject systemConfigFile = FileUtil.getSystemConfigFile("Menu");
        FileObject[] menus = systemConfigFile.getChildren();
        for (FileObject menu : menus) {
            // skip the menus that cause a StackOverflowException
            if (menu.getName().equals("Window") || menu.getName().equals("GoTo")
                    || menu.getName().equals("Edit") || menu.getName().equals("View")) {
            Menu newMenu = new Menu(menu.getName());
            menuBar.getMenus().add(0, newMenu);
            FileObject[] items = menu.getChildren();
            // TODO Load sub-menus with their own menu items
            for (FileObject item : items) {
                try {
                    DataObject dobj = DataObject.find(item);
                    InstanceCookie ic = (InstanceCookie) dobj.getCookie(InstanceCookie.class);
                    if (ic != null) {
                        Object instance = ic.instanceCreate();
                        if (instance instanceof ActionListener) {
                            ActionedMenuItem menuItem = new ActionedMenuItem((ActionListener)instance);
                        } else if (instance instanceof JSeparator) {
                            // TODO Add logic to avoid two consecutive separators
                            newMenu.getItems().add(new SeparatorMenuItem());
                } catch (IOException | ClassNotFoundException ex) {
    private static class ActionedMenuItem extends MenuItem
        private final ActionListener listener;

        private ActionedMenuItem(ActionListener instance) {
            String displayName = "";
            if (instance instanceof AbstractAction) {
                displayName = ((AbstractAction) instance).getValue("displayName").toString();
            } else if (instance instanceof SystemAction) {
                displayName = ((SystemAction) instance).getName();
            // TODO Deal with & and mnemonics
            listener = instance;
            setOnAction(new EventHandler<ActionEvent>() {
                public void handle(ActionEvent e) {
                    try {
                        SwingUtilities.invokeAndWait(new Runnable() {
                            public void run() {
                                // TODO Create proper action
                    } catch (InterruptedException | InvocationTargetException ex) {
Window with basic menu

Window with basic menubar

Geertjan's Blog - July 23, 2016 10:49 AM
Twitter, Codebird, and JavaScript

In my "bower.json" file, I have a dependency set like this:

"codebird-js": "2.6.0"

That enables Codebird to be installed.

Next, I went to apps.twitter.com and created a new application, so that I now have a Consumer Key (API Key) and a Consumer Secret (API Secret).

<script type="text/javascript">
    var cb = new Codebird;
            function (response) {
                var statuses = response.statuses;
                for (var i = 0; i < statuses.length; i++){
                    var status = statuses[i];
                    var screen_name = status.user.screen_name;
                    var text = status.text;
                    console.log(screen_name + ": " + text);
            }, true);

The point of this blog entry is really to come to a point where you can see how to parse Twitter. Above, in bold, is the code needed for that. Printed out into the console you'll now see names/texts of those who have tweeted about NetBeans.

Geertjan's Blog - July 22, 2016 08:56 AM
OAuth and Oracle JET

OAuth is an open protocol to allow secure authorization in a simple and standard method from web, mobile, and desktop applications. Oracle JET includes a helper library for working with OAuth, though not OAuth itself, i.e., Oracle JET does not ship with OAuth. Instead, it provides a helper class that helps you manage OAuth tokens and requests, rather than including the OAuth client libraries that are needed. Also, there is documentation for the OAuth helper library in the Oracle JET Developer Guide, in a chapter named Using oj.OAuth in Your Oracle JET Application.

In your "define" block, you need to include "ojs/ojmodel", since that's where the OAuth class is provided. The OAuth class provides the methods you can use to initialize the oj.OAuth object, verify initialization, and calculate the authorization header based on client credentials or access token.

Once you have included "ojs/model", you initialize "oj.OAuth", as described in the chapter, e.g.:

self.myOAuth = new oj.OAuth('X-Authorization');

When you use the Oracle JET Common Model, you'll find the "oj.Collection.extend" enables you to reference your "oj.OAuth" object. Also see the related JavaScript documentation:


Here's all the code for a real "define" block that includes OAuth for working with Twitter. Take note of the bits in bold below, which are the statements relating to OAuth:

    function (oj, ko, $) {
        function HeaderViewModel() {
            var self = this;
            self.TweetCol = ko.observable();
            self.datasource = ko.observable();
            self.serviceURL = 'https://api.jublo.net/codebird/1.1/search/tweets.json';
            self.myOAuth = new oj.OAuth('X-Authorization');
            self.parseTweet = function (response) {
                return {
                    id_str: response['id_str'],
                    text: response['text'],
                    userName: response['user']['name']
            var Tweet = oj.Model.extend({
                urlRoot: self.serviceURL,
                parse: self.parseTweet,
                idAttribute: 'id_str'
            var myTweet = new Tweet();
            var TweetCollection = oj.Collection.extend({
                url: self.serviceURL + '?q=NetBeans',
                model: myTweet,
                oauth: self.myOAuth
            self.getData = function () {
                self.TweetCol(new TweetCollection());
                    success: function () {
                            new oj.CollectionTableDataSource(self.TweetCol())
                    error: function (jqXHR, textStatus, errorThrown) {
                        console.log('Error in fetch: ' + textStatus);
        return new HeaderViewModel();

In "main.js", the "credentials.js" file is loaded:

var prop;
    url: 'js/credentials.json',
    dataType: 'json',
    async: false,
    success: function (data) {
        sessionStorage.setItem('credentials', JSON.stringify(data));
    error: function (req, status, err) {
        console.log('something went wrong', status, err);

The "credentials.js" file has this content:

    "client_id": "blabla",
    "client_secret": "blabla",
    "bearer_url": "https://api.jublo.net/codebird/oauth2/token",
    "access_token": "blabla"

Above, Codebird is used. Codebird is a library that is commonly used to manage OAuth2 connections to Twitter. And, instead of setting up your own code, you can use Codebird's proxy service.

In the "define" block above, notice the "self.getData" at the end, which ties everything together, and is called from the view:

<button data-bind="click: getData, 
                   ojComponent: { 
                       component: 'ojButton', 
                       label: 'Get Data'}">Get Data</button>
    data-bind="ojComponent: {
            component: 'ojTable', 
            data: datasource,
	    columnsDefault: {headerStyle: 'text-align: left; white-space:nowrap;'}, 
                  {headerText: 'User ', field: 'userName'},
                  {headerText: 'Text', field: 'text'}

That's it. A complete sample scenario that uses OAuth with Oracle JET.

APIDesign - Blogs - July 22, 2016 05:33 AM
Become Polyglot by Learning Java!

I was invited to give a talk at CurryOn 2016 about Truffle called Become Polyglot by Learning Java!. It provoked tweets like: If you only watch one talk from @curry_on_conf, this one from @JaroslavTulach on Graal/Truffle is stunning. Here is its recording:

Or go to YouTube page.

--JaroslavTulach 05:33, 22 July 2016 (UTC)

Geertjan's Blog - July 21, 2016 09:29 AM
JBoss Data Virtualization with Oracle JET

I met with Cojan van Ballegooijen who is involved with the Red Hat JBoss Data Virtualization project. Read about that here:


I'm interested in setting up a scenario where Oracle JET could provide a dashboard on top of a VDB (virtual database).

Here's the steps we took to get started.

  1. We started by downloading the 6.3.0 Beta of JBoss Data Virtualization: http://developers.redhat.com/products/datavirt/download.

  2. After running "java -jar" on the JAR downloaded above, we had installed the product and had a folder named "EAP-6.4.0".

  3. In the folder "quickstarts/dynamicvdb-datafederation", there's a folder "src/teiidfiles", which we copied into the root, i.e., into the "EAP-6.4.0" folder.

  4. In the folder "standalone/configuration", there's a file named "standalone.xml", where we tweaked the reference to "jboss.dir" so that it pointed to the hardcoded location of the EAP-6.4.0 folder, i.e., there was a problem with slash escaping on Windows of the "jboss.dir" reference and to workaround that we hardcoded the path, for the data source with the jndi-name "java:/accounts-ds".

  5. Then we ran "bin/standalone.bat", the process started, the "teiidfiles" were loaded, and at this location we saw the JSON payload: http://localhost:8080/odata4/Portfolio/Accounts/CUSTOMER?$format=json

OK, great, we have the JSON, which provided the data from the VBD. Once we have JSON, the step to an Oracle JET dashboard is trivial, since Oracle JET has all kinds of hooks for working with JSON.

However, there's one stumbling block at this point and that is that authentication is needed for accessing our data. It seems that Keycloak is needed in this scenario:


That's the next step. Once that's done, then we have here a nice scenario for creating user interfaces on top of virtual databases created via JBoss Data Virtualization.