A step towards more ecological software development

Have you ever wondered if you, as a software developer, can do more to reduce your carbon footprint? What about the carbon footprint of all the apps you’ve deployed? 

Generally, in software development, you don’t hear a lot about this topic. But why is that? Can we not make enough impact? Is it even worth putting some effort in? 

Changing mindset

There are a lot of aspects in which software can be made more efficient, in order to reduce the computing power needed. Database queries can be made more performant, extra roundtrips can be avoided, unnecessary data doesn’t have to be stored, redundant calculations may be removed, log retention and the amount of logs could be reduced, multiple application instances running simultaneously could potentially be scaled down,… You name it. But do we actually care enough? Usually, when we think of improving these things, we usually do it to improve user experience, but rarely do we think about the ecological impact. We can actually change that. Let’s be a little more conscious in how we technically design our applications. The more of us who think about it, the more significant the overall impact can become over our shared application landscapes.

 

The trigger

To be honest with you, I didn’t always kept the ecological point of view in mind while developing applications. Sure, I thought about performance and log retention, caching were it would be advantageous, reducing round trips, introducing indexes in database queries, but I didn necessarily have the ecological footprint of the application in mind. But then I came accross an interesting post on LinkedIn, that changed this:

This immediately triggered me, and I went on to watch the Devoxx presentation on YouTube, which I truly recommend watching:

Green scheduling

Let’s talk a bit more about the software in the conference talk.

What is it? In a nutshell, it is software that allows you to schedule recurring tasks, like nightly jobs, considering the carbon intensity at the planned execution time. The aim is to run the task at the most opportune moment, being the window of time where carbon intensity would be at its lowest point.

Currently, the software consists of a propriatry API (maintained by First8) as well as an open source Java library. There are plans to support more programming languages in the future. Currently there is already support for the Spring and Quarkus frameworks.

The API is in charge of calculating the most desirable window in which to execute a given job, for a given time zone and region. It also takes an expected duration amount into consideration. Currently, the API is free of charge, but you do require an API key. You can easily set it up though, do go through the steps as documented on their Get Started page.

The library provides the annotation, its processing and the logic calling the API and the scheduled job management.

You are most likely already familiar with Spring’s Scheduled annotation, where you would define recurring jobs like so for example:
@Scheduled(cron = "0 0 2 * * ?", zone = "Europe/Brussels"). Using the library’s equivalent annotation, you would define that like so:
@GreenScheduled(fixedWindow = "02:00 08:00", carbonIntensityZone = "BE", duration = "1h" timeZone= "Europe/Brussels").
Note that instead of always running the job at 2AM, now we specify a time window. The carbonIntensityZone maps to a region as defined with ENTSO-E, from which the API consumes data. You also see that we need to pass a duration parameter, this is mandatory at the moment, and can be a rough estimation of the time the batch job would need to complete. Perhaps, this will be made a bit smarter in the future.

An example I’m personally already using in a hobby project:

@GreenScheduled(
fixedWindow = "01:00 23:00",
duration = "1h",
carbonIntensityZone = "BE",
timeZone = "Europe/Brussels",
dayOfWeek = "MON"
)
public void cleanUpArchivedLogs() {
// Log cleanup code omitted
}

As you can see, there’s different options for defining when the job has to run.
Of course, you would have to use this mindfully. If the job you want to execute is required to run at a specific time (do ask the question: why?), this approach doesn’t fit your case. But for jobs, like the above, where the execution time is not that important, go for it!

Now, imagine the impact it would make if all of us would consider something like this when setting up scheduled jobs. Every job can literally contribute in reducing the carbon footprint.

Even considering the downside of the extra API call and the computing power required for it to come up with the most suitable execution time, we will usually save more carbon, given we setup wide enough windows.

However, the supported regions, at the time of writing, only include ‘NL’. First8 (a Dutch company) does however plan to support a lot more regions, but the timeline on that is not yet very clear. If you are interested in support for a given region, do contact them to request support for it.  

Do not hesitate to contribute to the project on GitHub. The team is welcoming any change or improvement and they setup very easy-to-follow setup and contribution guidelines.

I’m playing around with the software myself. I’m evaluating wether it is ready for use in production applications (mostly region support seems to be lacking).
I’ve also contributed 2 minor changes to the library to show my support:
Implement Autocloseable on schedulers
Javadoc improvements

Green energy production often relies on multiple weather factors like, sun, wind, rain (for hydro plants),… And this little piece of software tries to make better use of that.

Moving forward

The green-scheduler I’ve just ellaborated on is of course not the only answer to improving our shared carbon footprint. It is a good step in the right direction. It makes us reflect on what we can do better. And that’s exactly it, that’s exactly what we need to start doing a little bit more.

Do you have suggestions to further improve ourselves on the topic? Or are there already other things you are actively doing to make an impact? Do let me know in a comment, I would be very interested in hearing about it, or to start a conversation!

JToolTip Behavior Outside JFrames

As I was working on a small application, I started implementing a custom JToolTip to be used throughout the app, in stead of Swing’s default JToolTip.

The custom JToolTip entirely inside the JFrame.
The custom tooltip entirely inside the JFrame.

Testing the application I was surprised by the behavior of the tooltips when they would exceed the borders of a JFrame (exceeding for a pixel was enough).

In the image below, you can notice that a background (default Swing Color) is present for the tooltip component. This background was not present for the exact same tooltip if it appeared inside the frame. So, the goal was to remove this background.

The custom JToolTip exceeding the JFrame's border.
The custom tooltip exceeding the JFrame’s border.

First thing that came in mind was, ‘I should change the background to a transparent one’. And so I did, by calling this line on the JToolTip (mind the last parameter, the alpha value of the color):

setBackground(new Color(255, 255, 255, 0));<br />

Obviously that didn’t do the trick, but it was one step closer to the solution. In fact, someone pointed out that when the component surpasses the frame’s borders, it is actually added to a JWindow prior to being displayed.

SwingUtilities provides a method that returns the Window of a specified component:

SwingUtilities.windowForComponent(...);

It sufficed to update the background color of the window, in which the tooltip was housed, with a transparent one (alpha value of 0).

As an additional measure I made sure all the parent components of the tooltip were set to be non-opaque.

The final solution could be implemented in the overridden addNotify() method:

@Override
    public void addNotify() {
        super.addNotify();
        setOpaque(false);
        Component parent = this.getParent();
        if (parent != null) {
            if (parent instanceof JComponent) {
                JComponent jparent = (JComponent) parent;
                jparent.setOpaque(false);
            }
        }
        Window window = SwingUtilities.windowForComponent(this);
        try {
            window.setBackground(new Color(255, 255, 255, 0));
        } catch (IllegalComponentStateException e) {
            //Do nothing
        }
    }

In the above code, you may notice the catch block handling potentially raised exception: IllegalComponentStateException. It was vital to add that catch statement in. A tooltip inside a frame, not exceeding the borders, is not added to a JWindow before being displayed. This means no window background should be changed, as there would be no window.

Find the question on StackOverflow for further reference.

Track the Heap With Memory View

With Jetbrains‘ recent plugin, ‘JVM Debugger Memory View’ you can go the extra mile while debugging your applications in IntelliJ IDEA and Android Studio. If you want to keep an eye on the heap, the plugin is a valid tool to use during your debug sessions!

Memory View
A search in the Memory View.

Memory View basically lists a ton of Objects that are placed on the heap at the time present. It gives you the possibility to get a better feel of the current situation (at a breakpoint) of your application, memory-wise. The tool has packed its features inside a new tab in the IDE. You can find it by default in a panel on the right side.

In the overview you can see how many Objects have been added, removed when stepping over code. If you would place a few breakpoints you can easily view how the just executed code has affected the heap.

It is also possible to track new Instances of a particular Object. To do so you will need to turn on this feature for every class name listed.

Achievement instances in Memory View.
Achievement instances in Memory View.

Opening the class instances dialog enables filtering. Apply a filter with an evaluated expression.

Filtering in Memory View.
Filtering in Memory View.

Once you have a desired overview of instances you can unfold instances, just like you already could in the variables section in the regular debug mode. This is great for inspection of the objects. Objects where exceptions were raised properly stand out as well.

Furthermore, there is a possibility to view the call stack of the instance. When an object is selected you can view this in the stack frame on the right.

Another nice feature is the ‘Referring Objects For Object X’ one. To open up this frame, right click on an object and click ‘Show Referring Objects…’. You will now get a thorough overview of every referrer of the selected Object.

If you’ve got IntelliJ IDEA 2016.1 or higher, you can simply install the plugin from the Jetbrains repository.

As a side note I’d like to warn Android Studio users. The IDE may freeze due to a bug still present at the time of writing. Also, getting large amounts of instances could cause problems due to memory restrictions in Android. It seems the development is still ongoing. If you’ve found a bug, you can always log it in their issue tracker.

Programming Unlockable Achievements

So you wrote this game, but would now like to step up? Unlockable achievements is an aspect that enhances your game and it’s fun and interesting to program.

Minecraft Achievement
A simple Minecraft Achievement

The Concept

Let’s elaborate on the actual purpose and the concept of unlockable achievements. Basically you could consider an Achievement to be a milestone. It is a goal your end user achieves, literally. It is up to you to determine these milestones.

Let’s take Minecraft‘s ‘Taking Inventory’ achievement as an example. The achievement is unlocked at the moment the inventory is opened for the first time. This example is a single Achievement, meaning it has no predecessors or successors. Possibly you’d want to create an achievement that could only be unlocked when this one was unlocked first. You may even want to have a set of achievements unlocked before achieving a parent achievement.

The previous example was obviously very simplistic. There was one task, one goal that lead to the unlocking of the achievement. Different achievements might consist of multiple milestones to reach before unlock. Or maybe you’d want specific actions to take place in order to achieve the achievement.

Achievements Everywhere

Gaming companies, publishers and console builders all make use of achievements. Think about the trophies you can earn on PlayStation and XBox consoles. Think about achievements that you can collect on the Steam platform. And don’t forget the achievements on mobile devices in Google Play Games (Android) and Game Center (iOS). There are so many possibilities, so many things you can do with your in-game achievements. You can go beyond an implementation in your game itself.

Implementation

Let’s put things in practice by covering a possible implementation approach in Java.

You want to get things started by defining an interface:

public interface Achievable {
    void achieve();
}

Now we’re ready to define an Achievement class. You can make it Observable as we did in the following example. That way registered observers can get notified at the moment the Achievement is unlocked.

public class Achievement extends Observable implements Achievable {

    private String name, description;
    private List<AchievementProperty> propertyList;
    private boolean unlocked;

    /**
     * Class constructor specifying name, description and properties to be activated.
     *
     * @param name        the untranslated name of the achievement
     * @param description the untranslated description of the achievement
     * @param properties  the properties related to the achievement
     */
    public Achievement(String name, String description, List<AchievementProperty> properties) {
        this.name = name;
        this.description = description;
        this.propertyList = properties;
        this.unlocked = false;
    }

    /**
     * Unlocks this achievement and notifies its' observers.
     */
    @Override
    public void achieve() {
        if (!unlocked) {
            boolean allActive = true;
            for (AchievementProperty property : propertyList) {
                if (!property.isActive()) {
                    allActive = false;
                    break;
                }
            }
            if (allActive) {
                this.unlocked = true;
                setChanged();
                notifyObservers();
            }
    }
//Getters, setters and toString omitted...
}

As you can see in the above code, the achievement contains a list of AchievementProperty. These are properties that need to be active when the achievement is unlocked.

Here’s how the AchievementProperty class may look like:

public class AchievementProperty {

    private String name;
    private int value;
    private String activation;
    private int activationValue;
    private int initialValue;
    private String tag;

    /**
     * Class constructor specifying name, activation, activation value and initial value.
     *
     * @param name            the untranslated name of the property
     * @param activation      the activation method of the property
     * @param activationValue the activation value of the property
     * @param initialValue    the initial value of the property
     */
    public AchievementProperty(String name, String activation, int activationValue, int initialValue) {
        this.name = name;
        this.activation = activation;
        this.activationValue = activationValue;
        this.initialValue = initialValue;
    }

    /**
     * Class constructor specifying name, activation, activation value, initial value and tag.
     *
     * @param name            the untranslated name of the property
     * @param activation      the activation method of the property
     * @param activationValue the activation value of the property
     * @param initialValue    the initial value of the property
     * @param tag             the tag of the property
     */
    public AchievementProperty(String name, String activation, int activationValue, int initialValue, String tag) {
        this.name = name;
        this.activation = activation;
        this.activationValue = activationValue;
        this.initialValue = initialValue;
        this.tag = tag;
    }

    /**
     * Returns true when this property is active, false if otherwise.
     *
     * @return true when this property is active, false if otherwise
     */
    public boolean isActive() {
        boolean flag = false;

        switch (activation) {
            case Achiever.ACTIVE_IF_GREATER_THAN:
                flag = value > activationValue;
                break;
            case Achiever.ACTIVE_IF_LESS_THAN:
                flag = value < activationValue;
                break;
            case Achiever.ACTIVE_IF_EQUALS_TO:
                flag = value == activationValue;
        }

        return flag;
    }

    /**
     * Resets this property's current value.
     */
    public void reset() {
        this.value = initialValue;
    }

Now it’s up to you to get all that linked up by creating the ‘Achiever’ class. I’ll leave that as an exercise to the reader. Here’s a bit more context to get you going:

  1. Make use of a HashMap to keep AchievementProperty instances;
  2. Make use of a HashMap to keep Achievement instances;
  3. Provide a ‘defineProperty’ method that creates and returns a new AchievementProperty based on specified parameters. If the property is not yet listed in the HashMap, put it in there;
  4. Provide a ‘defineAchievement’ method that creates and returns a new Achievement based on specified parameters (do not forget its’ related Achievementproperty/AchievementProperties!). If the achievement is not yet listed in the HashMap, put in in there;
  5. Add a method that will achieve all eligible achievements (don’t forget checks on the related AchievementProperty/AchievementProperties;
  6. Add methods to add/set a value to properties, or even to reset property values.

At this point you can create your new achievements and their respective related property/properties.

On the moment a property needs to get an update, you call the ‘addValue’ method from step 6 and you call the ‘checkAchievements’ method from step 5. This way your achievements can get unlocked at the proper time.

About the Bromine Project

Since my experience with Selenium is growing I become to understand it better every day. At first I was amazed about its possibilities. You can do a lot with Selenium WebDriver, but soon enough I came to realize it’s missing a few aspects. That’s how Bromine evolved from idea to project.

Filling in the Gaps

The Bromine project’s aim is to fill in the gaps in the default Selenium WebDriver Livery for Java. In stead of using Selenium, use Bromine that will on its turn use Selenium for you, while still leaving you enough means of customizing the WebDriver functionality.

Screenshots

A good example of a feature I was really missing in Selenium was a descent way of taking screenshots. The method getScreenshotAs(OutputType.FILE); just simply didn’t quit fulfill my needs (and those were from an automatic testing’s perspective). What I specifically wanted to be able to take a screenshot of the current browser instance any time I’d desire, but more importantly, every time a unit test fails.

An example screenshot taken by a Bromine command.
An example screenshot taken by a Bromine command.

In Bromine, a simple JUnit rule can take care of just that. Add it to your test class as follows:

@Rule
public ScreenShotOnFailure failure = new ScreenShotOnFailure("./screenshots/");

Statistics

When I use Selenium in a test framework, at some point, I might become interested in several statistics. Of course I do not intend to re-invent the wheel. I respect the current web analytics standard of today, Google Analytics, and I believe it to cover most needs one can have regarding statistics and analysis of a website.

What Google Analytics doesn’t provide you is statistics of events on your web page right in your test framework.

Why would that even be useful? Well, if you’re creating an automated test framework you are trying to ensure a qualitative final product for your users to interact with. Wouldn’t you want to know how many clicks one has to perform before reaching a particular page? Aren’t you interested in how many times form fields have to be filled in before a desired action occurs? Those are examples of what Bromine would like to cover.

As of version 0.2-alpha, a basic implementation of this is in place, ready for you to extend at will. I made sure I provided at least a very minimum, being tracking of left mouse button clicks, double clicks and the amount of times keys are entered.

Since I can image one might find the need to create their own tracking means, I ensured the system works with plugins (StatsPlugin) that can be registered and enabled any time.

Bringing SUT Structure

Selenium merely provides the ability to browse through websites, while what many might want to do would be structuring their System Under Test (SUT) inside their framework. It is a good practice to do so, since you might want to reuse pages and features that are used across the site multiple times.

Bromine provides a base to register pages (Page) and their respective sections (section) to a globally accessible collection (Pages). The easiest way to implement your application structure would be to assign a specific package in your project to contain classes extending the Page class. If you make use of the default no-parameter constructor, you won’t even have to create new instances of your pages. Just make sure to call registerAllPagesFromPackage(String pack) from the Pages class to register all your predefined pages to the collection.

Work in Progress

Bromine is currently in a very early stage. Additional extensions to Selenium are more than likely to appear, as well as probable breaking changes in the future. Needless to say that Bromine has to evolve as does Selenium.

Personally, I attempt to use the framework in multiple different projects. That way I can evaluate how useful it is and how well it works. Most useful features at the moment (for me personnally) are the screenshots and the structuring of pages from the SUT.

I’m happy to share the source on GitHub. I made it to be open source since I will always be open to feedback and improvement suggestions.