Sonntag, 13. April 2014

Java8 CompletableFuture for JavaFX and CDI Part II

The last part was describing how you could reach the goal to make the order of some dependent method calls independent. Now we will see, how we could use this for the combination of CDI and JavaFX.
If you want to have CDI managed Controllers inside your JavaFX application you have to deal with the two life cycles. The init from CDI and the init from JavaFX. If you are combining both technologies, you will have the problem that the order of the livecycle steps are not always in the same order. Depending from the technology that will start, the order of the init methods will change. For CDI it is the method with the annotation Postconstruct and for JavaFX the method initialize.
Well, lets see what you could do..
For this example I will start with the FXMLoader. Check the Method setControllerFactory. You will see, that after the creation of the Controller instance the method initInstance() will be called.
 
@Singleton
public class FXMLLoaderSingleton {

    private @Inject @CDILogger Logger logger;
    private @Inject Instance<CDIJavaFxBaseController> instance;

    private final ClassLoader cachingClassLoader = new FXClassLoader(FXMLLoader.getDefaultClassLoader());
    private final Map<Class, FXMLLoader> class2LoaderMap = new HashMap<Class, FXMLLoader>();

    public FXMLLoader getFXMLLoader(Class clazz) {
        final Map<Class, FXMLLoader> loaderMap = class2LoaderMap;
        final String name = clazz.getName();
        if (loaderMap.containsKey(clazz)) {
            if (logger.isDebugEnabled()) {
                logger.debug("fx loader fuer diese klasse schon in der map " + name);
            }
        } else {
            final String fxmlFileName = clazz.getSimpleName() + ".fxml";
            if (logger.isDebugEnabled()) {
                logger.debug("fxmlFileName -> " + fxmlFileName);
            }
            final URL resource = clazz.getResource(fxmlFileName);
//            FXMLLoader loader = new CDIFXMLLoader(resource);
            FXMLLoader loader = new FXMLLoader(resource);
            loader.setClassLoader(cachingClassLoader);
            loader.setControllerFactory(new Callback<Class<?>, Object>() {
                @Override
                public Object call(Class<?> param) {
                    final Class<JavaFXBaseController> p = (Class<JavaFXBaseController>) param;
                    final JavaFXBaseController controller = instance.select(p).get();
                    controller.initInstance(); //trigger async call
                    return controller;
                }
            });
            try {  
                final Class<?> aClass = Class.forName(clazz.getName() + "Controller");
                final CDIJavaFxBaseController call = (CDIJavaFxBaseController) loader.getControllerFactory().call(aClass);
                loader.setController(call);
            } catch (ClassNotFoundException e) {
                logger.error(e);
            }
            loaderMap.put(clazz, loader);
        }
        return loaderMap.get(clazz);
    }

    private FXMLLoaderSingleton() {
    }
}

The method initInstance() will trigger the init-process. Inside the method the task will be called async. The task itself will wait until the CDi and JavaFX init will be ready. After this the method initBusinessLogic will be called. This means, thet the developer only will have to implement the method initBusinessLogic and he will be sure that all init stuff is done.
Happy coding ;-)
public abstract class JavaFXBaseController implements CDIJavaFxBaseController {

    public static final String DONE = "done";

    private boolean mockModusActive = false;
    public boolean isMockModusActive() {
        return mockModusActive;
    }
    public void setMockModusActive(boolean mockModusActive) {
        this.mockModusActive = mockModusActive;
    }

    public abstract void cleanUp();

    public abstract void setI18n();

    private @Inject @CDILogger Logger logger;

    private Boolean initCompleteCDI = false;
    private Boolean initCompleteFX = false;

    public CompletableFuture supplyAsync;

    @Override
    public final void initInstance(){
        final CachedThreadPoolSingleton instance = CachedThreadPoolSingleton.getInstance();
        supplyAsync = CompletableFuture.supplyAsync(task, instance.cachedThreadPool);
        if (logger.isDebugEnabled()) supplyAsync.thenAccept(logger::debug);  //logger
    }

    public final Supplier task = ()-> {
//        Warten bis alle true
        while(! (initCompleteCDI && initCompleteFX) ){
            try {
                //evtl loggen
                if (logger.isDebugEnabled()) {
                    logger.debug("initCompleteCDI = " + initCompleteCDI);
                    logger.debug("initCompleteFX = " + initCompleteFX);
                    logger.debug("getClass().getName() = " + getClass().getName());
                }
                TimeUnit.MILLISECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
                return e.toString();
            }
        }

        if (logger.isInfoEnabled()) {
            logger.info("initBusinessLogic() => called now");
        }
        final boolean fxApplicationThread = Platform.isFxApplicationThread();
        if ( ! fxApplicationThread){
            Platform.runLater(this::initBusinessLogic);
        } else {
            initBusinessLogic();
        }


        if (logger.isInfoEnabled()) {
            logger.info("initBusinessLogic() => done now");
        }
        return DONE;
    };

    @PostConstruct
    public final void postconstruct(){
        if (logger.isDebugEnabled()) {
            logger.debug("PostConstruct mockModusActive == " + mockModusActive);
        }
        cdiPostConstruct();
        initCompleteCDI = true;
        if (logger.isDebugEnabled()) {
            logger.debug("postconstruct ready " + getClass().getName());
        }
    }

    public abstract void cdiPostConstruct();

    @Override
    public final void initialize(URL url, ResourceBundle resourceBundle) {
        if (logger.isDebugEnabled()) {
            logger.debug("initialize mockModusActive== " + mockModusActive);
        }
        initializeFX(url, resourceBundle);
        initCompleteFX = true;
        if (logger.isDebugEnabled()) {
            logger.debug("initialize ready " + getClass().getName());
        }
    }


    protected abstract void initializeFX(URL url, ResourceBundle resourceBundle);
    /**
     * wird nach der init von CDI und JavaFX aufgerufen,
     * egal in welcher Reihenfolge die init durchlaufen wird.
     *
     * ein blockierender method call
     *
     */
    public abstract void initBusinessLogic();
}

Dienstag, 8. April 2014

Dynamic WADL with CDI

The WADL (Web Application Definition Language) is used to describe HTTP-based applications which means that JAXRS applications can and are described by that. Typically it is generated (static or dynamic) with the jersey maven plugin (detailed informations can be found here). But for some reason i could not use either maven nor the jersey plugin. So i had to do it on my own and used it as a little finger exercise. The main goal was to achieve dynamic wadl generation for a JAXRS application. The working steps were relativly easy:
  • Create a JAXB-Model from the current WADL-Specification
  • Create a CDI-Based design for JAXRS resources
In the end you only have to provide a producer class which creates a @Wadl Class[] and inject an instance of @Wadl  @WadlApplication.

@Path("/")
public class MyResource
{
 @Inject
 @Wadl
 @WadlApplication
 Instance<Application> applicationInstance;

 @GET
 @Produces(MediaType.APPLICATION_XML)
 public Application getRoot(@Context UriInfo uriInfo)
 {
  return getWadl(uriInfo);
 }
}

 As a simple example assume that you have a TinkerForge MasterBrick connected to a RaspberryPi. Addionally you want to provide a JAXRS-Resource for every connected sensor. With the sample code below you are now able to extend the WADL dynmically.

public class WadlClassProducer
{
 @Inject
 @SensorAnno
 @Any
 Instance<SensorResource> sensorInstances;

 @Produces
 @Wadl
 public Class[] create()
 {
  List<Class<?>> clazzList = new ArrayList<Class<?>>();
  for (SensorResource sensor : sensorInstances)
  {
   clazzList.add(sensor.getResourceClass());
  }
  return clazzList.toArray(new Class[0]);
 }
}

The sources can be found here.

Freitag, 28. März 2014

Java8 CompletableFuture for JavaFX and CDI Part I

Java8 CompletableFuture for JavaFX and CDI Part I Java8 will give you a few more tools to solve concurrency problems.
One of them is the CompletableFuture. I will show you, how you could sync the
two different init-cycles from CDI and JavaFX with this.

CDI and JavaFX are using a life-cycle during the init process.
For CDI you can use the method that is annotated with the
AnnotationLiteral @Postconstruct and for JavaFX you can use the method initialize(..)
If you want to have a method that is called after both others are finished you have to think
about the problem that it is not clear which method is called first.
To show more in detail what the problem is let us think about the following.
 
private String pattern;
private SimpleDateFormat sdf;

//beispielhaft für eine init
public void createSDF(){
    this.sdf = new SimpleDateFormat(this.pattern);        
}

//beispielhaft für eine init
public void newPattern(final String pattern) {
    this.pattern = pattern;
}

public String format(final Date date){
    return sdf.fomat(date);
}
To use the method format(..) you must use the methods newPattern(..) and createSDF first.
But both in the right order like the following code snipp.
 
newPattern("yyyy.MM.dd");
createSDF();
final String s = versionAB.format(new Date());
System.out.println("s = " + s);
If you are calling first createSDF(..) for example you will get an exception.
But thinking to the problem with CDI and JavaFX it must be valid to do something like the following.
 
createSDF();
newPattern("yyyy.MM.dd");

final String s = versionAB.format(new Date());
System.out.println("s = " + s);
The method creatdSDF(..) is called before newPattern(..).
The solution is quite simple. The method call from createSDF must be non blocking but
waiting with the execution until newPattern(..) was called.
The same with format(..). This method call must wait until both are finished but itself it
is an blocking method call. This is to give the developer the feeling he expected,
if he is working with the result from format(..).
To solve this we have to booleans called initCompleteA and initCompleteB.
Both are false in the beginning. If newPattern(..) is called initcompleteA will be true,
and initCompleteB will be true after the method creatSDF() is ready.
 
public void newPattern(final String pattern) {
    this.pattern = pattern;
    initCompleteA=true;
    System.out.println("newPattern = " + pattern);
}
public void createSDF(){
    CompletableFuture<Void> supplyAsync
        = CompletableFuture
        .supplyAsync(taskCreateSDF, cachedThreadPool);
    supplyAsync.thenAccept(System.out::println);
}
public Supplier<Void> taskCreateSDF = ()-> {
    while(! initCompleteA ){
        try {
            System.out.println("createSDF is waiting" );
            TimeUnit.MILLISECONDS.sleep(4);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    sdf = new SimpleDateFormat(pattern);
    initCompleteB = true;
    return null;
};
The Method format(..) now is only waiting for both...
 
public Supplier<String> task = ()-> {
//Warten bis alle true
    while(! (initCompleteA && initCompleteB) ){
        try {
            System.out.println("initCompleteA = " + initCompleteA);
            System.out.println("initCompleteB = " + initCompleteB);
            System.out.println("pattern = " + pattern);
            System.out.println("sdf = " + sdf);
            TimeUnit.MILLISECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    return sdf.format(this.date);
};
private Date date;

public String format(final Date date){
    this.date = date;
    supplyAsync = CompletableFuture
        .supplyAsync(task, cachedThreadPool);
    try {
        return supplyAsync.get();
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    }
    return "";
}
The example you will find at http://stash.rapidpm.org/projects/PUB/repos/jaxenter.de-0016-async-calls/browse
The next Part will show how we have to implement the JavaFX CDI bootstrapping to use this.

Montag, 17. März 2014

Lego Mindstorms EV3 Components: Color Sensor - Part 1

In this and in our next postings on our Lego Mindstorms series we will have a closer look at the EV3 color sensor. Today we will use the sensor's ability of detecting and distinguishing different colors.

Meanwhile version 0.7.0 of the lejos api was released. But in this tutorial we will still use the 0.6.0-release as 0.7.0s changes weren't dramatic. So you should be able to run the same program with 0.7.0, too.

The robot

The only task the robot will do in this tutorial is: Detecting colors and tell us which color was detected. So in fact we only need the sensor. No motors or something like that is needed. But as we already have a robot from our last articles on the infrared sensor we will take that one and only switch the infrared sensor with the new color sensor.



The parcours

We built a stick with different colors: red, green, yellow and blue. We will hold the different colors in front of the robot's sensor and the robot should give feedback on the detected color by letting the background-LED of the brick's buttons illuminate in the same color. One exception: If blue is detected the program should exit.


The color sensor API

Like the infrared sensor the color sensor has different modes for different tasks. The infrared sensor for example had modes to detect signals of an infrared source or to detect objects and their distance to the robot.
There is a mode for every task a sensor can execute. To detect different colors we need the color sensor's colorIDMode. Once the sensor is in the right mode we only need to call colorSensor.getColorID to get the detected color.

Sounds easy, IS easy. Here comes the code.

The code

We have two classes this time: The Main-class and the ColorRecognizerThread-class. First, let's look at the (really small) main-class:

public class Main {


    public static void main(String[] args) throws InterruptedException {
        final EV3ColorSensor colorSensor = new EV3ColorSensor(SensorPort.S2);
        final SensorMode mode = colorSensor.getColorIDMode();
        final ColorRecognizerThread colorRecognizerThread = new ColorRecognizerThread(colorSensor);

        colorRecognizerThread.start();

        Button.waitForAnyPress();
    }

}

In contrast to our earlier postings we don't need a DifferentialPilot this time because the robot doesn't have to move. So the only things we do is instantiating a new ColorSensor-Instance and set it to the colorIDMode. Then we instantiate a ColorRecognizerThread (which extends Thread) and give it the color sensor object as a constructor parameter. In that thread we will implement the logic to detect colors and let the LED illuminate in the same color.
After starting the thread we wait for any button press as always so that our program won't just exit after starting the thread.

The ColorRecognizerThread looks like the following:

public class ColorRecognizerThread extends Thread {

    private EV3ColorSensor colorSensor;

    public ColorRecognizerThread(final EV3ColorSensor colorSensor) {
        this.colorSensor = colorSensor;
    }

    @Override
    public void run() {
        while(true){
            final int colorId = colorSensor.getColorID();
            switch (colorId){
                //RED
                case 0:
                    Button.LEDPattern(2);
                    break;
                //GREEN
                case 1:
                    Button.LEDPattern(1);
                    break;
                //BLUE
                case 2:
                    Button.LEDPattern(4);
                    threadSleep(2000);
                    Button.LEDPattern(0);
                    System.exit(0);
                //YELLOW
                case 3:
                    Button.LEDPattern(3);
                    break;
                default:
                    Button.LEDPattern(0);
            }
        }
    }

    private void threadSleep(final int ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

The constructor is easy as it only saves the color sensor object into a private variable so that we can use it in the run-method.
The really interesting part is the run-method of course, which is called when starting the thread in the main class. We have a deadloop as we want the robot to detect colors continuously. In that loop we get the color found by the color sensor by calling the getColorID()-Method. As you can see it returns an integer. By having a look at the sources (Color.java) we find out which integer value stands for which color:

    public static final int RED = 0;
    public static final int GREEN = 1;
    public static final int BLUE = 2;
    public static final int YELLOW = 3;
    public static final int MAGENTA = 4;
    public static final int ORANGE = 5;
    public static final int WHITE = 6;
    public static final int BLACK = 7;
    public static final int PINK = 8;
    public static final int GRAY = 9;
    public static final int LIGHT_GRAY = 10;
    public static final int DARK_GRAY = 11;
    public static final int CYAN = 12;
    public static final int BROWN = 13;
    public static final int NONE = -1;

So, after getting the id we have a "switch case"-statement for that id. If the found color is red, green or yellow we just want the background-LED of the brick to illuminate in the same color (case 0, 1 and 3). Maybe you are curious why the integer parameter for the Button.LEDPattern-method doesn't match with the integer values from the Color-class. Well, the LED doesn't have a pattern for all of the colors. It has 9 different patterns in total (thanks to tigger from the forum for that information!)

0: turn off button lights
1/2/3: static light green/red/yellow
4/5/6: normal blinking light green/red/yellow
7/8/9: fast blinking light green/red/yellow
>9: same as 9.
 If the color blue is found (case 2) I wanted the program to do the following: Turn the light of the color sensor of and exit the program. The api says that we can use the setFloodlight(int color)-method for that by calling it with Color.NONE:

/**
* Used to turn on or off the floodlight by color. If the sensor has multiple light colors,
* you can control which color is turned on or off. If the color does not exist, it does
* nothing and returns false. You can turn the floodlight off by using Color.NONE.
But this throws an exception if you look at the sources of EV3ColorSensor (the default case of the switch-statement):

public boolean setFloodlight(int color)
    {
        int mode;
        switch (color)
        {
        case Color.BLUE:
            mode = COL_AMBIENT;
            break;
        case Color.WHITE:
            mode = COL_COLOR;
            break;
        case Color.RED:
            mode = COL_REFLECT;
            break;
        default:
            // TODO: Should we ignore a wrong color or throw an exception?
            throw new IllegalArgumentException("Invalid color specified");
        }
        switchMode(mode, SWITCH_DELAY);
        // TODO Auto-generated method stub
        return true;
    }

But I never the less wanted to give some optic signal to show that the program is exiting. Turning off the LED wasn't enough because we already turn it of in our default case of our switch statement in the ColorRecognizerThread. In the end I decided to let the LED display the pattern 4 (blinking green) for two seconds before exiting the program. The threadSleep-method was just created to have the try-catch out of our run-method (because it looks stupid).

That's all.

The result

And here is the tiny result (watch on youtube for better quality):





Montag, 10. März 2014

Lego Mindstorms EV3 Components: Infrared Sensor - Part 3

This is the last part of our articles on the mindstorm's infrared sensor. After looking at the abilities of the remote sensor to recognize objects and commands from the remote control we will now have a closer a look on the functionality of finding an infrared signal sent by the remote control constantly.

In february the lejos api had a new release - 0.6.0-ALPHA, so while using the 0.5.0-ALPHA-release in our last articles we will by now use the 0.6.0-release.

The robot

We will use the robot from the last two articles on the infrared sensor again, and of course we will use the remote control. If you haven't checked the infrared articles already ( Part 1/Part 2) you should do so.

The parcours

There is the robot and there is the remote control. In this part we want to tell the robot: Hold a distance of about 20-35cm to the remote control!
Which means that if we move the remote control nearer to the robot, it should move backwards and if we move the remote control away from the robot it should follow. We will only use the toggling button this time. If it is toggled and sending a signal, the robot should care about holding the right distance to the remote control. The program will exit if the signal ends (the button is untoggled).

The infrared sensor API

As announced in our last part on the infrared sensor we will use the SeekMode this time to receive the relative position and distance of the remote control.

What we will need to instantiate therefore is: the infrared sensor and a RangeFinderAdaptor for the infrared sensor.

As soon as we instantiated a RangeFinderAdapter we can use its getRanges()-method which returns all required information to let the robot find the remote control and its position.

We will use a thread which will check those informations continuously so that the robot will always react to changes of the remote controls position.

Let us directly jump to the finished code and see how it works in detail.

The code

We have two classes this time: The Main-class and the InfraredSignalCheckerThread-class. First, let's look at the main-class:

public class Main {

    protected final static double PILOT_SPEED = 60.0;
    protected final static int PILOT_ACCELERATION = 500;
    protected final static double WHEEL_DIAMETER = 30.0f;
    protected final static double DISTANCE_BETWEEN_WHEELS = 170.0;

    public static void main(String[] args) throws InterruptedException {

        final DifferentialPilot pilot = new DifferentialPilot(WHEEL_DIAMETER, DISTANCE_BETWEEN_WHEELS, Motor.C, Motor.B);
        final EV3IRSensor infraredSensor = new EV3IRSensor(SensorPort.S2);
        final RangeFinderAdaptor rangeFinderAdaptor = new RangeFinderAdaptor(infraredSensor.getSeekMode());
        final InfraredSignalCheckerThread checkerThread = new InfraredSignalCheckerThread(rangeFinderAdaptor, pilot);

        configurePilot(pilot);
        checkerThread.start();

        Button.waitForAnyPress();
    }

    private static void configurePilot(final DifferentialPilot pilot) {
        pilot.setAcceleration(PILOT_ACCELERATION);
        pilot.setRotateSpeed(PILOT_SPEED);
        pilot.setTravelSpeed(PILOT_SPEED);
    }
}

First, we instantiate the pilot and the infraredSensor as always. Then we instantiate the RangeFinderAdapter which gets the infrared-sensor's SeekMode as a parameter. The RangeFinderAdapter will return all informations on the remote control's position. We then instantiate a InfraredSignalCheckerThread which gets the adaptor to check the remote control's position continuosly and the pilot to let the robot react on the remote control's position.

After the instantiations we set the pilot's speeds and start the thread. So now let's have a look at our Thread-class:

public class InfraredSignalCheckerThread extends Thread {

    private RangeFinderAdaptor adaptor;
    private DifferentialPilot pilot;
    private boolean isMoving = false;
    private  boolean isBearing = false;

    public InfraredSignalCheckerThread(final RangeFinderAdaptor adaptor, final DifferentialPilot pilot){
        this.adaptor = adaptor;
        this.pilot = pilot;
    }

    @Override
    public void run() {
        while(true){
            final float bearing = adaptor.getRanges()[0];
            final float distance = adaptor.getRanges()[1];
            if(distance < 129.0f && distance > 127.0f && bearing < 1.0f){
                System.exit(0);
            }
            doBearing(bearing);
            doMoving(distance);
        }
    }

    private void doBearing(final float bearing) {
        if(bearingIsOk(bearing)){
            isBearing = false;
        }
        else {
            if(bearing > 5.0f){
                pilot.rotateRight();
                isBearing = true;
            } else {
                pilot.rotateLeft();
                isBearing = true;
            }
        }
    }

    private void doMoving(final float distance) {
        if(!isBearing){
            if(!isMoving){
                pilot.quickStop();
            }
            if(distanceIsOk(distance)){
                pilot.quickStop();
                isMoving = false;
            }
            else {
                if(distance < 25.0f){
                    pilot.backward();
                } else {
                    pilot.forward();
                }
                isMoving = true;
            }
        }
    }

    private boolean bearingIsOk(final float bearing) {
        if(bearing < 5.0f && bearing > -5.0f){
            return true;
        }
        return false;
    }

    private boolean distanceIsOk(final float distance) {
        if(distance >20.0f && distance < 35.0f){
            return true;
        }
        return false;
    }
}

The constructor is easy as it only saves the adaptor and the pilot into private variables so that we can use them in the run-method. If you have a look at the private variables you will see that there are two boolean attributes isBearing and isMoving. We need those variables because we want to robot to first react on direction changes of the remote control (which is done by rotating), and we don't want the robot to react on distance changes (which is done by moving forwards/backwards) until the bearing has finished.

Okay, let's have a look at the run-method which is called when we start the thread in the main-class.
We need two information on our remote control: The relative bearing to the robot and the distance to the robot. As said earlier, the getRanges()-Method returns those information. Here is what the api says:
/**
     * return a sample provider for the IR sensor operating in seek mode
     * The provider returns the bearing and distance to one or more IR beacons.
     * Up to four
     * beacons (on different channels 0-3) can be detected. Each beacon has an
     * associated two byte value (so the beacon on channel 0 will have values
     * in locations 0 and 1 in the array. The first location contains the relative
     * bearing to the beacon, the second the distance.

     * The bearing values range from -12 to +12 (with values increasing clockwise
     * when looking from behind the sensor. A bearing of 0 indicates the beacon is
     * directly in front of the sensor. Distance values (0-100) are in cm and if no
     * beacon is detected a bearing of 0 and a distance of 255 is returned.

So, we only care for the first two floats of the array because we only have one remote control. And we want the bearing-information of it ([0]) and the distance-information ([1]).

After writing those informations into float variables we check, if the information are valid: The api says, if no signal is found the value of bearing will be 0 and the distance will be 255. So first, we check this case and exit the program if no signal is found (I found out, that if no signal is sent, the distance value is 128.0 and not 255 as written in the api).

If the values are valid (a signal was received we call the methods doBearing and doMoving). Those methods will make the robot first react on direction changes of the remote control, and then react on distance changes afterwards. Let's have a closer look at these two methods, first the doBearing-Method:

private void doBearing(final float bearing) {
        if(bearingIsOk(bearing)){
            isBearing = false;
        }
        else {
            if(bearing > 5.0f){
                pilot.rotateRight();
                isBearing = true;
            } else {
                pilot.rotateLeft();
                isBearing = true;
            }
        }
    }

private boolean bearingIsOk(final float bearing) {
        if(bearing < 5.0f && bearing > -5.0f){
            return true;
        }
        return false;
    }

First, we check if the bearing is okay, which means that the remote control is more or less directly in front of the robot. As said in the api that value can be anything between -12 and 12 (I found out, that this value can be anything between -25 and 25). So we tell the program, if the value is between -5 and 5 the bearing is okay and the reaction of the robot has finished. If the bearing is not okay, we tell the robot to rotate right of the bearing is greater than 5, or rotate left if the value is lower than -5. While rotating, we tell the program, that the robot is reacting to the bearing, by setting the isBearing-attribute to true. By the rotation the bearing value will approach to 0. When that's the case we tell the program, that the robot has finished its reaction and set the isBearing variable to false.

And here's the doMoving-Method:

private void doMoving(final float distance) {
        if(!isBearing){
            if(!isMoving){
                pilot.quickStop();
            }
            if(distanceIsOk(distance)){
                pilot.quickStop();
                isMoving = false;
            }
            else {
                if(distance < 20.0f){
                    pilot.backward();
                } else {
                    pilot.forward();
                }
                isMoving = true;
            }
        }
    }
private boolean distanceIsOk(final float distance) {
        if(distance >20.0f && distance < 35.0f){
            return true;
        }
        return false;
    }

When the doBearing-method has finished, the doMoving-method will start. But we only want to react on the remote control's distance if the robot has finished it's reaction to the bearing. So we first check, if the robot is not bearing any longer. The second "if" that follows now is a bit tricky: We check, if the robot is moving as a result from the doMoving-Method or as a result from the doBearing-method. If it NOT moving as a result of the doMoving-method, it should stop because then we have the case, that the robot is still rotating as a reacting to the bearing (we didn't tell the program to stop rotating any time in the doBearing-method). So after that, we check if the remote control's distance is okay (which means the remote control is in a distance of 20 to 35cm) to the robot. If that is the case the robot should stop and we mark the isMoving-attribute as false. If the distance is NOT okay we tell the robot to move backwards of the distance is less then 25 (because it should "flee" from the remote control) or move forwards if the distance is greater than 35 (because it should "follow" the remote control).

The result

And here is the result (watch on youtube for better quality):





Freitag, 28. Februar 2014

Wildfly/JBoss: How to secure customer passwords

If you are familiar with Wildfly/JBoss you might now that you can easily configure your system to use JAAS database authentication for the login process of your customer. Because it is considered bad practice to store passwords in clear text a hash-algorithm (e.g. SHA256, MD5) can be specified to encrypt them. Further informations can be found under here.

The problem with that approach is that your passwords will be vulnerable to dictionary and rainbowtable attacks (refresh your knowlegde here).
One way to face this problem is to use salted hashed passwords but the standard DatabaseServerLoginModule does not support that. But you can use this extension of the DatabaseServerLoginModule.
The configuration is fairly easy:

Wildfly/JBoss Konfiguration

1. Create module
Create the new module de.rtner.security.main and configure the module.xml like this
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="de.rtner.security">
    <resources>
        <resource-root path="PBKDF2-1.0.4.jar"/>
        <resource-root path="SaltedDatabaseLoginModule-1.0.4.jar"/>
    </resources>
   <dependencies>
        <module name="javax.api"/>
        <module name="javax.servlet.api"/>
        <module name="org.jboss.as.web-common"/>
        <module name="org.jboss.logging"/>
        <module name="org.picketbox"/>
        <module name="sun.jdk"/>
    </dependencies>
</module>
Both declared jars must also be present in that folder.

2. Update module.xml of picketbox.

Every custom login module has to be declared as a dependencies in the module.xml of picketbox. So just add this line:
<module name="de.rtner.security"/>
3. Update standalone.xml
<login-module code="de.rtner.security.auth.spi.SaltedDatabaseServerLoginModule" flag="required" module="de.rtner.security">
 <module-option name="dsJndiName" value="java:jboss/datasources/ExampleDS"/>
 <module-option name="principalsQuery" value="select password from User where login=?"/>
 <module-option name="rolesQuery" value="select role, 'Roles' from UserRole where login=?"/>
 <module-option name="hmacAlgorithm" value="HMacSHA256"/>
 <module-option name="formatter" value="de.rtner.security.auth.spi.PBKDF2HexFormatter"/>
 <module-option name="engine" value="de.rtner.security.auth.spi.PBKDF2Engine"/>
 <module-option name="engine-parameters" value="de.rtner.security.auth.spi.PBKDF2Parameters"/>
</login-module>

The password encryption can be done with the following function.
private String createPbKdF2Passwort(String password) throws NoSuchAlgorithmException
{
 PBKDF2Formatter formatter = new PBKDF2HexFormatter();
 SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
 byte[] salt = new byte[8];
 sr.nextBytes(salt);
 int iterations = 1000;
 PBKDF2Parameters p = new PBKDF2Parameters("HmacSHA256", "ISO-8859-1", salt, iterations);
 PBKDF2Engine e = new PBKDF2Engine(p);
 p.setDerivedKey(e.deriveKey(password));
 return formatter.toString(p);
}

Have fun coding.

Donnerstag, 20. Februar 2014

are you missing the ? operator from project coin?

How to get rid of 90% boiler plate code from NPE-save model - surfing?
What I am meaning with modell surfing? For example you have a class DemoClassA.
Inside DemoClassA you have an instance of DemoClassB.
Inside DemoClassB you have an instance of DemoClassC. And so on..

You need something like the following.

String value = demoClassA.getDemoClassB().getDemoClassC().getValue();
The bad thing is if your valid model could have ClassB or ClassC with null. You only have to show the value inside your GUI if the complete getter - cascade will be valid. The first would be something like this.

  
 DemoClassB valueB = demoClassA.getDemoClassB();
 if(demoB != null){
    DemoClassC demoC = demoB.getDemoClassC();
    if(demoC != null){
     String value = demoC.getValue();
    }
 }
A lot of booooring code. Project Coin had something with Wildcards.
 
 String value = demoClassA?.getDemoClassB()?.getDemoClassC()?.getValue();
 
This is really nice, but it was not accepted. So I had do something like this for myself.
One main point will be that the objects are ready initialized and I could not change the source code from this part. Other languages as plain Java are not allowed. No other frameworks, no AOP and something like this. Puuhh.. what else?
I was thinking about the newsletter nr 180 (http://www.javaspecialists.eu/archive/Issue180.html) from Heinz Kabutz. He explained how to generate static Proxy Classes. This was a good point to start from.
The key concept is the generating of Proxy Classes on the fly if they are needed. Via Reflection the real Subject is analysed and the Proxy generated. He is instanciating the new proxy class and the real subject with the default constructor. For my project this was not helpfull, because the model was grown over the last 10 years. Nearly no default constructor is available and the project owner was building something like a RMI Lazy Loading inside the persistent model. This model itself is used directly inside Swing.. hmmmmm nothing was I really want to use...
Changing the old code is very time consuming.
On the other side I was writing a lot of this if != null code.
So I decided to write a Proxy that I can use on initialized objects. This must be recursive to get the NPE save getter cascades. Based on Heinz code, I started to write a VirtualProxySourceGeneratorOnExistingObject to stop the instance creation on the real Subject.
public class VirtualProxySourceGeneratorOnExistingObject extends VirtualProxySourceGenerator {

    public VirtualProxySourceGeneratorOnExistingObject(
            Class subject, Class realSubject) {
        super(subject, realSubject, Concurrency.OnExistingObject);
    }
    protected void addRealSubjectCreation(PrintWriter out,  String name, String realName) {
        out.printf(" public %s realSubject;%n", name);
        out.println();
        out.printf(" private %s realSubject() {%n", name);
        out.println(" return realSubject;");
        out.println(" }");
    }
}  
After this I changed the VirtualProxySourceGeneratorto use this VirtualProxySourceGeneratorOnExistingObject and changed it in a way that a getter method will generate a new Proxy for the next realSubject.
public abstract class VirtualProxySourceGenerator {

    protected final Class subject;
    protected final Class realSubject;
    private final String proxy;
    private CharSequence charSequence;
    private Concurrency type;

    public VirtualProxySourceGenerator(
            Class subject, Class realSubject, Concurrency type) {
        this.subject = subject;
        this.realSubject = realSubject;
        this.type = type;
        this.proxy = makeProxyName(subject, type);

    }

    private static String makeProxyName(Class subject, Concurrency type) {
        return "$$_" + subject.getName().replace('.', '_') +
                "Proxy_" + Integer.toHexString(System.identityHashCode(
                subject.getClassLoader())) + "_" + type;
    }

    public String getProxyName() {
        return proxy;
    }

    public CharSequence getCharSequence() {
        if (charSequence == null) {
            StringWriter sw = new StringWriter();
            generateProxyClass(new PrintWriter(sw));
            charSequence = sw.getBuffer();
        }
        //System.out.println("charSequence = " + charSequence.toString());
        return charSequence;
    }

    private void generateProxyClass(PrintWriter out) {
        addClassDefinition(out);
        addProxyBody(out);
        out.close();
    }

    private void addProxyBody(PrintWriter out) {
        addRealSubjectCreation(out, subject.getName(), realSubject.getName());
        addProxiedMethods(out);
        out.println("}");
    }

    protected abstract void addRealSubjectCreation(PrintWriter out, String name, String realName);


    private void addClassDefinition(PrintWriter out) {
        addImports(out);
        out.printf("public class %s %s %s {%n",
                proxy, getInheritanceType(subject), subject.getName());
    }

    private String getInheritanceType(Class subject) {
        return subject.isInterface() ? "implements" : "extends";
    }

    protected void addImports(PrintWriter out) {

    }

    private void addToStringIfInterface(PrintWriter out) {
        if (subject.isInterface()) {
            out.println();
            out.println(" public String toString() {");
            out.println(" if(realSubject() == null ) return \"NullObjectHolder in \" + this.getClass() ;");
            out.println(" return realSubject().toString();");
            out.println(" }");
        }
    }

    private void addProxiedMethods(PrintWriter out) {
        for (Method m : subject.getMethods()) {
            addProxiedMethod(out, m);
        }
        addToStringIfInterface(out);
    }

    private void addProxiedMethod(PrintWriter out, Method m) {
        if (Modifier.isFinal(m.getModifiers())) return;
        addMethodSignature(out, m);
        addMethodBody(out, m);   //NPE da val ger getter gefuellt wird

        final Class returnType = m.getReturnType();
        if (returnType == void.class) out.printf(");%n }%n");
        else {
            out.printf(");%n");  //end of orig method.. start proxy additional stuff
            final boolean aFinal = Modifier.isFinal(returnType.getModifiers());
            if (!returnType.isPrimitive() && !returnType.isArray() && ! aFinal ){
                final String typeName = returnType.getTypeName();
                final String proxyGenerator = "org.rapidpm.module.se.commons.proxy.ProxyGenerator";
                final String concurrency = "org.rapidpm.module.se.commons.proxy.Concurrency";
                out.printf(" if (val == null) { System.out.println(\" val == null for method  + " +m.getName()+ "\");} %n");
                out.printf(typeName + " proxyObj = " + proxyGenerator+ ".make("+typeName+".class, "+typeName+".class, " +concurrency+"."+type.toString()+"); %n");

                if (type.equals(Concurrency.OnExistingObject)){
                    out.printf("try { %n");
                    out.printf("    proxyObj.getClass().getDeclaredField(\"realSubject\").set(proxyObj, val);  %n");
                    out.printf("} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {  %n");
                    out.printf("    e.printStackTrace(); %n");
                    out.printf("}  %n");
                }
                out.printf(" return proxyObj; %n");
            } else {
                out.printf(" return val; %n");
            }
                out.printf("%n}%n");
        }
    }

    private void addMethodSignature(PrintWriter out, Method m) {
        out.printf("%n public %s", Util.prettyPrint(m.getReturnType()));
        out.printf(" %s(", m.getName());
        addParameterList(out, m);
        out.printf(") {%n ");
    }

    private void addParameterList(PrintWriter out, Method m) {
        Class[] types = m.getParameterTypes();
        for (int i = 0; i < types.length; i++) {
            String next = i == types.length - 1 ? "" : ", ";
            out.printf("%s p%d%s", Util.prettyPrint(types[i]), i, next);
        }
    }

    private void addMethodBody(PrintWriter out, Method m) {
        addMethodBodyDelegatingToRealSubject(out, m);
    }

    private void addMethodBodyDelegatingToRealSubject(PrintWriter out, Method m) {
        //hole result
        final Class returnType = m.getReturnType();
        if (returnType == void.class) out.printf("realSubject().%s(", m.getName());
        else if(m.getName().equals("toString")){
            out.println("String val;");
            out.println(" if(realSubject() == null ) val = \"NullObjectHolder in \" + this.getClass() ; ");
            out.printf(" else val = realSubject().%s(", m.getName());
        } else if(m.getName().startsWith("get") && ! returnType.isPrimitive()){
            String name;
            if (returnType.isArray()) name = returnType.getSimpleName();
            else name = returnType.getName();
            out.println(name + " val;");
            out.println(" if(realSubject() == null ) val = null ; ");
            out.printf(" else val = realSubject().%s(", m.getName());   
        } else {
            String name;
            if (returnType.isArray()) name = returnType.getSimpleName();
            else name = returnType.getName();
            out.println(name + " val;");
            out.printf("val = realSubject().%s(", m.getName());  

        }
        addMethodCall(out, m);
    }

    private void addMethodCall(PrintWriter out, Method m) {
        Class[] types = m.getParameterTypes();
        for (int i = 0; i < types.length; i++) {
            String next = i == types.length - 1 ? "" : ", ";
            out.printf("p%d%s", i, next);
        }
    }
}
The result is really cool. see the following code ;-)
       DemoClassA demoClassA = new DemoClassA();
        demoClassA.demoClassB = null;

        final String value = proxy(demoClassA).getDemoClassB().getDemoClassC().getValue();
        System.out.println("value = " + value);

You can navigate the full path. no NPE! No boiler plate code!
@Test
    public void testGenerator00X() throws  Exception {
        DemoClassA demoClassA = new DemoClassA();
        demoClassA.demoClassB = null;

        final String value = proxy(demoClassA).getDemoClassB().getDemoClassC().getValue();
        System.out.println("value = " + value);

    }

private DemoClassA proxy(DemoClassA demoClassA) {
        final Class<DemoClassA> aClass = (Class<DemoClassA>) demoClassA.getClass();
        final DemoClassA demo = ProxyGenerator.make(aClass, aClass, Concurrency.OnExistingObject);

        final Class<? extends DemoClassA> aClassProxy = demo.getClass();
        try {
            aClassProxy.getDeclaredField("realSubject").set(demo,demoClassA );
        } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
            e.printStackTrace();
        }
        return demo;
    }
You can now use every getter.. not NPE. Only the result will be an null. This was exactly what I needed to get only the valid values from the model if they are available. This means, that you could proxy an object after you have initialized it. The full source code is available under : https://bitbucket.org/rapidpm/modules on the develop branch. I will merge it into the version 2.0 as generic pattern and CDI managed...

Montag, 17. Februar 2014

CDI EJB-Remote Context for wildfly

This article shows how ejb remote clients can be configured and connected in a more dynamic way.

Within wildfly (current version 8.0.0.Final) there are several possibilities to connect ejb remote clients. Descriptions can be found on:

The Problem


You have an application for two (or more) tenants which are identical but are deployed on different machines. Customers should be able to switch between those tenants without restarting the application. Additionally the code itself should not depend on tenant specific code.
As far as i know this would be necessary with the standard approach (jboss-ejb-client.properties) given above.

A Solution


After some consideration i have identified the following five components which are needed to implement this feature.
  • Component that creates WildFly ejb remote connections
  • Component that produces the JNDI-Context
  • Component that holds the selected tenant-key for the client
  • Component that maps the tenant-keys to connection properties
  • CDI-Modul Qualifier

Putting them together leads to the following UML:



To keep the example as simple as possible i have decided to use the ejb-remote-quickstart example and extend it with the jndicontext module. The current implementation uses a simple property file which holds the following data.
tenant1.host=localhost
tenant1.port=8080
tenant1.username=test
tenant1.password=test
tenant1.noanonymous=false

tenant2.host=192.168.0.104
tenant2.port=8080
tenant2.username=test
tenant2.password=test
tenant2.noanonymous=false

The Fazit


The resulting service locator just has to use the JndiSession (in this example the RemoteEJBClient) which technically holds the tenant key and can be set from the GUI.
public class RemoteEJBClient {
    @Inject @JndiContextAnno
    Instance<Context> contextInstance;

    @Inject
    JndiSession jndiSession;
    //...snip
    private RemoteCalculator lookupRemoteStatelessCalculator() throws NamingException {
        Context context = contextInstance.get();
        //...snip
    }
}

public class CDIBootStrapper {
    public static void main(String[] args) throws Exception
    {
        WeldContainer weld = new Weld().initialize();
        RemoteEJBClient client = weld.instance().select(RemoteEJBClient.class).get();

        client.getJndiSession().setTenantKey("tenant1");
        client.invokeStatelessBean();

        client.getJndiSession().setTenantKey("tenant2");
        client.invokeStatelessBean();
    }
)
So the code looks very clean and in comparison to jboss-ejb-client.properties way more functional.
The sources can be found on https://bitbucket.org/abischof/injectablejndicontext.
Have fun coding... ;)

Donnerstag, 13. Februar 2014

Raspberry Wildfly Cluster for less than 300€

So WildFly 8 is final now.
In this article i like to show how you can create a development/testing wildly cluster with raspberry pis and only one power supply.

I have bought:
  • 5x Raspberry Pis (Model B) with Wireless USB-Adapters
  • 1x 10-Port USB 2.0 Hub
  • 5x USB to Micro USB Adpapter

The Raspberries are configured with Raspbian Wheezy (wlan auto), JDK 8 and Wildfly 8 Final.
In this combination you have to remove the '-server' from the domain.sh otherwise WildFly won't start.

The WildFly Configuration can be made within 5 minutes.
  1. Master
    1. Create management user admin (./add-user.sh)
    2. Create a management slave user for each of your pi slaves (./add-user.sh)
      • Remember the secret value at the end of this process for each slave (e.g.<secret value="MTIzNDU=" />)
    3. Bind the interfaces to the public interface (e.g. 192.168.0.103) 
  2. Slave
    1. Configure host.xml with the slave name of 1.1
      • <host name="slave1" xmlns="urn:jboss:domain:2.0">
    2. Configure the server identity
      • <server-identities> <secret value="MTIzNDU="/> </server-identities>
    3. Bind the interfaces to master and public interface (e.g. 192.168.0.104)
      • To simply the typing i have written a small script that takes the master-ip and the bind-ip
      • #MasterAdress
        MASTER_ADDRESS=$1
        
        # Bind Addresses
        BIND_ADDRESS=$2
        
        JBOSS_BIND_ADDRESS_MANAGEMENT=$BIND_ADDRESS
        JBOSS_BIND_ADDRESS=$BIND_ADDRESS
        JBOSS_BIND_ADDRESS_UNSECURE=$BIND_ADDRESS
        
        sudo ./domain.sh -Djboss.bind.address.unsecure=$JBOSS_BIND_ADDRESS_UNSECURE -Djboss.bind.address.management=$BOSS_BIND_ADDRESS_MANAGEMENT -Djboss.bind.address=$JBOSS_BIND_ADDRESS -Djboss.domain.master.address=$MASTER_ADDRESS
Ready. Now you can deploy any archive either to main-server-group (just a domain) or other-server-group (full cluster).

Montag, 10. Februar 2014

JDK8/Streams are cool? Here is the answer. ;-)

Today I was preparing a few slides for my next JUG talk. For this if started with a normal piece of code like the following.
  
    public List<List<Integer>> generateDemoValueMatrix() {
        final List<List<Integer>> resultMatrix = new ArrayList<>();
        final Random random = new Random();
        for(int anzahlKurven = 0; anzahlKurven <ANZAHL_KURVEN; anzahlKurven++){
            final List<Integer> result = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                final int nextInt = random.nextInt(100);
                result.add(nextInt);
            }
            resultMatrix.add(result);
        }
        return resultMatrix;
    }

Next step would be the creation of two methods...
  
    public List<List<Integer>> generateDemoValueMatrix() {
        final List<List<Integer>> result = new ArrayList<>();
        for(int anzahlKurven = 0; anzahlKurven <ANZAHL_KURVEN; anzahlKurven++){
            final List<Integer> demoValuesForY = generateDemoValuesForY();
            result.add(demoValuesForY);
        }
        return result;
    }
    public List<Integer> generateDemoValuesForY() {
        final Random random = new Random();
        final List<Integer> result = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            final int nextInt = random.nextInt(100);
            result.add(nextInt);
        }
        return result;
    }
Ok, look´s like always... booooring.... So I started with Streams..
    public List<List<Integer>> generateDemoValueMatrix() {
        return Stream
                .generate(this::generateDemoValuesForY)
                .limit(ANZAHL_KURVEN)
                .collect(Collectors.toList());
    }
    public List<Integer> generateDemoValuesForY(){
        final Random random = new Random();
        return Stream
                .generate(() -> {
                    return random.nextInt(100);
                })
                .limit(10)
                .collect(Collectors.toList());
    }
Not really better.. only new syntax.. now reducing the syntax..
    public List<List<Integer>> generateDemoValueMatrix() {
        return Stream
                .generate(this::generateDemoValuesForY)
                .limit(ANZAHL_KURVEN)
                .collect(Collectors.toList());
    }
    public List<Integer> generateDemoValuesForY(){
        final Random random = new Random();
        return Stream
                .generate(() -> random.nextInt(100))
                .limit(10)
                .collect(Collectors.toList());
    }

But Random offer something new.
    public List<List<Integer>> generateDemoValueMatrix() {
        return Stream
                .generate(this::generateDemoValuesForY)
                .limit(ANZAHL_KURVEN)
                .collect(Collectors.toList());
    }
    public List<Integer> generateDemoValuesForY(){
        return new Random()
                .ints(0, 100)
                .limit(10)
                .boxed()
                .collect(Collectors.toList());
    }
Combining both methods..
    public List<List<Integer>> generateDemoValueMatrix() {
        final Random random = new Random();
        return Stream.generate(
                    () -> Stream.generate(
                            () -> random.nextInt(100))
                            .limit(10)
                            .collect(Collectors.toList())
                )
                .limit(ANZAHL_KURVEN)
                .collect(Collectors.toList());
    }
OK, not short enough.. we could it better..
    public List<List<Integer>> generateDemoValueMatrix() {
        return Stream.generate(
                () -> new Random()
                        .ints(0, 100)
                        .limit(10)
                        .boxed()
                        .collect(Collectors.toList())
                ).limit(ANZAHL_KURVEN)
                .collect(Collectors.toList());
    }
Uuuppsss.. static imports possible.. ;-)
    public List<List<Integer>> generateDemoValueMatrix() {
        return generate(() -> new Random()
                .ints(0, 100)
                .limit(10).boxed().collect(toList())
        ).limit(ANZAHL_KURVEN).collect(toList());
    }
Now compare with the first and decide ;-) Streams are cool ? I think so!!

Lego Mindstorms EV3 Components: Infrared Sensor - Part 2

In this second part on the mindstorm's infrared sensor we will focus on the remote control and the ability of the remote sensor to recognize commands from that remote control respectively. There are multiple buttons on that remote control and we will control the robot by pressing different buttons.

The robot

We will use the robot from the first part as it already uses the infrared sensor. The mindstorm's remote control looks like the following:


There are two buttons on the left (red) and two buttons on the right (blue). There is a fifth button at the top center which is (in contrast to all other buttons) a toggling button. So if you press it one time, the remote control sends a signal continuously until the button is pressed a second time. Before taking the photo I pressed that button one time to activate the green signal led. We will use that toggle button on the next part of the infrared sensor articles.
The red slider at the bottom center is for selecting a frequency channel. You can select four channels and the current channel is shown in the red circle under the toggling button.

The parcours

There is the robot and there is the remote control. The aim is to press different buttons on the remote control to control and move the robot. We will use the two buttons on the left to let the robot rotate left/right, respectively the two buttons on the right to let the robot move forwards/backwards. When more than one button is pressed, the program should exit.


The infrared sensor API

There are two relevant modes for the infrared sensor. The distance mode and the seek mode. We used the former implicitly in the last article and we will use it in this one because it offers the possibility to receive commands from the infrared remote control. The latter can be used to receive the position and the distance of the remote control to the robot (the next tutorial will use the seek mode).

It's very easy to receive a command from the remote control. The only method we will use is infraredSensor.getRemoteCommand(0);
This will return an integer value which represents the pressed button on the remote control (e.g. the left upper button on the remote control will return 1). The parameter of the method is also an integer value which represents the frequency channel which we use on the remote control. You can select one of four different channels (via the red slider on the remote control). In this case we use channel 0 (which is called channel 1 on the remote control).

That's it. We don't need RangeFinderAdaptors, RangeFeatureDetectors or anything like that this time. So let's directly jump to the finished code and see how it works.

The code

There are two classes. The Main-class and an InfraredSignalCheckerThread, which extends Thread and contains the logic for received commands from the remote control.

Let's start with the Main-Class:

import lejos.hardware.Button;
import lejos.hardware.motor.Motor;
import lejos.hardware.port.SensorPort;
import lejos.hardware.sensor.EV3IRSensor;
import lejos.robotics.navigation.DifferentialPilot;

public class Main {

    protected final static double NINETY_DEGREES = 90.0;
    protected final static double PILOT_SPEED = 100.0;
    protected final static int PILOT_ACCELERATION = 500;
    protected final static double WHEEL_DIAMETER = 30.0f;
    protected final static double DISTANCE_BETWEEN_WHEELS = 170.0;

    public static void main(String[] args) throws InterruptedException {

        final DifferentialPilot pilot = new DifferentialPilot(WHEEL_DIAMETER, DISTANCE_BETWEEN_WHEELS, Motor.C, Motor.B);
        final EV3IRSensor infraredSensor = new EV3IRSensor(SensorPort.S2);
        final InfraredSignalCheckerThread checkerThread = new InfraredSignalCheckerThread(infraredSensor, pilot);

        configurePilot(pilot);
        checkerThread.start();
        Button.waitForAnyPress();
    }

    private static void configurePilot(final DifferentialPilot pilot) {
        pilot.setAcceleration(PILOT_ACCELERATION);
        pilot.setRotateSpeed(PILOT_SPEED);
        pilot.setTravelSpeed(PILOT_SPEED);
    }
}

If you've (hopefully) read our last article on the infrared sensor, you will recognize that the Main-class became a bit smaller this time. We don't have to configure anything on the infrared sensor.
First we create instances for the pilot and the infrared sensor again. The new thing is the InfraredSignalCheckerThread which extends Thread. This class contains all the logic for received commands. The logic is implemented in a Thread-extending class because we want to listen continuously for any received commands. The created instance of the InfraredSignalCheckerThread needs the infraredSensor-object of course and it needs the pilot (because we will control/move the robot corresponding to the pressed button on the remote control).

After we created the instances we configure the pilot and start the checkerThread. That's it. Let's have a look at the InfraredSignalCheckerThread-class now.

The InfraredSignalCheckerThread-class:

import lejos.hardware.sensor.EV3IRSensor;
import lejos.robotics.navigation.DifferentialPilot;

public class InfraredSignalCheckerThread extends Thread {

    private EV3IRSensor infraredSensor;
    private DifferentialPilot pilot;

    public InfraredSignalCheckerThread(final EV3IRSensor infraredSensor, final DifferentialPilot pilot){
        this.infraredSensor = infraredSensor;
        this.pilot = pilot;
    }

    @Override
    public void run() {
        while(true){
            final int remoteCommand = infraredSensor.getRemoteCommand(0);
            switch (remoteCommand){
                case 0:
                    pilot.quickStop();
                    break;
                case 1:
                    pilot.rotateLeft();
                    break;
                case 2:
                    pilot.rotateRight();
                    break;
                case 3:
                    pilot.forward();
                    break;
                case 4:
                    pilot.backward();
                    break;
                default:
                    System.out.println("button combination pressed..exiting...");
                    System.exit(0);
            }
        }
    }
}

Let's have a look at the run-method. As you can see we have an infinite loop. In that loop we get an integer command from the method infraredSensor.getRemoteCommand(0). The given parameter (0) means that the infrared sensor should listen at frequency channel 0 (remember the red slider on the remote control for selecting a channel).
So now the thread is checking for any commands on channel 0 continuously. As next we check which command was sent. The different buttons send different integer values. Here is the documentation from within the EV3IRSensor-class:

/** The button values are:
* 1 TOP-LEFT
* 2 BOTTOM-LEFT
* 3 TOP-RIGHT
* 4 BOTTOM-RIGHT
* 5 TOP-LEFT + TOP-RIGHT
* 6 TOP-LEFT + BOTTOM-RIGHT
* 7 BOTTOM-LEFT + TOP-RIGHT
* 8 BOTTOM-LEFT + BOTTOM-RIGHT
* 9 CENTRE/BEACON
* 10 BOTTOM-LEFT + TOP-LEFT
* 11 TOP-RIGHT + BOTTOM-RIGHT
* (0 means no buttons pressed)
*/

So, as you can see if no button is pressed on the remote control the method will return 0. The four buttons we want to use return 1, 2, 3 and 4.
Knowing these return values the switch statement becomes very easy to understand. If no button is pressed the robot shouldn't move. If the top left button is pressed the robot should rotate to the left and so on, we just call the corresponding methods of the DifferentialPilot-class to control the motors. If more than one button is pressed at a time the program should exit.

The result

And here is the result (watch on youtube for better quality):



Some words on complications that I had while writing the program: After starting the CheckerThread I had to wait around 30 seconds before pressing a button on the remote control. I have no explaination for that but when I pressed any button earlier the robot moved very jerkily. I tried different workarounds like Thread.sleep() and Delay.ms() in the main-method and the checker-thread. I also tried a timer in the CheckerThread which printed a message on the console to tell the user that the program isn't yet ready if he tried to press any button during those first 30 seconds. But none of these attempts worked.

Freitag, 7. Februar 2014

FXController with CDI managed DynamicObjectAdapter - Part 2

Based on my blog article part 1 we want to integrate the DynamicObjectAdapter into an JavaFX application. To remember: We have an interface called DemoLogic with two methods. add(..) and sub(..) The implementation is really simple, but at runtime we could switch the implementation partially. For this we needed an adapter.
The biggest tdifference compared to the default CDI decorator was, that we need no definition inside the beans.xml. The implementation is smaller and no need for Qualifiers and other biolder-plate code.
This DemoLogic we want to use now inside an JavaFX application. For this we ned first an fxml.file called DemoPane.fxml. Here we will define a few elements.
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.CheckBox?>
<fx:root type="javafx.scene.layout.AnchorPane"
            xmlns:fx="http://javafx.com/fxml">
    <children>
        <VBox>
            <children>
                <Button fx:id="button" text="Hello World" />
                <CheckBox fx:id="checkbox" text="switch context"/>
                <TextField fx:id="textFieldA"/>
                <TextField fx:id="textFieldB"/>
                <Label fx:id="label"/>
            </children>
        </VBox>

    </children>

</fx:root>
With the button we will activate the calculation, with the checkbox we will switch the context. To have a small as possible implementation, there is no error checking.
The next will be the controller called DemoController. This is a normal JavaFX Controller, but CDI managed. How to get this? Well there is a good blog article here ;-) CDI JavaFX bootstrapping.
Inside the DemoController we will get an Instance of the DemoLogic and the Context.
@Inject
    @DynamicDecoratorTest
    Instance<DemoLogic> demoLogicInstance;

    @Inject
    Context context;
The full implementation will be like the following.
@DynamicDecoratorTest
public class DemoController implements Initializable{

    @FXML public TextField textFieldA;
    @FXML public TextField textFieldB;
    @FXML public Button button;
    @FXML public Label label;
    @FXML public CheckBox checkbox;

    @Inject
    @DynamicDecoratorTest
    Instance<DemoLogic> demoLogicInstance;

    @Inject
    Context context;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        button.setText("klick me");
        button.setOnAction(actionEvent -> {

            final DemoLogic demoLogic = demoLogicInstance.get();

            final String textFieldAText = textFieldA.getText();
            final Integer a = Integer.valueOf(textFieldAText);

            final String textFieldBText = textFieldB.getText();
            final Integer b = Integer.valueOf(textFieldBText);

            final int result = demoLogic.add(a, b);
            label.setText(result+"");

        });

        checkbox.setOnAction(actionEvent -> {
            context.original = checkbox.isSelected();
        });
    }
}
Inside the method initialize you will find the connection between the GUI logic and the business logic. This is now clean devided.
To test this I was using Arquillian. LAter we will see how we could do this with TestFX. We are working on the CDI Support.
@RunWith(Arquillian.class)
public class DemoLogicTest {
    @Deployment
    public static JavaArchive createDeployment() {
        return ShrinkWrap.create(JavaArchive.class)
                .addPackages(true, "org.rapidpm.demo")
                .addPackages(true, "junit.org.rapidpm.demo")
                .addPackages(true, "demo")
                .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
    }

    @Inject @DynamicDecoratorTest
    Instance<DemoController> demoControllerInstance;
    @Inject
    Context context;

    static final FXMLLoader loader = new FXMLLoader();

    @Test
    public void testDemoLogicJavaFXTest() throws Exception {
        loader.setControllerFactory(param -> demoControllerInstance.get());
        Application.launch(DemoApp.class);
    }


    public static class DemoApp extends Application {
        @Override
        public void start(Stage stage) throws Exception {

            final URL resource = getClass()
                    .getClassLoader()
                    .getResource("DemoPane.fxml");
            loader.setLocation(resource);
            final DemoController controller = (DemoController) loader
                    .getControllerFactory()
                    .call(DemoController.class);
            try {

                loader.setController(controller);
                loader.setRoot(new AnchorPane());
                final Parent root = (Parent) loader.load();

                stage.setScene(new Scene(root));
                stage.setTitle("Custom Control");
                stage.setWidth(300);
                stage.setHeight(200);
                stage.show();
            } catch (IOException exception) {
                throw new RuntimeException(exception);
            }

        }

        public static void main(String[] args) {
            launch(args);
        }
    }
}

You never need the decorator from CDI anymore. ;-)

Dienstag, 4. Februar 2014

TestFX a must for jUnit Tests inside JavaFX environments!

You have written jUnit Tests for JavaFX applications? 
You want to simulate user interactions?

If you are starting from scratch this will be a long task.
But the Team from TestFX is working on a solution.
TestFX (https://github.com/SmartBear/TestFX) is an OpenSource framework from Henrik Olsson (SmartBear) with the goal to be an easy-to-use framework for testing JavaFX.

This framework is ready for Java8 and supports JavaFX 2.
With this you are able to test featured JavaFX based GUIs.

No License needed, no costs, complete OpenSource and extensible.

The fluent and clean API is simple to use for the interaction with the controls. No special wrapper must be implemented, no boilerplate code is needed to test a simple control. Extend the jUnit Test-class and create an instance of your JavaFX control.

That´s all you need. After this you are able to interact directly with the instance you created.
TestFX will give you a lot of service methods to interact and verify the behavior of the tested control.
And, if something goes wrong, you will get an screenshot of the failed test.

One of the really big advantages is the easy possibility to extend TestFX by yourself. The framework is clean and well structured.
The support for Hamcrest Matchers and Lambdas will give you all you need to build complex tests.

There is only one more thing....
...  we are working on the CDI support for TestFX.

stay tuned and happy coding.

Montag, 3. Februar 2014

One way to deadlock a JBoss AS 7

Take a standard JBoss AS 7 and create/deploy a simple remote stateless session bean with two methods. One of them should be asynchronous. As shown in the following example the asynchronous method creates a little bit of load and the second one simulates a login.
public interface IMyBean
{
 Future<Void> doNothing();
 void login();
}
@Stateless
@Remote(IMyBean.class)
public class MyBean implements IMyBean
{
 @Override
 @Asynchronous
 public Future<Void> doNothing()
 {
  //Creates Load
  int lo = 0;
  for (int i = 0; i < 5000; i++)
  {
   lo += i;
  }
  System.out.println("nothing done");
  return new AsyncResult<Void>(null);
 }
 @Override
 public void login()
 {
  System.out.println("logged in");
 }
}
In the next step besides 10 EJB-Remote-Clients which access the asynchronous method parallel we create an additional client which repeatly tries to login. (Note: Classpath contains jboss-ejb-client.properties and jboss-client.jar)
public class HangTest
{
 public static void main(String args[]) throws NamingException
 {
  //EJB-Remote-Access
  Properties jndiProps = new Properties();
  jndiProps.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
  Context context = new InitialContext(jndiProps);
  final IMyBean myBean = (IMyBean) context.lookup("ejb:/hangtest/MyBean!IMyBean");

  //Create and start asynchronous method threads
  final List<Thread> threadList = new ArrayList<>();
  for (int i = 0; i < 10; i++)
  {
   Thread thread = new Thread()
   {
    @Override
    public void run()
    {
     try
     {
      myBean.doNothing().get();
     }
     catch(Exception e)
     {
      e.printStackTrace();
     }
     finally
     {
      threadList.remove(this);
     }
    }
   };
   threadList.add(thread);
   thread.start();
  }

  //Repeated Login
  while(!threadList.isEmpty())
  {
   System.out.println("Try login...");
   myBean.login();
  }
 }
}
The code above works as expected which means that random server messages ("nothing done", "logged in") are printed out and that the login client can login. It also can be executed as many times as you want without a change in behavior.
BUT if you increase the number of asynchronous method clients for example to 20-30 (depending on your computer) then nothing is printed out and the login client can not login anymore. The JBoss or - to be more specific - some components of it are in a deadlock (Note: JBoss shutdown does not work anymore). So what has happened?

To answer this question we have to look into the standalone.xml, especially in the subsystem "urn:jboss:domain:ejb3". This section contains ejb3-related configurations and among them threadpools. In this context it is important that the default threadpool is shared between asynchronous calls, timers and ejb-remote.
<subsystem xmlns="urn:jboss:domain:ejb3:1.2">
...
 <async thread-pool-name="default"/>
 <timer-service thread-pool-name="default">
  <data-store path="timer-service-data" relative-to="jboss.server.data.dir"/>
        </timer-service>
 <remote connector-ref="remoting-connector" thread-pool-name="default">
  <thread-pools>
   <thread-pool name="default">
    <max-threads count="10"/>
    <keepalive-time time="100" unit="milliseconds"/>
   </thread-pool>
  </thread-pools>
   </remote>
</subsystem>

So if you stumble upon that problem either increase the max-thread count property or even better seperate the thread-pools for asynchronous and ejb-remote components.

Montag, 27. Januar 2014

Lego Mindstorms EV3 Components: Infrared Sensor - Part 1

Now that we have demonstrated how to work with motors, the next component we will focus on is a sensor - the infrared sensor.

In this first part we will show how to use the ability of the sensor to find objects and recognize the distance between that object and the sensor. There are other functionalities like receiving commands from the infrared remote control, which we will focus on in later posts.

The used lejos version is 0.5.0-alpha like in our last postings as it is still the most current version (01/27/2014).

The robot

First, as always, we needed a new robot which uses the infrared sensor. Therefore I just enhanced the robot from the last episode a bit (so if you want to understand the source code in this posting it will help if you already have checked the two postings about using motors). I strengthened the basement between the two wheels, so that it wouldn't break because of the weight of the brick and other components. The brick is now no longer located directly between the wheels, but a bit more above. Additionally, I mounted the infrared sensor centered above / in front of the brick and plugged it into the sensor plug 2. The result looks like the following.



( could be a relative of disney's wall-e )

The parcours

As said, in this tutorial we will focus on the ability of the infrared sensor to locate objects and return the objects' distance.

The scenario I created for that purpose:
We have a walled zone (cage). The robot is placed anywhere in that cage and the robot will always move forwards until he is directly in front of a wall. He then will turn left (90°) and will again move forwards until he reaches the next wall.



The infrared sensor API

So, before looking at the code let's talk a bit about what classes and methods the api offers for the infrared sensor.

It's quite easy to use an infrared sensor. You can simply instantiate an object of the EV3InfraredSensor-class. The (slightly) harder part is to tell the program to use the functionality of the sensor to detect objects and return their distances - and react on the returned values of course. Therefore you need: RangeFinderAdaptor, RangeFeatureDetector and FeatureListener.

But it's not as hard as it might seem now.
The aim is to have a listener on the sensor, so that the it returns the distance of a recognized object in regular time intervals (let's say: return the object's distance every second).
We need a class, which implements the FeatureListener, to do that. In my opinion the name FeatureListener is a bit confusing.. "Feature" means the object that has been detected by the sensor. The class which implements it has to implement the method
public void featureDetected(final Feature feature, final FeatureDetector detector);
And this method is called in the given interval, so we react to the distance of the detected object here (we will see how that works in the code for the parcours).
But that implementing class is the last thing we will do.
The regular order for realizing our aim with the instantiated Sensor-object is:
  1. Instantiate a RangeFinderAdaptor-object and tell it in which mode the sensor is used
  2. Instantiate a RangeFeatureDetector-object and tell it: the interval of checking the object's distance and the maximum distance of objects. It also needs the (prior to this step) created RangeFinderAdaptor-object.
  3. Instantiate an object of the class which implements the FeatureListener
  4. Add the instantiated listener from step 3 to the RangeFeatureDetector-object from step 2.
That's it. So after the theory let's have a look at the finished plain code.

The code

We have two classes this time. The Main-Class (as always) and the class which implements the needed FeatureListener.

Let's start with the Main-Class:

import lejos.hardware.Button;
import lejos.hardware.motor.Motor;
import lejos.hardware.port.SensorPort;
import lejos.hardware.sensor.EV3IRSensor;
import lejos.robotics.RangeFinderAdaptor;
import lejos.robotics.navigation.DifferentialPilot;
import lejos.robotics.objectdetection.FeatureListener;
import lejos.robotics.objectdetection.RangeFeatureDetector;
import lejos.utility.Delay;

public class Main {

    protected final static double NINETY_DEGREES = 90.0;
    protected final static double PILOT_SPEED = 50.0;
    protected final static int PILOT_ACCELERATION = 25;
    protected final static float MAX_DISTANCE = 100.0f;
    protected final static int INTERVAL = 500;
    protected final static double WHEEL_DIAMETER = 30.0f;
    protected final static double DISTANCE_BETWEEN_WHEELS = 170.0;

    public static void main(String[] args) {

        final DifferentialPilot pilot = new DifferentialPilot(WHEEL_DIAMETER, DISTANCE_BETWEEN_WHEELS, Motor.C, Motor.B);
        final EV3IRSensor infraredSensor = new EV3IRSensor(SensorPort.S2);

        configurePilot(pilot);
        configureInfraredSensor(infraredSensor, pilot);

        //wait for the sensor to be completely initialized and start the robot
        Delay.msDelay(5000);
        System.out.println("    Starting!");
        pilot.forward();
        Button.waitForAnyPress();
    }

    private static void configureInfraredSensor(final EV3IRSensor infraredSensor, final DifferentialPilot pilot) {
        final RangeFinderAdaptor rangeFinderAdaptor = new RangeFinderAdaptor(infraredSensor.getDistanceMode());
        final RangeFeatureDetector rangeFeatureDetector = new RangeFeatureDetector(rangeFinderAdaptor, MAX_DISTANCE, INTERVAL);
        final FeatureListener detectedObjectListener = new DetectedObjectListener(pilot);
        rangeFeatureDetector.addListener(detectedObjectListener);
    }

    private static void configurePilot(final DifferentialPilot pilot) {
        pilot.setAcceleration(PILOT_ACCELERATION);
        pilot.setRotateSpeed(PILOT_SPEED);
        pilot.setTravelSpeed(PILOT_SPEED);
    }
}

The main-method is quite short and simple. In the first part we instantiate the pilot to control the wheels/motors and the infrared sensor. For more information on the pilot check the corresponding postings about using motors with the lejos api if you haven't done yet).
The EV3InfraredSensor-class only needs to know which plug it is plugged into to create a corresponding object.

After creating our needed pilot and sensor we need to configure them. Have a look at the configureInfraredSensor-method. That's were we realize the things described in the last paragraph.
  1. We create a RangeFinderAdaptor-object by telling the constructor in which mode the sensor should work.
  2. We create a RangeFeatureDetector and assign the RangeFinderAdaptor-object plus the maximum distance of objects and the interval where the sensor should check for objects.
  3. We create a FeatureListener-object which needs the pilot because we will control the pilot in it. We will see the implementation of the listener next.
  4. We assign the created listener to the RangeFeatureDetector so the featureDetected-method of the listener is called in the configured interval.
After configuring the sensor I set a delay of five seconds because the configuration needs some time. When I tried starting the pilot without a delay it came to weird reactions like the robot moving forwards and backwards some millimeters jerkily.
After the delay the robot will start moving forwards and the rest of the code is done in the listener, so let's have a look at it next. (Button.waitForAnyPress() is just used to let the program continue. Without that line the program would just end before the robot even started moving.)

The Listener-class:

import lejos.robotics.navigation.DifferentialPilot;
import lejos.robotics.objectdetection.Feature;
import lejos.robotics.objectdetection.FeatureDetector;
import lejos.robotics.objectdetection.FeatureListener;
import static org.rapidpm.ev3.infrared.Main.*;

public class DetectedObjectListener implements FeatureListener {

    private DifferentialPilot pilot;

    public DetectedObjectListener(final DifferentialPilot pilot) {
        this.pilot = pilot;
    }

    @Override
    public void featureDetected(final Feature feature, final FeatureDetector detector) {
        int range = (int)feature.getRangeReading().getRange();
        if(range <= 10){
            if(range <=2){
                System.exit(0);
            }
            pilot.stop();
            pilot.rotate(NINETY_DEGREES);
            pilot.forward();
        }
    }
}

We have a field for the pilot from the constructor which we will use in the featureDetected()-method which is called in the configured interval.
In that method we get the distance/range of a recognized object from the Feature-object (which represents the detected object).
If the range is greater than 10 (centimeters), nothing will happen. The robot will of course continue moving forward (remember that in the main-method we called pilot.forward() and told the program to wait for a button press to exit the program).
If the range is lower than 10, we know that the robot has reached a wall. So we tell the pilot to stop. After that we let the robot rotate by 90°. At last we tell the pilot to move forwards again. An exception to that behavior is the special case if the range is lower or equals 2 cm. If that is the case the program will exit. Why is that? Without that backdoor, the program would run until any button of the brick is pressed (remember the main-method). But instead of having to grab the robot and press a button we now can just hold any object directly in front of the infrared sensor and the program will exit.

The result

At the end I added some console output to the featureDetected-method to have some feedback during the execution of the program.

    @Override
    public void featureDetected(final Feature feature, final FeatureDetector detector) {
        int range = (int)feature.getRangeReading().getRange();
        if(range <= 10){
            if(range <=3){
                System.out.println("Recognized signal directly on front of me: exiting!");
                System.exit(0);
            }
            System.out.print("Reached wall! Stopping...");
            pilot.stop();
            System.out.println("done!");
            System.out.print("Rotating 90 degrees...");
            pilot.rotate(NINETY_DEGREES);
            System.out.println("done!");
            pilot.forward();
        } else {
            System.out.println("range: "+range);
        }
    }

And here is the result (watch on youtube for better quality):


Montag, 20. Januar 2014

IoT with Java8 and TinkerForge Part 2

One of the interesting features of TinkerForge is the possibility to put different elements like sensors, physical buttons, and more on a MasterBrick

This is what we want to do today.

The Barometer
Today we are using the Barometer-Bricklet. The Barometer Bricklet can be used to extend the features of Bricks by the capability to measure air pressure in range of 10 to 1200mbar with a resolution of 0.012mbar. The measurement is temperature compensated internally. The Bricklet is equipped with a MS5611-01BA01 sensor which is designed to be used as an altimeter, too.

At https://bitbucket.org/rapidpm/jaxenter.de-0012-iot-tinkerforge are all source codes you will need, including the TinkerForge API itself. I spoke with TinkerForge and we decided to put the API into maven. After we have done this, I will inform you. If you are interested, follow me on Twitter please ( @SvenRuppert )

The most interesting part for us today will be the presents of two sensors inside of one Bricklet.
How we can handle it and how we will get the data to the screen?

Connect to n - Sensor-units
To remember... To connect to a sensor you need an instance of the representing class. To get the value from the sensor you have to implement an ActionListener. Here the short example from my last blog about TinkerForge. (engl / ger)

import com.tinkerforge.BrickletTemperature;
import com.tinkerforge.IPConnection;
public class ExampleCallback {
  private static final String host = "localhost";
  private static final int port = 4223;
  private static final String UID = "dXj";
  public static void main(String args[]) throws Exception {
    IPConnection ipcon = new IPConnection();
    BrickletTemperature temp = new BrickletTemperature(UID, ipcon);
    ipcon.connect(host, port);
    temp.setTemperatureCallbackPeriod(1000);
    temp.addTemperatureListener(new
    BrickletTemperature.TemperatureListener() {
      public void temperature(short temperature) {
        System.out.println("Temperature: "
        + temperature/100.0 + " °C");
      }
    });
    ipcon.disconnect();
}
}
The same will be with the two sensor-units inside the Barometer-Bricklet. The class name will be BrickletBarometer, and you have to implement two ActionListeners. One for the air-pressure called AirPressureListener and one for the altitude called AltitudeListener.

public class ExampleCallback {
    private static final String host = "localhost";
    private static final int port = 4223;
    private static final String UID = "jY4";

    public static void main(String args[]) throws Exception {
        IPConnection ipcon = new IPConnection();
        BrickletBarometer b = new BrickletBarometer(UID, ipcon);
        ipcon.connect(host, port);
        b.setAirPressureCallbackPeriod(1000);
        b.setAltitudeCallbackPeriod(1000);
        b.addAirPressureListener(
                new BrickletBarometer.AirPressureListener() {
                    public void airPressure(int airPressure) {
                        System.out.println("Air Pressure: "
                                + airPressure / 1000.0 + " mbar");
                    }
                }
        );
        b.addAltitudeListener(new BrickletBarometer.AltitudeListener() {
            public void altitude(int altitude) {
                System.out.println("Altitude: " + altitude / 100.0 + " m");
            }
        });
        ipcon.disconnect();
    }
}
Connection to JavaFX
The connection to JavaFX could be simple. The basic steps are always the same. You have to start an Thread outside our JavaFX GUI Thread. Inside this thread you have to configure the sensor and inside the run()- method you have to add the action listener. All steps that are manipulating the GUI, you have to start again inside a Platform.runLater() Now, we have to sensor-units. This means that we are doing this twice. To reuse the code later, we are extracting it into an separate class. If we would do it for the temperature sensor we used last time, it will look like the following.

public class Temp implements Runnable {

  private String UID;
  private ObservableList seriesData;

  public Temp(final String UID, final XYChart.Series series) {
      this.UID = UID;
      this.seriesData = series.getData();
  }

  @Override
  public void run() {
      IPConnection ipcon = new IPConnection();
      BrickletTemperature temp = new BrickletTemperature(UID, ipcon);
      try {
          ipcon.connect(Barometer.host, Barometer.port);
          temp.setTemperatureCallbackPeriod(1000);
          temp.addTemperatureListener(new BrickletTemperature.TemperatureListener() {
              public void temperature(short temperature) {
                  Platform.runLater(new Runnable() {
                      @Override
                      public void run() {
                          final double temp = temperature / 100.0;
                          System.out.println("Temperature: " + temp + " °C");
                          final XYChart.Data data = new XYChart.Data(new Date(), temp);
                          seriesData.add(data);
       }
                  });
              }
          });
      } catch (IOException 
       | AlreadyConnectedException 
    | TimeoutException 
    | NotConnectedException e) {
          e.printStackTrace();
      }
  }
}
For the Barometer-Bricklet I was writing two classes. One for the airpressure and one for the altitude. Both are identically, with one difference. The implementation of the ActionListener. Every sensor will put his data to a separate LineChart.
 This implementation is not perfect, because we are not disconnecting from the sensor in the end, and for one Bricklet we have two representing classes. Both instances are in a different thread. But this is still running over a longer period. (at least a few days with my laptop) How to encapsulate this in better way we will see in one of my next posts.

public class Altitude implements Runnable {

    private String UID;
    private ObservableList seriesData;

    public Altitude(final String UID, final XYChart.Series series) {
        this.UID = UID;
        this.seriesData = series.getData();
    }

    @Override
    public void run() {
        IPConnection ipcon = new IPConnection();
        BrickletBarometer b = new BrickletBarometer(UID, ipcon);

        try {
            ipcon.connect(Barometer.host, Barometer.port);
            b.setAirPressureCallbackPeriod(1000);
            b.addAltitudeListener(new BrickletBarometer.AltitudeListener() {
                public void altitude(int altitude) {
                    System.out.println("Altitude: " + altitude / 100.0 + " m");
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            final double temp = altitude / 100.0;
                            final XYChart.Data data = new XYChart.Data(new Date(), temp);
                            seriesData.add(data);
                        }
                    });
                }
            });
        } catch (IOException | AlreadyConnectedException | TimeoutException | NotConnectedException e) {
            e.printStackTrace();
        }
    }
}

public class Airpressure implements Runnable {

    private String UID;
    private ObservableList seriesData;

    public Airpressure(final String UID, final XYChart.Series series) {
        this.UID = UID;
        this.seriesData = series.getData();
    }

    @Override
    public void run() {
        IPConnection ipcon = new IPConnection();
        BrickletBarometer b = new BrickletBarometer(UID, ipcon);

        try {
            ipcon.connect(Barometer.host, Barometer.port);
            b.setAirPressureCallbackPeriod(1000);
            b.addAirPressureListener(new BrickletBarometer.AirPressureListener() {
                public void airPressure(int airPressure) {
                    System.out.println("Air Pressure: " + airPressure / 1000.0 + " mbar");
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            final double temp = airPressure / 1000.0 ;
                            final XYChart.Data data = new XYChart.Data(new Date(), temp);
                            seriesData.add(data);
                        }
                    });
                }
            });
        } catch (IOException 
     | AlreadyConnectedException 
     | TimeoutException 
     | NotConnectedException e) {
            e.printStackTrace();
        }
    }
}
Putting all together we will get the following main.

public class Barometer extends Application {
    public static final String host = "localhost";
    public static final int port = 4223;


    public static void main(String args[]) throws Exception {
        launch(args);
    }

    public static XYChart.Series seriesTemp = new XYChart.Series();
    public static XYChart.Series seriesAirpressure = new XYChart.Series();
    public static XYChart.Series seriesAltitude = new XYChart.Series();

    @Override
    public void start(Stage stage) {
        stage.setTitle("Line Chart TinkerForge Sample");

        final VBox box = new VBox();
        seriesTemp.setName("Temp");
        seriesAirpressure.setName("Airpressure");
        seriesAltitude.setName("Altitude");

        final ObservableList boxChildren = box.getChildren();
        boxChildren.add(createLineChart("Temp", seriesTemp));
        boxChildren.add(createLineChart("Airpressure", seriesAirpressure));
        boxChildren.add(createLineChart("Altitude", seriesAltitude));

        Scene scene = new Scene(box, 2000, 1500);

        stage.setScene(scene);
        stage.show();
        Platform.runLater(new Temp("dXj", seriesTemp));
        Platform.runLater(new Airpressure("jY4", seriesAirpressure));
        Platform.runLater(new Altitude("jY4", seriesAltitude));
    }

    private LineChart createLineChart(final String chartName,final XYChart.Series series ){
        final DateAxis dateAxis = new DateAxis();
        dateAxis.setLabel("Time");
        final NumberAxis yAxis = new NumberAxis();

        final LineChart lineChart = new LineChart<>(dateAxis, yAxis);
        lineChart.setTitle(chartName);
        lineChart.getData().add(series);

        return lineChart;
    }
}

At https://bitbucket.org/rapidpm/jaxenter.de-0012-iot-tinkerforge are all source codes you will need, including the TinkerForge API itself. I spoke with TinkerForge and we decided to put the API into maven. After we have done this, I will inform you. If you are interested, follow me on Twitter please ( @SvenRuppert )

Short and simple.. as always .. But if we are using more sensors in a way like this, we will get performance problems. To solve this we are connecting different NoSQL systems soon. And we have to build the next version of JavaFX GUI-Elements... .... stay tuned.. and happy coding.