Semaphores on Java – Some Edge Cases

At work, we recently had a discussion about semaphores. With these two tests, I want to shed some light on using semaphores on the JVM with Java:

import java.util.concurrent.Semaphore;

import org.junit.Assert;
import org.junit.Test;

public class SemaphoreTests {

@Test
public void releaseWithoutPreviousAcquirePossible() {
Semaphore semaphore = new Semaphore(1, true);
semaphore.release();
Assert.assertEquals(2, semaphore.availablePermits());
}

@Test(expected = Error.class)
public void upperBoundOfSempahoreDefinedByMaxInteger() {
new Semaphore(Integer.MAX_VALUE).release();
}
}

Building Command Line Apps With Gradle

Over the course of the last years, the build automation tool gradle has established itself as the favourite kid on the block regarding build tools. It is used in many great open source projects, e.g., hibernate and grails, and is now even the default build system for Android apps.

In betsy, one major open source project of the distributed systems group, we also use gradle. I want to elaborate one particular use case we had in mind when leveraging gradle for our project.

Our focus was to have one simple command that can do the following:

  • download all dependencies (including the build tool itself)
  • compile the software
  • run the software passing it arguments from the command line

Most build tools today can download all dependencies via a repository like central maven and compile the software. Downloading itself as part of the build process, however, is not an easy task. The same holds true for starting the built software with passed parameters as part of the build process. I want to show you how we achieved it with the help of gradle.

Download all dependencies (including the build tool itself)

Gradle ships with the amazing feature of the Gradle Wrapper which consists of a shell and a batch script that can automatically download gradle and start the gradle build. Its only dependencies are that Java has to be installed. These scripts can be automatically generated with gradle. To achieve this, you need to define the wrapper task in the build.gradle script like that:

task wrapper(type: Wrapper) {
    gradleVersion = '1.7'
}

Then, by running the command gradle wrapper on the command line, we generate the gradlew and the gradlew.bat files. Thus, no local gradle installation is required anymore, as we can use these scripts instead. This allows developers interested in our project to try it out with much less hassle.

Run the software passing it arguments from the command line

To be able to run the software directly from gradle, we use the application plugin which lets us define a Main class which can be started using the run command. To achieve this, we extend the build.gradle file as follows:

apply plugin: "application"
mainClassName = "some.package.MyMainClass"

With this extension, we can run our application with gradlew run. However, it is not possible to pass in arguments from the command line, yet. For this, we use the following extension of the run task:

run {
    if(project.hasProperty('args')){
        args project.args.split('\\s+')
    }
}

Then, we can pass in arguments using the args property via gradlew run -Pargs=”–my args for the system”. This works really well, however, we always have to type in gradlew run -Pargs=”” when we want to pass in custom parameters. Thus, we introduced one shell and one batch script to circumvent that problem. We named these scripts after our project, in our case betsy and betsy.bat.

gradlew run -Pargs="$*" # contents of the betsy shell script
gradlew run -Pargs="%*" REM contents of the betsy batch script

Now, we are able to download gradle, run gradle with our build script, download all dependencies, compile our tool and start the tool with our parameters in an easy way by only typing in betsy -o bpelg Sequence.

Fixing Nokogiri Warning After Ubuntu Upgrade

I develop Ruby On Rails projects in Ubuntu-based virtual machines.
A few days ago, Canonical released Ubuntu 13.04.
After upgrading to this new release, I got the following warning when running my rails test suite:

$ rake
WARNING: Nokogiri was built against LibXML version 2.7.8, but has dynamically loaded 2.9.0
...

I invoked the nokogiri command for more information:

$ nokogiri -v
WARNING: Nokogiri was built against LibXML version 2.7.8, but has dynamically loaded 2.9.0
# Nokogiri (1.5.9)
---
    warnings:
    - Nokogiri was built against LibXML version 2.7.8, but has dynamically loaded 2.9.0
    nokogiri: 1.5.9
    ruby:
      version: 2.0.0
      platform: i686-linux
      description: ruby 2.0.0p0 (2013-02-24 revision 39474) [i686-linux]
      engine: ruby
    libxml:
      binding: extension
      compiled: 2.7.8
      loaded: 2.9.0

Ok, it seems that nokogiri was compiled with libxml 2.7.8 but the system currently only provides a new version of libxml, namely libxml 2.9.0.
This issue can be fixed by reinstalling nokogiri as the new installation will be compiled against the new LibXML version.

$ gem uninstall nokogiri # remove nokogiri
$ bundle # if you use bundler
$ gem install nokogiri # if you do not use bundler

As you can see, the warning is now gone.

$ nokogiri -v
# Nokogiri (1.5.9)
    ---
    warnings: []
    nokogiri: 1.5.9
    ruby:
      version: 2.0.0
      platform: i686-linux
      description: ruby 2.0.0p0 (2013-02-24 revision 39474) [i686-linux]
      engine: ruby
    libxml:
      binding: extension
      compiled: 2.9.0
      loaded: 2.9.0

Please leave a comment if you found this guide helpful!

Java Puzzler

What do you expect this simple little programm to print out? Would it make any difference if this is a Groovy or a Java file? Please write your answer in the comments.


package betsy;
public class CodePuzzler {
public static void main(String[] args) {
// init array
String[] array = new String[2];
array[0] = "One";
array[1] = "Two";
// iterate and print in thread
for(final String element : array){
new Thread() {
public void run() {
System.out.println(element);
}
}.start();
}
}
}

The helpful java.awt.Desktop class

I am currently working with Jörg on the betsy tool which compares the WS-BPEL 2.0 conformance of open source WS-BPEL 2.0 engines. At the end of a successful comparison run, html reports are generated and can be opened by the user via the browser. I often had to execute such a betsy run in different configurations and wanted to look at the results only. The problem is that you have to wait until the run is completed (no notifications available), open the windows explorer, navigate to the correct folder and open the html file. This process can be shortened by using bookmarks in the browser for the results. However, this does not solve the problem on being notified after the run is completed. Regardless, I have found a very simple solution: the java.util.Desktop class.

This class is shipped with the Java SE edition since Version 6 and can be used to open the default browser at a specific URI, open the default mail application (even open the compose mail window) or open/print a specific file using the registered application for this file type. I created a few examples in groovy code to show you how simple this functionality can be used as mostly only one import statement and one code statement is required. The code is written in groovy, however, it is also compatible with Java code. Just copy the import statement to the top of the Java class and past the other code line where you want to execute it.


import java.awt.Desktop;
Desktop.getDesktop().browse(new File("test.html").toURI());


import java.awt.Desktop;
Desktop.getDesktop().browse(new URI("http://www.google.de"));


import java.awt.Desktop;
Desktop.getDesktop().mail(new URI("mailto:mail@example.com"));

view raw

mail.groovy

hosted with ❤ by GitHub


import java.awt.Desktop;
Desktop.getDesktop().open(new File("test.html"));

view raw

open.groovy

hosted with ❤ by GitHub


import java.awt.Desktop
Desktop.getDesktop().print(new File("test.html"))

view raw

print.groovy

hosted with ❤ by GitHub

Moreover, you can open a file using the default editor, too. As some operation systems may not support this class, you can check with the static method Desktop.isDesktopSupported() whether it is possible to use this functionality in general. For more information using this class, please refer to the Javadoc documentation.

XML Validation with the Java API

Both, Java and XML are spread widely and used intensively. This post sheds some light onto the possibilities on validating XML files with the JAVA API.  In all code listings, the exception handling is omitted as well as the imports. The classes used are from the javax.xml, java.xml.parser and java.xml.validation packages. Moreover, this post focus on simple validation code snippets.

First, we can check if the XML file is well-formed. This can be done by parsing the XML file into a DOM document.


String path = "my/test/path/to/file.xml";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
db.parse(new File(path));

view raw

gistfile1.java

hosted with ❤ by GitHub

Next, it is possible to validate the XML file against a XML schema. However, in this case we validate the XSD file first to ensure that it is valid itself.


String path = "my/test/path/to/file.xsd";
SchemaFactory sFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
sFactory.newSchema(new File(path));

view raw

gistfile1.java

hosted with ❤ by GitHub

With the valid XSD file we can validate the XML file against this schema.

https://gist.github.com/4016661

As quite some XML files do use multiple XML Schemas, the code above will always fail. Therefore, we need to create a Schema which consists of multiple XSD files.


String path = "my/test/path/to/file.xml";
SchemaFactory sFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sFactory.newSchema(new Source[]{
new StreamSource(new File("/path/to/schema1.xsd")),
new StreamSource(new File("/path/to/schema2.xsd"))
});
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new File(path)));

view raw

gistfile1.java

hosted with ❤ by GitHub

When shipping the XSD files within the jar, it is required to reference them by resource instead.


String path = "my/test/path/to/file.xml";
SchemaFactory sFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sFactory.newSchema(new Source[]{
new StreamSource(getClass().getResourceAsStream("/path/to/schema1.xsd")),
new StreamSource(getClass().getResourceAsStream("/path/to/schema2.xsd"))
});
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new File(path)));

view raw

gistfile1.java

hosted with ❤ by GitHub

Most Useful Git Commands

This is a reminder post for myself to remember the most useful git commands.

Commands changing the local history

  • Undo last commit and stage changes: git reset --soft HEAD^
  • Permanently delete last commit : git reset --hard HEAD^
  • Use HEAD^^ for the last two commits, HEAD^^^ for the last three commits, … Use HEAD~<number> to reference the commit

Note: Do NOT use any of these commands after pushing to a repository as this would alter (the) history!

Merges and branches

  • Use git checkout -b <branch name> to create a new branch and automatically check the branch out.
  • Deleting branches using git branch -d <name> will not work when commits are unreachable after this. Use -D to override.
  • Invoke merge commands from the branch you want to merge into, e.g., from master to merge feature_branch into master. (git merge feature_branch in master branch) After merging a branch, it can be safely deleted.

Remotes and remote branches

  • The -u option in git push sets the passed remote and branch name as the default for the current repository. (git push [-u] <remote name> <local branch>)
  • Using git push <remove name> :<remote branch> deletes the remote branch. The colon marks the branch for deletion.
  • git remote show <remote name> displays lots of information about this remote.
  • git remote prune <remove name> deletes all local branches which do not have any corresponding remote branches anymore.

Tags

  • git tag lists all tags.
  • git checkout <tag name> checks out the commit referenced by the tag.
  • git tag -a <tag name> -m "<tag description>" adds a new tag.
  • git push --tags pushes the tags to the default remote.

Conflicts/Rebase

  • HEAD represents the local version in any conflict marking.
  • When using feature branches, first, run git rebase on feature branch and then git merge using fast forward in the master branch. This ensures that the possible conflict merges are made in the feature branch and not in the master branch.
  • Merge is better then rebase when the branches diverged by many (really many) commits.

Additional notes to myself

  • Use git aliases with git config alias.<abbreviation> "<full version>"!
  • git blame <file> displays which line of the given file has been authored by which user at which time in which commit.

 

Which commands do you consider useful?

Eclipse Tips and tricks

In a few days, Eclipse Juno will be released. This changes the version number from 3.7 (Indigo) to 4.2 (Juno) and introduces several interesting changes. I scanned through the Trips and tricks section of the Java development user guide and found several interesting points to increase productivity. Not every change is only available in Eclipse Juno, however, these are the ones that I did not know before and will use in future:

  • Entering NPE is automatically replaced with NullPointerException when using CTRL + SPACE.  This works for any class in Code Completion! Next, I will only write IAE, ISE, LL, and many more.
  • Pressing CTRL during Code Completion does not introduce an additional pair of brackes () that has to be removed when changing a method. Normally, when you have list.add("ASDF"); and change the add method via Code Completion to remove, you get list.remove(o)("ASDF");. This is quite annoying. If you accept the remove method instead of ENTER with CTRL + ENTER, you will get list.remove("ASDF"); directly.
  • Compare With works on Files and on Directories. So you can compare complete directories including subdirectories and their files with this method.
  • Package View: You can provide package abreviations for long package names
  • You can configure forbidden and discouraged files for a specific library. This allows for better code quality in huge teams as this prevents the usage of, e.g., internal classes circumventing the appropriate interfaces
  • JUnit: You can run a single test by right clicking on the method Run As -> run as JUnit Test
  • Cursor is at a bracket: Quick Fix for deleting the sourrounding statement
  • ALT + SHIFT + Z: Sourround with can be used to create Runnables, while, if, for, try-catch, etc. blocks around (a) selected line(s).
  • ALT + SHIFT + UP/DOWN: Structured Selection following the bracket structures
  • You can activate the checking of redundant null checks, potential null pointer access and for null pointer access at Java > Compiler > Errors/Warnings / Null Analysis
  • You can activate the validation of the JavaDoc and its corresponding method as warnings in Java > Compiler > Javadoc settings.

Do you have any Eclipse tips or tricks that you use extensively?