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();
}
}

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

The Java Initializers

In Java, the concepts of classes and instances are the core concepts. A class as well as each instance has variables and methods. To differentiate, the variables and methods corresponding to the class have to be marked static while variables and methods default to the instance (if not marked static). In the following, I focus only on the variables.

The following example shows the declaration for class and instance variables:

public class Variables {
  static String classVariable; // initialized with default value null

  String instanceVariable; // initialized with default value null
}

Class Variables

Class variables are interpreted in the order they appear in the file. I can directly assign values to a class variable (direct initialization) or call a static method which initialises the variable through its return value. This, however, can lead to problems as shown in the next listing:

public class Variables {
  static String directlyInitialized = "class variable";
  static String directlyInitializedWithMethod = init();
  static String anotherDirectlyInitialized = "test";

  private static String init() {
    return anotherDirectlyInitialized;
  }

  public static void main(String[] args) {
    System.out.println(directlyInitializedWithMethod); // prints null
  }
}

This will print out null as the variable anotherDirectlyInitialized is initialized after the directlyInitializedWithMethod is initialized. The compiler does not detect it, it is the responsibility of the programmer to avoid such situations. We could solve this issue by reordering the statements, however, this is an area where we can do errors easily.

There is another alternative, namely, class initializers. These initializers are executed after all static variables have been initialized.

public class Variables {
  static String directlyInitialized = "class variable";
  static String directlyInitializedWithMethod;
  static String anotherDirectlyInitialized = "test";

  static {
    directlyInitializedWithMethod = anotherDirectlyInitialized;
  }

  public static void main(String[] args) {
    System.out.println(directlyInitializedWithMethod); // prints test
  }
}

This static block can contain any complex setup logic. It is executed after all static variables are initialised but before any method call to the class is issued. Good use cases are the computation of constants or preinitialization of other instances which require more than a simple constructor or method call.

Instance Variables

The approach of initializing static variables is also applied to instance variables. I can directly assign values to an instance variable (direct initialization) or call a method which initialises the variable through its return value. This, however, can lead to the same initialization problems.

public class Variables {
  String directlyInitialized = "class variable";
  String directlyInitializedWithMethod = init();
  String anotherDirectlyInitialized = "test";

  private String init() {
    return anotherDirectlyInitialized;
  }

  public static void main(String[] args) {
    InstanceVariables object = new InstanceVariables();
    System.out.println(object.directlyInitializedWithMethod); // prints null
  }
}

However, there is also an initializer construct for instance variables. This construct is called before any constructor is called and allows to initialize instance variables regardless of their ordering.

public class Variables {
  String directlyInitialized = "class variable";
  String directlyInitializedWithMethod;
  String anotherDirectlyInitialized = "test";

  {
    directlyInitializedWithMethod = anotherDirectlyInitialized;
  }

  public static void main(String[] args) {
    InstanceVariables object = new InstanceVariables();
    System.out.println(object.directlyInitializedWithMethod); // prints test
  }
}

Another real use case of these instance initializers is to add values to a HashMap on creation as seen in the next code snippet:

// regular approach
Map<String, String> myMap = new HashMap<>();
myMap.put("DE", "German");
myMap.put("EN", "English");
		
		
Map<String, String> otherMap = new HashMap<String, String>() {
	// anonymous subclass of HashMap

	{
		// instance initializer setting specific values
		this.put("DE", "German");
		this.put("EN", "English");
	}

};

The advantage is, that the latter can be used to initialize a field in a class directly with specific values.

Line Separators

Line separators are a funny problem in itself. Each operating system uses different kind of escape sequences to determine a new line.

  • Windows: \r\n
  • Unix/Linux/Mac OS X: \n
  • pre-OSX Mac: \r

Orignially, the write head of typewriters could only do few tasks. I listed the most important ones below:

  • Write symbol and move the cursor one column to the right.
  • \r | carriage return | CR | Move cursor to the first column of the line.
  • \n | line feed         | LF | Move cursor to the next row/line at the same column.
  • \b | backspace     | BS | Move cursor one column back.
  • \t | horizontal tab  | HT | Move cursor to the next tab-stop.
In order to get the cursor to the beginning of the new line, you needed to use a carriage return followed by a line feed. This behaviour resulted in the \r\n escape sequence of windows. Others simplified it by selecting either \n or \r.

In Java, which is plattform independent, you get the plattform dependent escape sequence by obtaining the system property named line.separator.

String lineSeparator = System.getProperty("line.separator");

Other plattform specific system properties as the path.separator (backslash or slash) can be found at this guide.

Objects – A Not Very Well Known Utility Class In Java

The Java API has some quite useful classes which are not well known. One of them is the Objects class with several static helper methods. Most of them help dealing with null values (which is quite a pain if you have to do it by yourself). The Objects class is available since Java 7.

I really like the requireNonNull methods as you often have to write code that checks for null values. As it can be seen in the code snippet below, the static method requireNonNull is available in two versions. I prefer the one with the additional message as a NullPointerException is not very expressive in itself.

public void solve(String problem) {
    // throws NullPointerException if problem is null
    Objects.requireNonNull(problem);

    // throws NullPointerException with passed text if problem is null
    Objects.requireNonNull(problem,"problem is null");

    // solve problem
}

Null can also be problematic if you want to create a String as it is automatically transformed to an empty String. This is not always desired as null and an empty String cannot be differentiated anymore. The Objects class provides the toString method, which is also available in two versions as it can be seen in the code listing below.

public void printProblem(String problem) {
     // converts null to "null", otherwise calls toString()
     String output = Objects.toString(problem);

     // converts null to "no problem given", otherwise calls toString()
     String anotherOutput = Objects.toString(problem,"no problem given");

     // print problem
}

There are also two methods regarding the generation of hashcodes. Using the Objects.hashcode(Object o) method, the hashcode method of the Object o is called. In case of a null reference, 0 is returned. For computing the hash value for several objects, you can resort to Objects.hash(Object… values) which delegates the hash generation to the Arrays.hashCode method. These methods are not that useful to me as almost always I use an IDE to generate the hashCode method of an Object using its fields for me.

Additionally, the methods named equals and deepEquals help to compare objects for equality taking the null value explicitly into account while compare itself uses a Comparator. I can not see any immediate use for me regarding these methods either, but perhaps an occasion for them may arise.

I recommend that you read through the source code of the Objects.class. It is quite simple and easy to understand. You could write a class with the same functionality by yourself, however, you get this behaviour fully tested and already implemented for free! So use it!

Initializing Arrays in Java

Arrays are widely used in many (almost any) programming languages. In Java, you have to specific the length of an Array at the creation of an Array.

Here is a short example how to initalize an Array containting the numbers 1, 2 and 3:

int[] numbers = new int[3];
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;

In order to abbreviate this, there is a short form which can do this work in one line. This works as Java can determine the length of the array by looking at the number of elements within the curly brackets. At compile time, the short form is translated to the form above within the byte code.

int[] numbers2 = {1,2,3};

Now, there are some quirks to be aware of regarding the short form. You can use this only while defining the array variable. The following will result in a compile error:

int[] numbers2 = {1,2,3};
numbers2 = {4,5,6}; // compile error!

Why does this happen? The error message says: “Array constants can only be used in initializers”. But I am not quite sure, what the meaning behind is. I consider it a quirk of the Java language without any further research regarding this construct. 😉

However, today, I found a trick to circumvent this issue. You can find the solution in the Oracle Java Magazine, Section Fix This.

int[] numbers3 = {1,2,3};
numbers3 = new int[]{4,5,6};

I am not quite sure, why this works. Do you?

Locating jars using a class or Package

For my build process, I need to reference files stored inside of jars. This is normally done so:

jar:file:/path_to_jar.jar!/package1/package2/file.extension

The computation of this path can be done automatically in java.

public String getPath(Class clazz) {
	CodeSource containingJarFile = clazz.getProtectionDomain()
		.getCodeSource();

	String libLocation = "";
	if (containingJarFile != null) {

		libLocation = containingJarFile.getLocation().toString();

		if (libLocation.endsWith(".jar")) {
			libLocation = "jar:" + libLocation + "!/";
		}
	}

	return libLocation;
}

Just attach the path to the return of this method, and you can reference files inside jars.

The implementation is from the AcceleoCompiler Class from the Accleo Eclipse Project.