Česky   |  Deutsch   |  English   |  Español   |  Français   |  Indonesia   |  日本語   |  한글   |  Polski   |  Português (BR)   |  Türkçe   |  中文   |  正體中文   |  Your Language  
PlanetNetbeans
Planet NetBeans is an aggregation of NetBeans related musings from all over the Blogosphere.
Feeds
[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 127.0.0.1 (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)
Bistro! 2.0 (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)
Netbeans IDE Blog by Tushar Joshi, Nagpur (feed)
Devel Blog (feed)
diamond-powder (feed)
Antonio's blog (feed)
Where's my Blog?!

Powered by:    Planet

Last updated:
July 27, 2016 10:04 PM
All times are UTC

Sponsored by
sponsored by Oracle

visit NetBeans website
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:

@ActionID(
        category = "Edit",
        id = "za.co.pellissier.someaction.SomeAction"
)
@ActionRegistration(
        iconBase = "za/co/pellissier/someaction/clickme.png",
        displayName = "#CTL_SomeAction"
)
@ActionReferences({
    @ActionReference(path = "Menu/File", position = 1300),
    @ActionReference(path = "Toolbars/File", position = 200)
})
@Messages("CTL_SomeAction=Action!")
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"
                            "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
<filesystem>
    <folder name="Actions">
        <folder name="Edit">
            <file name="za-co-pellissier-someaction-SomeAction.instance">
                <!--za.co.pellissier.someaction.SomeAction-->
                <attr
                    bundlevalue="za.co.pellissier.someaction.Bundle#CTL_SomeAction" name="displayName"/>
                <attr
                    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"/>
            </file>
        </folder>
    </folder>
    <folder name="Menu">
        <folder name="File">
            <file name="za-co-pellissier-someaction-SomeAction.shadow">
                <!--za.co.pellissier.someaction.SomeAction-->
                <attr name="originalFile" stringvalue="Actions/Edit/za-co-pellissier-someaction-SomeAction.instance"/>
                <attr intvalue="1300" name="position"/>
            </file>
        </folder>
    </folder>
    <folder name="Toolbars">
        <folder name="File">
            <file name="za-co-pellissier-someaction-SomeAction.shadow">
                <!--za.co.pellissier.someaction.SomeAction-->
                <attr name="originalFile" stringvalue="Actions/Edit/za-co-pellissier-someaction-SomeAction.instance"/>
                <attr intvalue="200" name="position"/>
            </file>
        </folder>
    </folder>
</filesystem>

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) {
            Exceptions.printStackTrace(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">
   <children>
      <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" />
   </children>
</AnchorPane>

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">
<filesystem>
    <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"/>
        </folder>
    </folder>
</filesystem>

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 {

    @FXML
    private MenuBar menuBar;
    @FXML
    private TabPane tabPane;

    /**
     * Initializes the controller class.
     */
    @Override
    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")) {
                continue;
            }
            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);
                            newMenu.getItems().add(menuItem);
                        } else if (instance instanceof JSeparator) {
                            // TODO Add logic to avoid two consecutive separators
                            newMenu.getItems().add(new SeparatorMenuItem());
                        }
                    }
                } catch (IOException | ClassNotFoundException ex) {
                    Exceptions.printStackTrace(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
            setText(displayName);
            
            listener = instance;
            
            setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent e) {
                    try {
                        SwingUtilities.invokeAndWait(new Runnable() {
                            @Override
                            public void run() {
                                // TODO Create proper action
                                listener.actionPerformed(null);
                            }
                        });
                    } catch (InterruptedException | InvocationTargetException ex) {
                        Exceptions.printStackTrace(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;
    cb.setConsumerKey(
            "replace-with-consumer-key",
            "replace-with-consumer-secret");
    cb.__call(
            "search_tweets",
            "q=NetBeans",
            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);
</script>

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:

http://www.oracle.com/webfolder/technetwork/jet/jsdocs/oj.OAuth.html

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:

define(['ojs/ojcore', 
        'knockout', 
        'jquery', 
        'ojs/ojmodel', 
        'ojs/ojtable', 
        'ojs/ojcollectiontabledatasource'],
    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.datasource(null);
                self.TweetCol(new TweetCollection());
                self.myOAuth.setAccessTokenRequest(
                    JSON.parse(sessionStorage.getItem('credentials'))
                );
                self.TweetCol().fetch({
                    success: function () {
                        self.datasource(
                            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;
$.ajax({
    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>
<hr>
<table 
    data-bind="ojComponent: {
            component: 'ojTable', 
            data: datasource,
	    columnsDefault: {headerStyle: 'text-align: left; white-space:nowrap;'}, 
            columns:
               [
                  {headerText: 'User ', field: 'userName'},
                  {headerText: 'Text', field: 'text'}
               ]}">
</table>

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:

http://www.jboss.org/products/datavirt/overview

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:

https://access.redhat.com/documentation/en/red-hat-jboss-data-virtualization/6.3/security-guide/chapter-11-oauth-based-security-for-odata

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.

Geertjan's Blog - July 19, 2016 07:00 AM
Company Presentations on Oracle JET with NetBeans IDE

Today I spent some time with Oracle colleagues in presenting Oracle JET to a company in the Netherlands. The company was using a technology stack that included a front-end technology that needs to be modernized for various reasons and Oracle JET was presented to them as the way to bring the front-end of an application into the modern world of HTML5, CSS3, and JavaScript.

Of course, many small demos were done to make the key points of the benefits of Oracle JET. And those demos were all done in NetBeans IDE, with the great Oracle JET Support plugin!

Does your company want to modernize web front-ends? Take a look at Oracle JET, it's all open source and free, and available at http://github.com/oracle/oraclejet. We're doing company presentations on Oracle JET all over the world, if you're interested, let me know!

Adam Bien - July 18, 2016 04:06 AM
Oracle Commits To Java EE, WildFly Swarm, Payara Micro, Docker and Microservices, Smells Like CDI or the 28th airhacks.tv Questions and Answers

This time 110 live attendees participated in the 28th edition of airhacks.tv with topics from dynamic DI, over Oracle Java EE announcements, logging strategies over Payara and WildFly microservices, to introducing a new shiny hardware:

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 and particularly at Java EE 7 Microservices.


Real World Java EE Workshops [Airport Munich]>

APIDesign - Blogs - July 17, 2016 01:38 PM
Pitfalls of APIReviews

There are two pitfalls of an APIReview. Either there is no code to review or there is too much code already written. The too little code case can easily be fixed. As Linus Torwalds use to say: Talk is cheap. Show me the code!

However what to do when APIReview brings in complex, complete solution with code almost ready for integration? Isn't that insulting? What kind of review one is supposed to perform then? Claim that the solution is completely wrong? That won't make the author happy. On the other hand coming for an architecture advice with fully working version isn't polite to reviewers either. Shall we read it as: Look how great I am! Approve the APIReview now!

Maybe there is a way to handle such review as well. But it remains to be seen if it works. Wish me luck.

--JaroslavTulach 13:38, 17 July 2016 (UTC)

APIDesign - Blogs - July 15, 2016 05:52 PM
Test your APIs Easily with Maven SigTest Plugin

The NetBeans API & Maven community (e.g. me and Miloš Kleint) is proud to announce the immediate availability of sigtest-maven-plugin. Signature testing has never been easier: just follow the tips on the SigTest main page and you'll never make an incompatible change since then!

Read TheAPIBook and let NetBeans SigTest Maven plugin look over you and make you great API designer! Enjoy!

--JaroslavTulach 17:52, 15 July 2016 (UTC)

Adam Bien - July 15, 2016 04:29 AM
July 2016: Java is #1 And Raising

The Java programming language becomes even more popular (19.804%) and gains 2.08%. Second is the C programming language (12.238%) which lost 3.91% -- the gap is larger. C was number #1 in 2001.

Java is also doing well comparing the "Monthly Commits" of JavaScript, C, Clojure, Scala and Go.

One of the recurring airhacks.tv questions is: "As I student, should I still invest in Java?" :-)

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 - July 14, 2016 01:17 PM
JSX in NetBeans IDE 8.2

JSX is a XML-like syntax extension to ECMAScript without any defined semantics. Many more details about it can be found here:

https://facebook.github.io/jsx/

JSX is popular in the React community which "recommend[s] using JSX because it is a concise and familiar syntax for defining tree structures with attributes. It's more familiar for casual developers such as designers." Many more details about that can be found here:

https://facebook.github.io/react/docs/jsx-in-depth.html

Many NetBeans IDE users have been asking for JSX support in NetBeans IDE, since they are using React:

https://netbeans.org/bugzilla/show_bug.cgi?id=250778

As you can see from the above, the NetBeans team has added parsing and lexing support for JSX over the past few days.

Let's take a look at the result, using this repo as an example project to try out JSX support in NetBeans IDE:

https://github.com/reactjs/react-tutorial

Here's what I see in a very (very very) recent NetBeans IDE build (click to enlarge the image):

Contrast the above to the same file opened in the current release of NetBeans IDE, i.e., NetBeans IDE 8.1, to see the difference:

Great news, isn't it? :-) At this point, don't expect extensive support for JSX or for React. However, as you can see above, at least you can now edit your files without there being error markings everywhere, which made NetBeans IDE impossible to work with when working with JSX.

Adam Bien - July 14, 2016 07:10 AM
xplr: Utility For Migrations To Maven

Java projects without dependency management directly rely on JARs contained in the project structure for compilation and deployment purposes.

A migration to maven requires the analysis of the JARs origin. All JARs needs to be replaced by dependencies defined in Maven's pom.xml. Sometimes the used JARs already contain maven information, in some cases the meta information is stored in the JAR's manifest.mf.

xplr is a self-contained, 15 kB, Java 8 CLI utility, which recursively traverses folders, searches for JARs and extracts any pom or manifest information. xplr also generates the mvn install:install-file statements which help you to install any proprietary libraries to the maven repository.

Applied to itself with java -jar target/xplr.jar . xplr produces the following output:


(...)
#####################################
Directory: ./target
#####################################

# Jar: ./target/xplr.jar
## Manifest: 
## Package: com.airhacks.xplr
Archiver-Version:Plexus Archiver
Built-By:abien
Created-By:Apache Maven 3.3.3
Build-Jdk:1.8.0_77
Manifest-Version:1.0
Main-Class:xplr.Explorer

## POM: 
<dependency>
 <groupId>com.airhacks</groupId>
 <artifactId>xplr</artifactId>
 <version>0.0.1</version>
 <packaging>jar</packaging>
</dependency>
## MVN install command: 
mvn install:install-file -Dfile=./target/xplr.jar 
-DgroupId=com.airhacks -DartifactId=xplr -Dversion=0.0.1 -Dpackaging=jar
---
(...)

With two parameters: java -jar xplr.jar [FOLDER] [CLASS NAME] xplr lists all JARs containing the specified class name (excerpts are supported). E.g.

java -jar target/xplr.jar . Injector will find:

#####################################
Directory: ./src/test/jars
#####################################

# Jar: ./src/test/jars/afterburner.fx-1.6.2.jar
## Manifest: 
## Package: com.airhacks.afterburner.configuration
Archiver-Version:Plexus Archiver
Built-By:abien
Created-By:Apache Maven 3.2.1
Build-Jdk:1.8.0_31
Manifest-Version:1.0

## POM: 
<dependency>
 <groupId>com.airhacks</groupId>
 <artifactId>afterburner.fx</artifactId>
 <version>1.6.2</version>
 <packaging>jar</packaging>
</dependency>
## MVN install command: 
mvn install:install-file -Dfile=./src/test/jars/afterburner.fx-1.6.2.jar 
-DgroupId=com.airhacks -DartifactId=afterburner.fx -Dversion=1.6.2 -Dpackaging=jar
---


xplr is apache licensed GitHub project: https://github.com/AdamBien/xplr. First release is available for download (15 kB).

Happy migrations! 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]>

Adam Bien - July 13, 2016 09:11 AM
CDI smells, Oracle and Java EE 8, JAX-RS, Logging, Microservices, Monitoring or 28th airhacks.tv Questions and Answers

Questions for the 28th airhacks.tv, Today (July, 13th) at 6 pm CET:

  1. Java EE 8 News
  2. New server (the real hardware): the part list.
  3. Oracle says it is 'commmitted' to Java EE 8
  4. microprofile.io announcement
  5. Wildfly-Swarm, Payara Micro and the relation to microservices
  6. Dynamic injection into @Stateless EJBs
  7. Handling ViewExpiredException in JSF
  8. Managing JAX-RS clients on servers
  9. Accessing GlassFish / Payara logifles from the browser
  10. Is overusing CDI a code smell?
  11. JAX-RS MessageBodyWriter and Singleton challenges
  12. How to approach logging in microservices?
  13. Monitoring Java EE methods

Ask questions during the show via twitter mentioning me: http://twitter.com/AdamBien (@AdamBien) or using the hashtag: #airhacks. You can join the Q&A session live each first Monday of month, 6 P.M at airhacks.tv or http://www.ustream.tv/channel/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]>

Geertjan's Blog - July 13, 2016 08:27 AM
NetBeans Platform: An Ideal Platform for Scientific Computing

The session catalog for JavaOne 2016 is available here:

https://oracle.rainfocus.com/scripts/catalog/oow16.jsp?event=javaone&search.event=javaone

One of the entries you'll find there is this one: 

Interesting. A NetBeans Platform application that I had never heard of before. It looks like this:

And here's more info about it:

The above comes from here:

https://www.janelia.org/confocal-imagery-management-and-analysis-tools

I'm looking forward to attending this session at JavaOne this year! 

Geertjan's Blog - July 12, 2016 07:00 AM
Gallery Demos for JavaScript: Galleria.io

Following on from part 2, in this part we add Galleria.io to our set of dependencies in 'bower.json':

"dependencies": {
    "oraclejet": "2.0.2",
    "galleria": "1.4.2"
}

Here's the source code:

https://github.com/GeertjanWielenga/GalleriaDemos/tree/master/Galleria3-Galleria.io/app

The project structure is as follows:

Since Galleria.io is not an AMD module, we need to shim in the 'require.config':

shim: {
   'jquery': {
       exports: ['jQuery', '$']
   },
   'galleriaio': ['jquery']
}

The end result looks like this:

And, again, a Knockout component is created and used like this:

<div data-bind="component: {name:'galleria', 
    params: {
      uniqueID: '1',
      width: 300,
      height: 300,
      images: [
        'images/galleria1.jpg',
        'images/galleria3.jpg',
        'images/galleria4.jpg'
      ]
    }
}"></div>

Geertjan's Blog - July 11, 2016 07:00 AM
Gallery Demos for JavaScript: JQuery UI Accordion

Continuing from the first part, let's now move towards modularity via Require and data bindings via Knockout. 

Here is the application:

https://github.com/GeertjanWielenga/GalleriaDemos/tree/master/Galleria2-Knockout/app

The project structure is like this, which looks a lot like the structure of an Oracle JET application, though an Oracle JET template was not the starting point of the below. Instead, I started with a plain ordinary HTML/JavaScript application and built up the structure from there, i.e., as a normal JavaScript application:


Here the JQuery UI Accordion component is used, which looks as follows in this case: 

To make sure that the versions of the various libraries work together, instead of getting hold of JQuery, JQuery UI, Require, and Knockout separately, I'm getting hold of all of them at once via Oracle JET in 'bower.json':

"oraclejet": "2.0.2"

Each gallery makes use of a Knockout component created in the project, which is used as follows: 

<div data-bind="component: {name:'galleria', 
    params: {
      uniqueID: '1',
      images: [
        'images/galleria1.jpg',
        'images/galleria3.jpg',
        'images/galleria4.jpg'
      ]
    }
}"></div>

In the next part, we'll look at a different gallery component and set up the same kind of project structure to see how things work there.

Geertjan's Blog - July 10, 2016 07:00 AM
Gallery Demos for JavaScript: PrimeUI Galleria

I'm looking at different image gallery components as examples of how to work with them in the context of Oracle JET. Also, these scenarios are example of how to migrate from non-Oracle JET applications to Oracle JET applications.

Here's the first, making use of the PrimeUI Galleria component:

https://github.com/GeertjanWielenga/GalleriaDemos/tree/master/Galleria1-Default/app

The structure of the application is like this: 


Here's how the component looks:

In the "bower.json" file, there is a single dependency:  

"primeui": "4.1.12"

In fact, this scenario is a plain normal JavaScript scenario that makes use of PrimeUI. No modularity, etc, just plain simple PrimeUI.

To get from the above scenario to an Oracle JET application, you'd need to include Require (for migration modularity) and Knockout (for migration to Knockout components and data bindings). That's the topic of the next blog entry.

Geertjan's Blog - July 08, 2016 07:00 AM
Timeline in Oracle JET

Let's take the "ojTimeline" component from the Oracle JET component library, as described here in the Oracle JET Cookbook, while taking note of the format of the related JSON file here. Then, downloading that file into our Oracle JET application and changing the details in the JSON file, let's recreate the NetBeans Roadmap in Oracle JET, with this result:

Here's the business logic in JavaScript, i.e., the "define" block, including a selection listener:

define(['text!../../seriesOneData.json', 'knockout', 'ojs/ojtimeline'],
    function (file, ko) {
        function mainContentViewModel() {
            var self = this;
            self.selected = ko.observable("Nothing is selected.");
            var content = JSON.parse(file);
            self.series = ko.observableArray(content)();
            self.optionChangeListener = function (event, data) {
                for (var i = 0; i < content.length; i++) {
                    if (content[i].id == data['value']) {
                        self.selected(content[i].title);
                    }
                }
            };
        }
        return new mainContentViewModel();
    });

And here's the HTML view that renders the above:

<div data-bind="ojComponent:{
    component: 'ojTimeline',
            majorAxis: {scale: 'years'},
            minorAxis: {scale: 'quarters'},
            start: new Date('Oct 1, 2013').toISOString(),
            end: new Date('Oct 31, 2016').toISOString(),
            optionChange: optionChangeListener,
            selectionMode: 'single',
            series: [{ 
                id: 's1',
                emptyText: 'No Data.',
                items: series,
                label: 'NetBeans Roadmap'
            }],
}" style="width: '100%'; height: 250px"></div>
<hr>
<h2>Selected: <span data-bind="text: selected"></span></h2>

Adam Bien - July 07, 2016 10:00 AM
Validating JsonObjects In JAX-RS With Bean Validation And Java EE 7

Java EE 7 introduced parameter validation for managed beans (CDI / EJB). This feature can be used to implement a ConstraintValidator for JsonObject parameters of JAX-RS resources:

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 - July 07, 2016 07:00 AM
Tag Cloud in Oracle JET

Here in the Oracle JET Cookbook the Oracle JET Tag Cloud is described. Here's the JSON file that is used there, which I have put in the "public_html" folder of my project.

What we'll create is the same as in the Cookbook, except we'll parse the JSON file with "JSON.parse" and we'll use a "define" block.


Here's a 'define' block for working with the "ojtagcloud" component:

define(['text!../../socialNetworks.json', 'ojs/ojtagcloud'],
    function (file) {
        function mainContentViewModel() {
            var self = this;
            self.tags = [];
            var content = JSON.parse(file);
            for (var i = 0; i < content.length; i++) {
                var network = content[i];
                self.tags.push({
                    id: network["id"],
                    label: network["id"],
                    value: network["total"],
                    shortDesc: network["id"] + ': ' + network["total"] + '%'
                });
            }
        }
        return new mainContentViewModel();
    });

Then here's the view:

<p style="font-weight:bold;text-align:center;">
  Social Networks Used by US Internet Users (Ages 14-54)
</p>
<div data-bind="ojComponent:{
        component: 'ojTagCloud',
                layout: 'cloud',
                items: tags
    }" >
</div>

Geertjan's Blog - July 06, 2016 07:00 AM
JQuery UI Datepicker Widget and Oracle JET

The jQuery UI Datepicker is a popular component. Let's integrate it into an Oracle JET application. Oracle JET is an open application architecture, together with a set of components, based on open source libraries, providing a logical framework within which components such as the jQuery UI Datepicker can be organized:

For background on this topic, see this YouTube clip by JB Brock:

https://www.youtube.com/watch?v=XcPcaSbaHFg

Take the following steps:

  1. Get the 'datepicker.js', from somewhere. For example, use Bower to add 'jquery-ui' to your project.

  2. In 'main.js', point to the folder where all the 'ui' components are found:
    'jqueryui': 'libs/jquery-ui/ui/', 
  3. Reference the CSS file below in your 'index.html':
    <link rel="stylesheet" 
        href=" //code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"/>
    
  4. In your viewModel, add the 'datepicker' component in the 'define' block, while creating an observable property to hold the selected date and a callback function to handle selection:
    define(['ojs/ojcore', 'knockout', 'jqueryui/datepicker'],
        function (oj, ko) {
            function mainContentViewModel() {
                var self = this;
                self.selectedDate = ko.observable();
                self.dateSelector = function (dateText, inst) {
                    self.selectedDate(dateText);
                };
            }
            return new mainContentViewModel();
        });
  5. In your view, use the 'datepicker' component (while making sure to use the 'jqueryUI' binding, as pointed out in the YouTube clip above), using the "onSelect" option provided by the datepicker as a link to the view above, while providing a span element to display the selected date:
    <div 
         data-bind="jqueryUI: {
             component: 'datepicker', onSelect: dateSelector
         }">
    </div>
    <hr>
    Selected date: <span data-bind="text: selectedDate"></span>

That's it! Now you should see the datepicker and you should also see that the selected date is shown too.

Helpful links:

Geertjan's Blog - July 05, 2016 01:34 PM
Plotting Data on World Maps with Oracle JET

Our requirement is to use Oracle JET to show data on a world map, e.g., the number of employees in our organization working in various countries around the world. Below you see an example—three different ranges represented by colors on the map:

To get to the above point, let's start with the simplest imaginable world map scenario with Oracle JET's built-in maps for ojThematicMap.

Here's the view:

<div id='thematicMap-container'>
    <div id='thematicMap1' data-bind="ojComponent:{
            component: 'ojThematicMap',
                basemap: 'world',
                areaLayers: layers
        }" 
         style="height:500px;width:100%">
    </div>
</div>

Here's the viewModel:

define(['ojs/ojcore',
    'knockout',
    'ojs/ojthematicmap'],
        function (oj, ko) {
            function mainContentViewModel() {
                var self = this;
                self.layers = [{layer: 'countries'}];
            }
            return new mainContentViewModel();
        });

And here's the map that results from the simple code above:

However, you're more than likely to be in a situation where you're getting data from somewhere, e.g., XML or JSON, with info that you'd like to display on the map.

Here's a GeoJSON file that we can use as the starting point of our scenario:

https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json

We'll do the same thing as the earlier blog entry about Brazil, i.e., include the file above into your application, as explained earlier. Now, open the file, and add some more data into it, imagining that this data needs to be visualized on the map. The data you add needs to be in the "properties" section of some/each of the entries in the file. Below, you see that I have added "employees:2000" to the entry for United States of America. Do the same for a few of the other countries, i.e., add some random data into various properties sections to simulate some additional data that we want to be able to work with:

Now, we're in a scenario very similar to this one:

http://www.oracle.com/webfolder/technetwork/jet/uiComponents-thematicMap-default.html

Adapting our scenario to the sample above, here's the view:

<div id='thematicmap-container'>
    <div id='thematicmap1'
         data-bind="ojComponent:{
            component: 'ojThematicMap',
                basemap: 'Foo',
                mapProvider: mapProvider,
                areaLayers: layers
                }"
                 style="width:100%; height:400px;">
    </div>
    <div id='legend1' data-bind="ojComponent: {
      component: 'ojLegend',
          halign: 'center',
          orientation: 'horizontal',
          title: 'No. of Employees',
          titleHalign: 'center',
          titleStyle: 'font-size:14px;font-weight:bold;',
          textStyle: 'font-size:14px;',
          sections: legendSections
          }"
           style="width:100%; height:50px;">
  </div>
</div>

And here's the viewModel:

define(['text!../countries.geo.json',
    'ojs/ojcore',
    'knockout',
    'ojs/ojthematicmap', 'ojs/ojlegend'],
        function (geo, oj, ko) {
            function mainContentViewModel() {
                var self = this;
                self.mapProvider = {
                    geo: JSON.parse(geo),
                    propertiesKeys: {
                        id: 'name',
                        longLabel: 'name'
                    }
                };
                self.legendSections = [{items: [
                            {text: "0-500", color: '#FF0000'},
                            {text: "501-1000", color: '#0000CC'},
                            {text: "1001-2000", color: '#3AA54F'}
                        ]}];
                var getEmployeeColor = function (employees) {
                    if (employees <= 500)
                        return '#FF0000';
                    else if (employees <= 1000)
                        return '#0000CC';
                    else if (employees <= 2000)
                        return '#3AA54F';
                };
                var getStateId = function (state, stateIdMap) {
                    for (var id in stateIdMap) {
                        if (stateIdMap[id] == state)
                            return id;
                    }
                };
                var getEmployeeData = function (dataContext) {
                    var areaData = [];
                    var features = JSON.parse(geo).features;
                    for (var i = 0; i < features.length; i++) {
                        var name = features[i]["properties"]["name"];
                        var employees = features[i]["properties"]["employees"];
                        areaData.push({
                            id: 'a1',
                            location: getStateId(name, dataContext.ids),
                            color: getEmployeeColor(employees)
                        });
                    }
                    return areaData;
                };
                self.layers = [
                    {
                        layer: 'countries',
                        areaDataLayer: {id: 'adl1', areas: getEmployeeData}
                    }];
            }
            return new mainContentViewModel();
        });

The trickiest bit above is the parsing of the JSON. Take a look, in particular, at the piece of code in bold above.

Geertjan's Blog - July 04, 2016 10:07 AM
YouTube: Oracle JET, Maps, Java EE, and NetBeans IDE

During JavaOne Latin America, last week, Yolande from OTN did a NightHacking interview with me about Oracle JET.

Here it is, in 10 minutes, covering Oracle JET, Java EE, maps, the ojThematicMap component in Oracle JET, and NetBeans IDE:

Related reading:

Adam Bien - July 04, 2016 08:50 AM
Comes Java EE With The Smallest Docker Images?

Are Java EE application servers too fat for microservices? You will find the answer in the following 6 min screencast:

I used for the evaluation the docker images from docklands and the project ping as sample application. See also: The Memory Usage of Java EE 7 Application Servers Running On Docker and The Overhead Of Java EE Application Servers and On Stage Microservices Hacking at InfoShare

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


Real World Java EE Workshops [Airport Munich]>

Geertjan's Blog - July 02, 2016 08:49 AM
Key Promoter Plugin for NetBeans IDE 8.1

I've reworked the Key Promoter plugin a bit.

http://plugins.netbeans.org/plugin/55751/key-promoter

The status bar (assuming you're using NetBeans IDE 8.1 and have installed the plugin for NetBeans IDE 8.1) now displays the keyboard shortcut of the most recently used action. In the screenshot below, notice the green display area in the status bar, i.e., at the bottom of the screenshot below, which is provided by the plugin, displaying info about the most recently used action:

However, a few actions are not displayed, because they're not logged when invoked, something which needs to be fixed, i.e., the fact that these are not logged into 'uigestures' means that they cannot be picked up by the plugin:

  • Alt-Shift-Up/Down (Move Line Up/Down) 
  • Ctrl-Shift-Up/Down (Copy Line Up/Down) 
  • Ctrl-Shift-R (Toggle Rectangular Selection)

Probably others too. Would be great to hear about any actions that aren't picked up by the plugin!

The sources of the plugin are here:

https://github.com/GeertjanWielenga/NetBeansKeyPromoter

 

markiewb's blog - July 01, 2016 06:23 PM
Quicktip: Search for Maven artifacts from within NetBeans IDE

Open the context menu of the Maven Repository node in the services and start your search!

2016-07-01_20h19_17.png


Geertjan's Blog - July 01, 2016 11:31 AM
Integrating iTunes into Oracle JET

Here's a search string for iTunes:

https://itunes.apple.com/us/rss/toppaidapplications/limit=10/genre=6014/json

Let's integrate that into an Oracle JET application, with this result:

After a bit of fiddling with the parsing of the JSON, this is how I built up the table above.

Here's the view:

<table data-bind="ojComponent: {component: 'ojTable',
    data: dataSource,
    columns: [
        {headerText: 'Name', field: 'name'},
        {headerText: 'Price', field: 'price'}
    ]
        }">
</table>

Here's the viewModel: 

define(['ojs/ojcore', 'knockout', 'ojs/ojtable'
], function (oj, ko) {
    function homeContentViewModel() {
        var self = this;
        self.data = ko.observableArray();
        $.getJSON("https://itunes.apple.com/us/rss/toppaidapplications/limit=10/genre=6014/json").
                then(function (json) {
                    var entry = json.feed.entry;
                    $.each(entry, function () {
                        self.data.push({
                            name: this['im:name'].label,
                            price: this['im:price'].label
                        });
                    });
                });
        self.dataSource = new oj.ArrayTableDataSource(
                self.data,
                {idAttribute: 'name'}
        );
    }
    return homeContentViewModel;
});

Next steps would be to replace the hardcoded search string with some UI elements so that the user can specify the search string at runtime.

A reference that helped me with the above:

http://stackoverflow.com/questions/4925760/selecting-a-json-object-with-a-colon-in-the-key

DukeScript - June 30, 2016 11:46 PM
Transpile JavaScript to Java!

Let’s reverse the trend of last few years today! Instead of continuing to transpile more and more languages into JavaScript, let’s demonstrate how to transcript any JavaScript library into Java!

Please meet Definitely Typed Java Libraries another project sponsored by the DukeScript gang. It offers more than fifteen hundred of JavaScript libraries typings and an easy way to generate the Java API bindings for any of them.

Javadoc for first few libraries is available here.

Transpiler to Java

Some people suggested that there should be a transpiler from JavaScript to Java - that isn’t easy to do. Java needs some static type information and that isn’t available when parsing JavaScript source.

However the DukeScript project hasn’t given up: there is a huge set of TypeScript typings (essentially for any JavaScript library) and converting TypeScript types into Java types is certainly possible.

That is why DukeScript project has developed a Maven Typings Plugin that everyone can use to convert a typings file to a functional Java API.

Read our tutorial to find out how easy it is to convert underscore into Java APIs: please contribute to success of Java (in a browser) by forking and contributing another library. Share with us your experience!

Thanks!

Geertjan's Blog - June 29, 2016 04:30 PM
Integrating Brazil into Oracle JET

Using the info from yesterday, it's easy to integrate Brazil into Oracle JET:

To get started, get the brazil-states.geojson file and put it in your project as described yesterday. Below, the file has been renamed to "brazil.json".

Then here's your viewModel:

define(['text!../brazil.json',
        'ojs/ojcore',
        'knockout',
        'ojs/ojthematicmap'],
        function (geo, oj, ko) {
            function mainContentViewModel() {
                var self = this;
                self.mapProvider = {
                    geo: JSON.parse(geo),
                    propertiesKeys: {
                        id: 'name',
                        shortLabel: 'name',
                        longLabel: 'sigla'
                    }
                };
            }
            return new mainContentViewModel();
        });

And the view: 

<h1>Brazil Map</h1>
<div id='thematicmap1'
     data-bind="ojComponent:{
    component: 'ojThematicMap',
        basemap: 'Foo',
        mapProvider: mapProvider,
         areaLayers:
          [{
            layer: 'Bar',
            areaDataLayer: {
                id: 'adl1',
                areas: [
                    {id: 'a1', 'location': 'Tocantins', color: 'rgb(255, 181, 77)'},
                    {id: 'a2', 'location': 'Amazonas', color: 'rgb(255, 120, 90)'},
                    {id: 'a3', 'location': 'Mato Grosso', color: 'rgb(120, 30, 87)'},
                    {id: 'a4', 'location': 'Bahia', color: 'rgb(20, 80, 120)'}
                ]}
          }]
        }"
     style="width:100%; height:600px;"/>

Take note of "Foo" and "Bar" above, i.e., these labels can be anything you like, they're just there as identifiers. The same is true for the "id" in the "areaDataLayer". The colors above are just an example of what you can do, i.e., they don't signify anything in this example. 

All this is pretty cool, isn't it?

NetBeans – Java PDF Blog - June 28, 2016 01:20 PM
NetCat 8.2 – what it is and why you should care…

NetCat 8.2, not just about Cats on the Net……

Today sees the start of the NetCat 8.2 test program.

NetCat is the Community Test program that Oracle runs for each new release of NetBeans once it has completed its development and internal testing. It is only when you ask real users to use software that you find the real issues….

NetCat programs have run on previous releases of NetBeans, and one of the reasons why it is such a solid platform.

So what does it involve?

NetCat testing involves spending some time running though a test script. If you do A, B and C then does D happen. This is a really good way to get a better understanding of both the NetBeans IDE and the feature you are testing.

So why should you get involved?

Here are my top reasons for being involved….

1. It gives you a much  deeper understanding of the NetBeans IDE. 

I have been involved in the NetCat testing program since 7.4 It has given me a much better understanding of what NetBeans can do and I now write better code faster. NetCat testing of features means I now know many of the features which are hidden inside NetBeans and how to use them. I have recouped the time invested in testing many times over with my better coding skills.

2. It gives you a deeper understanding of testing.

Being part of the NetBeans test program has given us a much better of idea of how we can test and improve how we develop and test our own software.

3. We get a reliable platform for our coding.

NetBeans is a critical tool for our software development. While the tool is free, if it is buggy, slow or unreliable, this is a significant cost to us. As part of the NetCat program, we know that the next release will be very usable for us and we know what all the new feature are.

4. Cool swag.

As a thank-you for being involved, the testers all get free t-shirts, or other items (it varies with each release).

So how can you get involved?

That is easy….

You can sign-up for NetCat here.

If you’re a first-time reader, or simply want to be notified when we post new articles and updates, you can keep up to date by social media (TwitterFacebook and Google+) or the  Blog RSS.

Related Posts:

The post NetCat 8.2 – what it is and why you should care… appeared first on Java PDF Blog and was written by Mark Stephens.