Montag, 28. Oktober 2013

Java class loading anomaly

I learned about a (for me) initially rather unintuitive anomaly in the Java language today. Of course, this is not technically an anomaly but something well-defined in the JVMS. However, I was not aware of the class loading behavior described in this blog entry, despite having read the specification, which I decided this was worth sharing.

I stumbled onto this when I was curious about reasons why it is not allowed to use static fields referencing an enum for annotation values while it is allowed for any other value. It turns out that the Java compiler is not allowed to substitute enum fields at compile time while it can substitute such values for all other possible annotation members. But what does this mean in practice?

Let's look at this example class:

@MyAnnotation(HelloWorldHelper.VAL1)
class MyClass {
  public static void main(String[] args) {
    System.out.println(MyClass.class.getAnnotation(MyAnnotation.class).value());
    System.out.println(HelloWorldHelper.VAL2);
    System.out.println(HelloWorldHelper.class.getName());
    System.out.println(HelloWorldHelper.VAL3);
  }
}

with the following helper classes:

enum MyEnum {
  HELLO_WORLD_ENUM
}

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
  String value();
}

class HelloWorldHelper {
  public static final String VAL1 = "Hello world!";
  public static final String VAL2 = "Hello world again!";
  public static final MyEnum VAL3 = MyEnum.HELLO_WORLD_ENUM;
  static { System.out.println("Initialized class: HelloWorldHelper"); }
}

the output (for me first unexpectedly) returns as:

Hello world!
Hello world again!
HelloWorldHelper
Initialized class: HelloWorldHelper
HELLO_WORLD_ENUM

But why is this so? The Java compiler substitutes constant references to String values (this is also true for primitives) with a direct entry of the referenced String's value in the referencing class's constant pool. This also means that you could not load another class HelloWorldHelper at runtime and expect those values to be adjusted in MyClass. This adjustment would only happen for the MyEnum value which is as a matter of fact resolved at runtime (and therefore causes the HelloWorldHelper class to be loaded and initialized which can be observed by the execution of the static block). The motive for not allowing this anomaly for enums but for Strings might well be (of course, I can only guess) that the Java language specification treats strings differently than other object types such as the primitive wrapper types. Usually, copying an object reference would break Java's contract of object identity. Strings on the other side will still be identical even after they were technically duplicated due to Java's concept of pooling load-time strings. As mentioned before, primitives can also be copied into the referencing class since primitive types are implemented as value types in Java which do not know a concept of identity. However, the HelloWorldHelper class would be loaded when for example referencing a non-primitive Integer boxing type.

Interestingly enough does HelloWorldHelper.class.getName() does not require the HelloWorldHelper class to be initialized. When looking at the generated byte code, one can observe that the HelloWorldHelper class is actually referenced this time and will as a matter of fact be loaded into the JVM. However, JVMS §5.5 does not specify such a reflective access as a reason to initialize the class which is why the above output appears the way observed.

Donnerstag, 18. Juli 2013

Extending Guava caches to overflow to disk

Caching allows you to significantly speed up applications with only little effort. Two great cache implementations for the Java platform are the Guava caches and Ehcache. While Ehcache is much richer in features (such as its Searchable API, the possibility of persisting caches to disk or overflowing to big memory), it also comes with quite an overhead compared to Guava. In a recent project, I found a need to overflow a comprehensive cache to disk but at the same time, I regularly needed to invalidate particular values of this cache. Because Ehcache's Searchable API is only accessible to in-memory caches, this put me in quite a dilemma. However, it was quite easy to extend a Guava cache to allow overflowing  to disk in a structured manner. This allowed me both overflowing to disk and the required invalidation feature. In this article, I want to show how this can be achieved.

I will implement this file persisting cache FilePersistingCache in form of a wrapper to an actual Guava Cache instance. This is of course not the most elegant solution (more elegant would to implement an actual Guava Cache with this behavior), but I will do for most cases.

To begin with, I will define a protected method that creates the backing cache I mentioned before:

private LoadingCache<K, V> makeCache() {
  return customCacheBuild()
    .removalListener(new PersistingRemovalListener())
    .build(new PersistedStateCacheLoader());
}

protected CacheBuilder<K, V> customCacheBuild(CacheBuilder<K, V> cacheBuilder) {
  return CacheBuilder.newBuilder();
}

The first method will be used internally to build the necessary cache. The second method is supposed to be overridden in order to implement any custom requirement to the cache as for example an expiration strategy. This could for example be a maximum value of entries or soft references. This cache will be used just as any other Guava cache. The key to the cache's functionality are the RemovalListener and the CacheLoader that are used for this cache. We will define these two implementation as inner classes of the FilePersistingCache:

private class PersistingRemovalListener implements RemovalListener<K, V> {
  @Override
  public void onRemoval(RemovalNotification<K, V> notification) {
    if (notification.getCause() != RemovalCause.COLLECTED) {
      try {
        persistValue(notification.getKey(), notification.getValue());
      } catch (IOException e) {
        LOGGER.error(String.format("Could not persist key-value: %s, %s", 
          notification.getKey(), notification.getValue()), e);
      }
    }
  }
}

public class PersistedStateCacheLoader extends CacheLoader<K, V> {
  @Override
  public V load(K key) {
    V value = null;
    try {
      value = findValueOnDisk(key);
    } catch (Exception e) {
      LOGGER.error(String.format("Error on finding disk value to key: %s", 
        key), e);
    }
    if (value != null) {
      return value;
    } else {
      return makeValue(key);
    }
  }
}

As obvious from the code, these inner classes call methods of FilePersistingCache we did not yet define. This allows us to define custom serialization behavior by overriding this class. The removal listener will check the reasons for a cache entry being evicted. If the RemovalCause is COLLECTED, the cache entry was not manually removed by the user but it was removed as a consequence of the cache's eviction strategy. We will therefore only try to persist a cache entry if the user did not wish the entries removal. The CacheLoader will first attempt to restore an existent value from disk and create a new value only if such a value could not be restored.

The missing methods are defined as follows:

private V findValueOnDisk(K key) throws IOException {
  if (!isPersist(key)) return null;
  File persistenceFile = makePathToFile(persistenceDirectory, directoryFor(key));
  (!persistenceFile.exists()) return null;
  FileInputStream fileInputStream = new FileInputStream(persistenceFile);
  try {
    FileLock fileLock = fileInputStream.getChannel().lock();
    try {
      return readPersisted(key, fileInputStream);
    } finally {
      fileLock.release();
    }
  } finally {
    fileInputStream.close();
  }
}

private void persistValue(K key, V value) throws IOException {
  if (!isPersist(key)) return;
  File persistenceFile = makePathToFile(persistenceDirectory, directoryFor(key));
  persistenceFile.createNewFile();
  FileOutputStream fileOutputStream = new FileOutputStream(persistenceFile);
  try {
    FileLock fileLock = fileOutputStream.getChannel().lock();
    try {
      persist(key, value, fileOutputStream);
    } finally {
      fileLock.release();
    }
  } finally {
    fileOutputStream.close();
  }
}


private File makePathToFile(@Nonnull File rootDir, List<String> pathSegments) {
  File persistenceFile = rootDir;
  for (String pathSegment : pathSegments) {
    persistenceFile = new File(persistenceFile, pathSegment);
  }
  if (rootDir.equals(persistenceFile) || persistenceFile.isDirectory()) {
    throw new IllegalArgumentException();
  }
  return persistenceFile;
}

protected abstract List<String> directoryFor(K key);

protected abstract void persist(K key, V value, OutputStream outputStream) 
  throws IOException;

protected abstract V readPersisted(K key, InputStream inputStream) 
  throws IOException;

protected abstract boolean isPersist(K key);

The implemented methods take care of serializing and deserializing values while synchronizing file access and guaranteeing that streams are closed appropriately. The last four methods remain abstract and are up to the cache's user to implement. The directoryFor(K) method should identify a unique file name for each key. In the easiest case, the toString method of the key's K class is implemented in such a way. Additionally, I made the persist, readPersisted and isPersist methods abstract in order to allow for a custom serialization strategy such as using Kryo. In the easiest scenario, you would use the built in Java functionality which uses ObjectInputStream and ObjectOutputStream. For isPersist, you would return true, assuming that you would only use this implementation if you need serialization. I added this feature to support mixed caches where you can only serialize values to some keys. Be sure not to close the streams within the persist and readPersisted methods since the file system locks rely on the streams to be open. The above implementation will take care of closing the stream for you.

Finally, I added some service methods to access the cache. Implementing Guava's Cache interface would of course be a more elegant solution:

public V get(K key) {
  return underlyingCache.getUnchecked(key);
}

public void put(K key, V value) {
  underlyingCache.put(key, value);
}

public void remove(K key) {
  underlyingCache.invalidate(key);
}

protected Cache<K, V> getUnderlyingCache() {
  return underlyingCache;
}

Of course, this solution can be further improved. If you use the cache in a concurrent scenario, be further aware that the RemovalListener is, other than most Guava cache method's executed asynchronously. As obvious from the code, I added file locks to avoid read/write conflicts on the file system. This asynchronicity does however imply that there is a small chance that a value entry gets recreated even though there is still a value in memory. If you need to avoid this, be sure to call the underlying cache's cleanUp method within the wrapper's get method. Finally, remember to clean up the file system when you expire your cache. Optimally, you will use a temporary folder of your system for storing your cache entries in order to avoid this problem at all. In the example code, the directory is represented by an instance field named persistenceDirectory which could for example be initialized in the constructor.

Update: I wrote a clean implementation of what I described above which you can find on my Git Hub page and on Maven Central. Feel free to use it, if you need to store your cache objects on disk.

Freitag, 5. Juli 2013

Object-based micro-locking for concurrent applications by using Guava

One of the presumably most annoying problems with writing concurrent Java applications is the handling of resources that are shared among threads as for example a web applications' session and application data. As a result, many developers choose to not synchronize such resources at all, if an application's concurrency level is low. It is for example unlikely that a session resource is accessed concurrently: if request cycles complete within a short time span, it is unlikely that a user will ever send a concurrent request using a second browser tab while the first request cycle is still in progress. With the ascent of Ajax-driven web applications, this trusting approach does however become increasingly hazardous. In an Ajax-application, a user could for example request a longer-lasting task to complete while starting a similar task in another browser window. If these tasks access or write session data, you need to synchronize such access. Otherwise you will face subtle bugs or even security issues as it it for example pointed out in this blog entry.

An easy way of introducing a lock is by Java's synchronized keyword. This example does for example only block a request cycle's thread if a new instance needs to be written to the session.
HttpSession session = request.getSession(true);
if (session.getAttribute("shoppingCart") == null) {
  synchronize(session) { 
    if(session.getAttribute("shoppingCart")= null) {
      cart = new ShoppingCart();
      session.setAttribute("shoppingCart");
    }
  }
}
ShoppingCart cart = (ShoppingCart)session.getAttribute("shoppingCart");
doSomethingWith(cart);

This code will add a new instance of ShoppingCart to the session. Whenever no shopping cart is found, the code will acquire a monitor for the current user's session and add a new ShoppingCart to the HttpSession of the current user. This solution has however several downsides:
  1. Whenever any value is added to the session by the same method as described above, any thread that is accessing the current session will block. This will also happen, when two threads try to access different session values. This blocks the application more restrictive than it would be necessary.
  2. A servlet API implementation might choose to implement HttpSession not to be a singleton instance. If this is the case, the whole synchronization would fail. (This is however not a common implementation of the servlet API.)
It would be much better to find a different object that the HttpSession instance to synchronize. Creating such objects and sharing them between different threads would however introduce the same problems. A nice way of avoiding that is by using Guava caches which are both intrinsically concurrent and allow the use of weak keys:

LoadingCache<String, Object> monitorCache = CacheBuilder.newBuilder()
       .weakValues()
       .build(
           new CacheLoader<String, Object>{
             public Object load(String key) {
               return new Object();
             }
           });

Now we can rewrite the locking code like this:

HttpSession session = request.getSession(true);
Object monitor = ((LoadingCache<String,Object>)session.getAttribute("cache"))
  .get("shoppingCart");
if (session.getAttribute("shoppingCart") == null) {
  synchronize(monitor) { 
    if(session.getAttribute("shoppingCart")= null) {
      cart = new ShoppingCart();
      session.setAttribute("shoppingCart");
    }
  }
}
ShoppingCart cart = (ShoppingCart)session.getAttribute("shoppingCart");
doSomethingWith(cart);

The Guava cache is self-populating and will simply return a monitor Object instance which can be used as a lock on the shared session resource which is universially identified by shoppingCart. The Guava cache is backed by a ConcurrentHashMap which avoids synchronization by only synchronizing on the map key's hash value bucket. As a result, the application was made thread safe without globally blocking it. Also, you do not need to worry about running out of memory sice the monitors (and the related cache entries) will be garbage collected if they are not longer in use. If you do not use other caches, you can even consider soft references to optimize run time.

This mechanism can of course be refined. Instead of returning an Object instance, one could for example also return a ReadWriteLock. Also, it is important to instanciate the LoadingCache on the session's start up. This can be achieved by for example a HttpSessionListener.

Samstag, 15. Juni 2013

Subtyping in Java generics

Generic types introduce a new spectrum of type safety to Java program. At the same type, generic types can be quite expressive, especially when using wildcards. In this article, I want to explain how subtyping works with Java generics.

General thoughts on generic type subtyping


Different generic types of the same class or interface do not define a subtype hierarchy linear to the subtype hierarchy of possible generic argument types. This means for example that List<Number> is not a supertype of List<Integer>. The following prominent example gives a good intuition why this kind of subtyping is prohibited:

// assuming that such subtyping was possible
ArrayList<Number> list = new ArrayList<Integer>();
// the next line would cause a ClassCastException
// because Double is no subtype of Integer
list.add(new Double(.1d))

Before discussing this in further detail, let us first think a little bit about types in general: types introduce redundancy to your program. When you define a variable to be of type Number, you make sure that this variable only references objects that know how to handle any method defined by Number such as Number.doubleValue. By doing so, you make sure that you can safely call doubleValue on any object that is currently represented by your variable and you do not longer need to keep track of the actual type of the variable's referenced object. (As long as the reference is not null. The null reference is actually one of the few exceptions of Java's strict type safety. Of course, the null "object" does not know how to handle any method call.) If you however tried to assign an object of type String to this Number-typed variable, the Java compiler would recognize that this object does in fact not understand the methods required by Number and would throw an error because it could otherwise not guarantee that a possible future call to for example doubleValue would be understood. However, if we lacked types in Java, the program would not change its functionality just by that. As long if we never made an errornous method call, a Java program without types would be equivalent. Viewed in this light, types are merely to prevent us developers of doing something stupid while taking away a little bit of our freedom. Additionally, types are a nice way of implicit documentary of your program. (Other programming languages such as Smalltalk do not know types and besides being anoying most of the time this can also have its benefits.)

With this, let's return to generics. By defining generic types you allow users of your generic class or interface to add some type safety to their code because they can restrain themselfs to only using your class or interface in a certain way. When you for example define a List to only contain Numbers by defining List<Number>, you advice the Java compiler to throw an error whenever you for example try to add a String-typed object into this list. Before Java generics, you simply had to trust that the list only contained Numbers. This could be especially painful, when you handed references of your collections to methods defined in third-party code or received collections from this code. With generics, you could assure that all elements in your List were of a certain supertype even at compile time. 

At the same time, by using generics you loose some type-safety within your generic class or interface. When you for example implement a generic List

class MyList<T> extends ArrayList<T> { }

you do not know the type of T within MyList and you have to expect that the type could be as unsophisticated as Object. This is why you can restrain your generic type to require some minimum type:

class MyList<T extends Number> extends ArrayList<T> {
  double sum() { 
  double sum = .0d;
    for(Number val : this) {
      sum += val.doubleValue();
    }
  return sum;
  }
}

This allows you to asume that any object in MyList is a subtype of Number. That way, you gain some type safety within your generic class.

Wildcards


Wildcards are the Java equivalent to saying whatever type. Consequently, you are not allowed to use wildcards when instanciating a type, i.e. defining what concrete type some instance of a generic class should represent. A type instanciation occurs for example when instanciating an object as new ArrayList<Number> where you among other things implicitly call the type constructor of ArrayList which is contained in its class definition

class ArrayList<T> implements List<T> { ... }

with ArrayList<T> being a trivial type constructor with one single argument. Thus, neither within ArrayList's type constructor definition (ArrayList<T>)  nor in the call of this constructor (new ArrayList<Number>) you are allowed to use a wildcard. When you are however only referring to a type without instanciating a new object, you can use wildcards, such as in local variables. Therefore, the following definition is allowed:

ArrayList<?> list;

By defining this variable, you are creating a place holder for an ArrayList of any generic type. With this little restriction of the generic type however, you cannot add objects to the list via its reference by this variable. This is because you made such a general assumption of the generic type represented by the variable list that it would not be safe to add an object of for example type String, because the list beyond list could require objects of any other subtype of some type. In general this required type is unknown and there exists no object which is a subtype of any type and could be added safely. (The exception is the null reference which abrogates type checking. However, you should never add null to collections.) At the same time, all objects you get out of the list will be of type Object because this is the only safe asumption about a common supertype of al possible lists represented by this variable. For this reason, you can form more elaborate wildcards using the extends and super keywords:

ArrayList<? extends Number> list1 = new ArrayList<Integer>();
ArrayList<? super Number> list2 = new ArrayList<Object>();

When a wildcard defines a minimum subtype via extends such as list1, the compiler will enforce that any objects you get out of this list will be some subtype of Number such as for example Integer. Similarly, when defining a maximum subtype via super as in list2, you can expect any list to represent a supertype of Number such as Object. Thus you can safely add instances of any subtype of Number to this list.

Finally, you should note that you can actually use wildcards within type constructors if the used type arguments are itself generic. The following use of a type constructor is for example perfectly legal:

ArrayList<?> list = new ArrayList<List<?>>();

In this example, the requirement that the ArrayList must not be constructed by using a wildcard type is fullfilled because the wildcard is applied on the type argument and not on the constructed type itself.

As for subtyping of generic classes, we can summarize that some generic type is a subtype of another type if the raw type is a subtype and if the generic types are all subtypes to each other. Because of this we can define

List<? extends Number> list = new ArrayList<Integer>();

because the raw type ArrayList is a subtype of List and because the generic type Integer is a subtype of ? extends Number.

Finally, be aware that a wildcard List<?> is a shortcut for List<? extends Object> since this is a commonly used type definition. If the generic type constructor does however enforce another lower type boundary as for example in

class GenericClass<T extends Number> { }

a variable GenericClass<?> would instead be a shortcut to GenericClass<? extends Number>.

The get-and-put principle


This observation leads us to the get-and-put principle. This principle is best explained by another famous example:

class CopyClass {
  <T> void copy(List<T> from, List<T> to) {
    for(T item : from) to.add(item);
  }
}

This method definition is not very flexible. If you had some list List<Integer> you could not copy its contents to some List<Number>  or even List<Object>. Therefore, the get-and-put principle states that you should always use lower-bounded wildcards (? extends) when you only read objects from a generic instance (via a return argument) and always use upper-bounded wildcards (? super) when you only provide arguments to a generic instance's methods. Therefore, a better implementation of MyAddRemoveList would look like this:

class CopyClass {
  <T> void copy(List<? extends T> from, List<? super T> to) {
    for(T item : from) to.add(item);
  }
}

Since you are only reading from one list and writing to the other list, Unfortunately, this is something that is easily forgoten and you can even find classes in the Java core API that do not apply the get-and-put principle. (Note that the above method also describes a generic type constructor.)

Note that the types List<? extends T> and List<? super T> are both less specific than the requirement of List<T>. Also note that this kind of subtyping is already implicit for non-generic types. If you define a method that asks for a method parameter of type Number, you can automatically receive instances of any subtype as for example Integer. Nevertheless, it is always type safe to read this Integer object you received even when expecting the supertype Number. And since it is impossible to write back to this reference, i.e. you cannot overwrite the Integer object with for example an instance of Double, the Java language does not require you to waive your writing intention by declaring a method signature like void someMethod(<? extends Number> number). Similarly, when you promised to return an Integer from a method but the caller only requires a Number-typed object as a result, you can still return (write) any subtype from your method. Similarly, because you cannot read in a value from a hypothetical return variable, you do not have to waive these hypothetical reading rights by a wildcard when declaring a return type in your method signature.

Freitag, 7. Juni 2013

Advanced Java generics: retreiving generic type arguments

After their introduction in the JDK5, Java generics quickly became an integral element of many Java programs. However, as easy Java generics seem at first glance, as quickly a programer can get lost with this feature.

Most Java programers are aware of the Java compiler's type erasure. Generally speaking, type erasure means that all generic type information about a Java class is lost during the compilation of its source code. This is a tribute to Java's backwards compatibility: all generic variations of a Java class share a single representation within a running Java application. If an instance of ArrayList<String> would have to remember that its generic type was of type String, it would have to store this information somewhere within its functional description in order to indicate that for example List.get actually returns a String type. (By functional description I refer to properties which are shared among all instances of a class. This includes for example method or field definitions. In contrast to its functional description, an instance's state which is individual to each instance is stored in its object representation.) The functional description of the ArrayList<String> instance is thus represented by its class ArrayList.class. Since the ArrayList.class instance is however shared with other instances which could also be of type ArrayList<Integer>, this would already require to have two different versions of ArrayList.class. Such modifications of the class representation would however be incomprehensible to older JREs and thus break the backwards compatibility of Java applications. As a consequence, the following comparison will always succeed:

assert new ArrayList<String>().getClass() == new ArrayList<Integer>().getClass();

Since such a comparison is conducted at run time where the generic type of a class was already erased, this comparison translates to ArrayList.class == ArrayList.class what is trivial. Or more specifically, the running application will determine that ArrayList.class is equal to itself and return true, despite of String.class != Integer.class. This is a major difference of Java to other programming languages like for example C++ and also the reason for a common complaint about Java. (Academically speaking, C++ does not actually know generic types. Instead, C++ offers templates which are however similar to generics.)

So far, this is nothing new to many developers. However, contrary to popular belief it is sometimes possible to retrieve generic type information even during run time. Before explaining, when this is possible, let us look at an example. For this we define the following two classes:

class MyGenericClass<T> { }
class MyStringSubClass extends MyGenericClass<String> { }

MyGenericClass has a single argument for a generic type T. MyStringSubClass extends this generic class and is assigning T = String as its type parameter. As a result, the Java compiler is able to store the information about the generic argument's type String of superclass MyGenericClass in the byte code of its subclass MyStringSubClass. This modification can be achieved without breaking backwards compatibility, because this information is simply stored in a region of the compiled class's byte code which is ignored by old JRE versions. At the same time, all instances of MyStringSubClass can still share a single class representation, since T = String is set for all instances of MyStringSubClass.

But how can we get hold of this information stored in the byte code? The Java API provides the Class.getGenericSuperclass method which can be used to receive an instance of type Type. If the direct superclass is in fact generic, the returned instance is additionally of type ParameterizedType and can be cast to it. (Type is nothing but a marker interface. The actual instance will be an instance of the internal ParameterizedTypeImpl class, you should however always cast to the interface.) Thanks to a cast to the ParameterizedType interface, you can now call the method ParameterizedType.getActualTypeArguments to retrieve an array which is again of type Type. Any generic type argument of the generic superclass will be contained in this array at the same index as in the type definition. Any Type instance which represents a non-generic class is simply an implementation of a Java Class class. (Assuming, you are not handeling an array where the returned type is of GenericArrayType. I will skip this scenario in this article for the sake of simplicity.)

Now we can make use of this knowledge to write a utility function:

public static Class<?> findSuperClassParameterType(Object instance, Class<?> classOfInterest, int parameterIndex) {
  Class<?> subClass = instance.getClass();
  while (classOfInterest != subClass.getSuperclass()) {
    // instance.getClass() is no subclass of classOfInterest or instance is a direct instance of classOfInterest
    subClass = subClass.getSuperclass();
    if (subClass == null) throw new IllegalArgumentException();
  }
  ParameterizedType parameterizedType = (ParameterizedType) subClass.getGenericSuperclass();
  return (Class<?>) parameterizedType.getActualTypeArguments()[parameterIndex];
}

This function will browse through the class hierarchy of instance until it recognizes classOfInterest to be the next direct sub class in the hierarchy. When this is the case, this super class will be retrieved by using the Class.getGenericSuperclass method. As described above, this method returns a class's super class in a wrapped representation (ParamererizedType) which includes the generic types which are found in the subclass. This allows us to successfully run the following application:

Class<?> genericType = findSuperClassParameterType(new MyStringSubClass(), MyGenericClass.class, 0);
assert genericType == String.class;

Be however aware that

findSuperClassParamerterType(new MyGenericClass<String>(), MyGenericClass.class, 0)

will throw an exception in this implementation. As stated before: the generic information can only be retrieved with the help of a subclass. MyGenericClass<String> is however not a subclass of MyGenericClass.class but a direct instance with a generic argument. But without an explicit subclass, there is no <something>.class representation to store the String argument. Therefore this time, the generic type was irretrievably erased during compilation. For this reason, it is a good practice to define MyGenericClass to be abstract, if you are planing on performing such queries on a class.

However, we have not yet solved the problem, since there are several pitfalls we ignored so far. To show why, think of the following class hierarchy:

class MyGenericClass<T> { }
class MyGenericSubClass<U> extends MyGenericClass<U>
class MyStringSubSubClass extends MyGenericSubClass<String> { }

If we now call

findSuperClassParameterType(new MyStringSubClass(), MyGenericClass.class, 0);

an exception will be thrown. But why is this so? So far, we assumed that the type parameter T for MyGenericClass was stored in a direct subclass. In our first example, this was MyStringSubClass which mapped the generic parameter T = String. In contrast, now MyStringSubSubClass stores a reference U = String while MyGenericSubClass only knows that U = T. U is however not an actual class but a type variable of Java type TypeVariable. If we want to resolve this hierarchy, we have to resolve all of these dependencies. This can be achieved by adjusting our example code:

public static Class<?> findSubClassParameterType(Object instance, Class<?> classOfInterest, int parameterIndex) {
  Map<Type, Type> typeMap = new HashMap<Type, Type>();
  Class<?> instanceClass = instance.getClass();
  while (classOfInterest != instanceClass.getSuperclass()) {
    extractTypeArguments(typeMap, instanceClass);
    instanceClass = instanceClass.getSuperclass();
    if (instanceClass == null) throw new IllegalArgumentException();
  }

  ParameterizedType parameterizedType = (ParameterizedType) instanceClass.getGenericSuperclass();
  Type actualType = parameterizedType.getActualTypeArguments()[parameterIndex];
  if (typeMap.containsKey(actualType)) {
    actualType = typeMap.get(actualType);
  }
  if (actualType instanceof Class) {
    return (Class<?>) actualType;
  } else {
    throw new IllegalArgumentException();
  }

private static void extractTypeArguments(Map<Type, Type> typeMap, Class<?> clazz) {
  Type genericSuperclass = clazz.getGenericSuperclass();
  if (!(genericSuperclass instanceof ParameterizedType)) {
    return;
  }

  ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
  Type[] typeParameter = ((Class<?>) parameterizedType.getRawType()).getTypeParameters();
  Type[] actualTypeArgument = parameterizedType.getActualTypeArguments();
  for (int i = 0; i < typeParameter.length; i++) {
    if(typeMap.containsKey(actualTypeArgument[i])) {
      actualTypeArgument[i] = typeMap.get(actualTypeArgument[i]);
    }
    typeMap.put(typeParameter[i], actualTypeArgument[i]);
  }
}

The above code will resolve any chained generic type definitions by tracking them in a map. Please note that it is not enough to examine all type definitions by a specific index since MyClass<A,B> extends MyOtherClass<B,A> defines a perfectly legal subtype.

However, we are still not done. Again, we will look at an example first:

class MyGenericOuterClass<U> {
  public class MyGenericInnerClass<U> { }
}
class MyStringOuterSubClass extends MyGenericOuterClass<String> { }

MyStringOuterSubClass.MyGenericInnerClass inner = new MyStringOuterSubClass().new MyGenericInnerClass();

This time a reflection on the inner class by calling

findSuperClassParameterType(inner, MyGenericInnerClass.class, 0);

will fail. At first glance, this might seem consequent. We are looking for the generic argument type in MyGenericInnerClass on an instance of the same class. As we described above, this is usually not possible since no generic type information can be stored in MyGenericInnerClass.class. Here however, we examine an instance of a (non-static) inner class of a generic class's subtype. MyStringOuterSubClass knows that U = String. We have to take this into account when reflecting on the parameter type of MyGenericInnterClass.

Now here is where things get really tricky. In order to find generic declarations in outer classes, we have to first get hold of this outer class. This can be achieved by reflection and the fact that the Java compiler adds a synthetic (this means without source code representation) field this$0 to any inner class. This field can be retrieved by calling Class.getDeclaredField("this$0"). By obtaining the instance of the outer class in which the current inner class is contained, we automatically gain access to its Java class. Now we could just proceed as above and scan the enclosing class for generic definitions and add them to out map. However, type variable representation of U in MyGenericOuterClass will not equal the representation of U in MyGenericInnerClass. For all we know, MyGenericInnerClass could be static and define its own generic variable name space. Therefore, any TypeVariable type which represent generic variables in the Java API, is equipped with a genericDeclaration property. If two generic variables were defined in different classes, the TypeVariable representations are not equal by their definition, even if they share a name in the same name space by one class being a non-static inner class of the other.

Therefore we have to do the following:
  1. First, try to find a generic type in the inner classes super class hierarchy. Just as you would do with a non-nested class.
  2. If you cannot resolve the type: For the (non-static) inner class and all of its outer classes, resolve the type variables as complete as possible. This can be achieved by the same extractTypeArguments algorithm and is basically 1. for each nested class. We can get hold of the outer classes by checking if the this$0 field is defined for an inner class.
  3. Check if one of the outer classes contains a definition for a generic variable with an identical variable name. If this is the case, you found the actual type of a generic variable you were looking for.
In code, this looks like this:

public static Class<?> findSubClassParameterType(Object instance, Class<?> classOfInterest, int parameterIndex) {
  Map<Type, Type> typeMap = new HashMap<Type, Type>();
  Class<?> instanceClass = instance.getClass();
  while (classOfInterest != instanceClass.getSuperclass()) {
    extractTypeArguments(typeMap, instanceClass);
    instanceClass = instanceClass.getSuperclass();
    if (instanceClass == null) throw new IllegalArgumentException();
  }

  ParameterizedType parameterizedType = (ParameterizedType) instanceClass.getGenericSuperclass();
  Type actualType = parameterizedType.getActualTypeArguments()[parameterIndex];
  if (typeMap.containsKey(actualType)) {
    actualType = typeMap.get(actualType);
  }

  if (actualType instanceof Class) {
    return (Class<?>) actualType;
  } else if (actualType instanceof TypeVariable) {
    return browseNestedTypes(instance, (TypeVariable<?>) actualType);
  } else {
    throw new IllegalArgumentException();
  }
}

private static Class<?> browseNestedTypes(Object instance, TypeVariable<?> actualType) {
  Class<?> instanceClass = instance.getClass();
  List<Class<?>> nestedOuterTypes = new LinkedList<Class<?>>();
  for (
    Class<?> enclosingClass = instanceClass.getEnclosingClass();
    enclosingClass != null;
    enclosingClass = enclosingClass.getEnclosingClass()) {
    try {
      Field this$0 = instanceClass.getDeclaredField("this$0");
      Object outerInstance = this$0.get(instance);
      Class<?> outerClass = outerInstance.getClass();
      nestedOuterTypes.add(outerClass);
      Map<Type, Type> outerTypeMap = new HashMap<Type, Type>();
      extractTypeArguments(outerTypeMap, outerClass);
      for (Map.Entry<Type, Type> entry : outerTypeMap.entrySet()) {
        if (!(entry.getKey() instanceof TypeVariable)) {
          continue;
        }
        TypeVariable<?> foundType = (TypeVariable<?>) entry.getKey();
        if (foundType.getName().equals(actualType.getName())
            && isInnerClass(foundType.getGenericDeclaration(), actualType.getGenericDeclaration())) {
          if (entry.getValue() instanceof Class) {
            return (Class<?>) entry.getValue();
          }
          actualType = (TypeVariable<?>) entry.getValue();
        }
      }
    } catch (NoSuchFieldException e) { /* this should never happen */ } catch (IllegalAccessException e) { /* this might happen */}

  }
  throw new IllegalArgumentException();
}

private static boolean isInnerClass(GenericDeclaration outerDeclaration, GenericDeclaration innerDeclaration) {
  if (!(outerDeclaration instanceof Class) || !(innerDeclaration instanceof Class)) {
    throw new IllegalArgumentException();
  }
  Class<?> outerClass = (Class<?>) outerDeclaration;
  Class<?> innerClass = (Class<?>) innerDeclaration;
  while ((innerClass = innerClass.getEnclosingClass()) != null) {
    if (innerClass == outerClass) {
      return true;
    }
  }
  return false;
}

Wow, this is ugly! But the above code makes findSubClassParameterType work even with nested classes. We could go into even greater detail, since we can also find types of generic interfaces, generic methods, fields or arrays. The idea of all such extractions however remains the same. If a subclass knows the generic arguments of its super class, they can be retreived via reflections. Otherwise, due to type erasure, the generic arguments will be irretrievably lost at run time.

But in the end, what is this good for? To many developers, this conveys the impression of performed black magic such that they rather avoid writing such code. Admittedly, there are in general easier ways to perform such a query. We could have defined the MyGenericSubclass like this instead:

class MyGenericClass<T> {
  private final Class<T> clazz;
  public MyGenericClass(Class<T> clazz) {
    this.clazz = clazz;
  }
  public Class<T> getGenericClass() {
    return clazz;
  }
}

Of course, this works as well and is even less code. However, when you are writing APIs that are to be used by other developers, you often want them to be as slim and easy as possible. (This can go from writing a big framework to writing software in a team of two.) By the above implementation, you force the users of your class to provide redundant information that you could have retrieved differently. Also, this approach does not work likely well for interfaces where you implicitly require the implementing classes to add corresponding constructors. This matter will become even more relevant when looking towards Java 8 and its functional interfaces (also known as closures or lambda expressions). If you require your generic interfaces to supply a getGenericClass method besides their functional method, you cannot longer use them within a lambda expression.

PS: I hacked this code while I was writing this blog article and never really tested it but by dupa debugging. If you need such functionality, there is an excellent library called gentyref which provides the above analysis and much more.

Dienstag, 28. Mai 2013

Memory leaks and memory management in Java applications

One of the more prominent features of the Java platform is its automatic memory management. Many people translate this feature erroneously into there are no memory leaks in Java. However, this is not the case and I am under the impression that modern Java frameworks and Java-based platforms, especially the Android platform, increasingly contradict this erroneous assumption. In order to get an impression on how memory leaks can occur on the Java platform, look at the following implementation of a stack:

class SimpleStack {

    private final Object[] objectPool = new Object[10];
    private int pointer = -1;

    public Object pop() {
        if(pointer < 0) {
            throw new IllegalStateException("no elements on stack");
        }
        return objectPool[pointer--];
    }

    public Object peek() {
        if(pointer < 0) {
            throw new IllegalStateException("no elements on stack");
        }
        return objectPool[pointer];

    }

    public void push(Object object) {
        if(pointer > 8) {
            throw new IllegalStateException("stack overflow");
        }
        objectPool[++pointer] = object;
    }
}

This stack implementation stores its content in form of an array and additionally manages an integer which points to the currently active stack cell. This implementation introduces a memory leak every time an element is popped off the top of the stack. More precisely, the stack keeps a reference to the top element in the array, even though it will not be used again. (Unless it is pushed onto the stack again what will cause the reference to be overridden with the exact same reference.) As a consequence, Java will not be able to garbage collect this object even after all other references to the object are released. Since the stack implementation does not allow direct access to the underlying object pool, this unreachable reference will prevent garbage collection of the referenced object, until a new element is pushed onto the same index of the stack.

Fortunately, this memory leak is easy to fix:

public Object pop() {
        if(pointer < 0) {
            throw new IllegalStateException("no elements on stack");
        }
        try {
            return objectPool[pointer];
        } finally {
            objectPool[pointer--] = null;
        }
    }

Of course, the implementation of a memory structure is not a very common task in day to day Java development. Therefore, let us look at a more common example of a Java memory leak. Such a leak is often introduced by the commonly used observer pattern:

class Observed {

    public interface Observer {
        void update();
    }

    private Collection<Observer> observers = new HashSet<Observer>();

    void addListener(Observer observer) {
        observers.add(observer);
    }

    void removeListener(Observer observer) {
        observers.remove(observer);
    }

}

This time, there exists a method that allows to directly remove a reference from the underlying object pool. As long as any registered observer gets unregistered after its use from the outside, there are no memory leaks to fear in this implementation. However, imagine a scenario where you or the user of your framework forget to deregister the observer after its use. Again, the observer will never be garbage collected because the observed keeps a reference to it. Even worse, without owning a reference to this now useless observer, it is impossible to remove the observer form the observed's object pool from the outside.

But also this potential memory leak has an easy fix which involves using weak references, a Java platform feature that I personally wished programmers would be more aware of. In a nutshell, weak references behave like normal references but do not prevent garbage collection. Thus, a weak reference can suddenly be found being null if there were no strong references remaining and the JVM performed a garbage collection. Using weak references, we can change the above code like this:

private Collection<Observer> observers = Collections.newSetFromMap(
        new WeakHashMap<Observer, Boolean>());

The WeakHashMap is a ready-made implementation of a map that wraps its keys with weak references. With this change, the observed will not prevent garbage collection of its observers. However, you should always indicate this behavior in your Java docs! It can be quite confusing, if users of your code want to register a permanent observer to your observant like a logging utility to which they do not plan to keep a reference to. For example, Android's OnSharedPreferencesChangeListener uses weak references to is listeners without documenting this feature. This can keep you up at night!

In the beginning of this blog entry, I suggested that many of today's frameworks require careful memory management by their users and I want to give at least two examples on this topic to explain this concern.

Android platform:

Programming for Android introduces a life cycle programming model to your core application classes. All in all, this means that you are not in control of creating and managing your own object instances of these classes but that they will instead by created by the Android OS for you whenever they are needed. (As for example if your application is supposed to show a certain screen.) In the same manner, Android will decide when it does not longer need a certain instance (as when your application's screen was closed by the user) and inform you about this removal by calling a specific life cycle method on the instance. If you however let a reference to this object slip away into some global context, the Android JVM will not be able to garbage collect this instance contrary to its intent. Since Android phones are usually rather restrained in memory and because Android's object creation and destruction routines can grow pretty wild even for simple apps, you have to take extra care to clean up your references.

Unfortunately, a reference to a core application class slips away quite easily. Can you spot the slipped reference in the following example?

class ExampleActivity extends Activity {

    @Override
    public void onCreate(Bundle bundle) {
        startService(new Intent(this, ExampleService.class).putExtra("mykey",
                new Serializable() {
                    public String getInfo() {
                        return "myinfo";
                    }
                }));
    }
}

If you thought, it the this reference in the intent's constructor, you are wrong. The intent only serves as a starting command to the service and will be removed after the service has started. Instead, the anonymous inner class will hold a reference to its enclosing class which is the ExampleActivity class. If the receiving ExampleService keeps a reference to the instance of this anonymous class, it will as a consequence also keep a reference to the ExampleActivity instance. Because of this, I can only suggest to Android developers to avoid the use of anonymous classes.

Web application frameworks (Wicket, in particular):

Web application frameworks usually store semi-permanent user data in sessions. Whatever you write into a session will usually stay in memory for an undetermined period of time. If you litter up your sessions while having a significant number of visitors, your servlet container's JVM will pack up sooner or later. An extreme example of needing to take extra care of your references is the Wicket framework: Wicket serializes any page a user visited in a versioned state. Oversimplified, this means that if one of your website's visitors clicks your welcome page ten times, Wicket will in its default configuration store ten serialized objects on your hard drive. This requires extra care because any references hold by a Wicket page object, will cause the references objects to be serialized together with the page. Look for example at this bad practice Wicket example:

class ExampleWelcomePage extends WebPage {

    private final List<People> peopleList;

    public ExampleWelcomePage (PageParameters pageParameters) {
        peopleList = new Service().getWorldPhonebook();
    }
}
By clicking your welcome page ten times, your user just stored ten copies of the world's phone book on your servers hard drive. Therefore, always use LoadableDetachableModels in your Wicket applications which will take care of the reference management for you.

Tracing memory leaks in Java applications can be tiresome and therefore, I want to name JProfiler as a useful (but unfortunately non-free) debugging tool. It allows you to browse through the insides of your Java running application in form of for example heap dumps. If memory leaks are a problem for your applications, I recommend to give JProfiler a shot. There is an evaluation license available.

For further reading: If you want to see another interesting occurrence of memory leaks when you are customizing class loaders, refer to the Zeroturnaround blog.

Freitag, 24. Mai 2013

Converting Microsoft DOC or DOCX files into PDF using Java without contortions

I will give you a heads up: There is no simple, well-performing solution using pure Java. To get an intuition for why this is the case, just try to open a DOC-formated file with a non-Microsoft text editor, usually Apache Open Office or Libre Office. If your file contains more than a few standard formated lines, you are likely to experience layout displacements. The same is true for the DOC-format's XML-based successor, the DOCX format.

Unfortunately, converting a file to PDF conforms to opening the DOC-file and printing it out into another file. Consequently, the resulting PDF file will contain the same layout displacements as the software you originally used to open the DOC-file. Of course, this does not only apply to Open Office: You would face the same difficulties (or probably even worse) if you read a DOC(X) file using any Java library offering such functionality.

Therefore, a fully functioning DOC(X) to PDF conversion will always require you to use Microsoft Word. Unfortunately, Microsoft Word does not offer command line switches for direct printing or PDF-conversion.

Recently, I was faced with this problem what lead me to implement the small workaround which I will introduce in the reminder of this blog entry. To begin with, you need a working installation of Microsoft Word 2007 or higher on your machine. If you are using Microsoft Word 2007, make sure that the PDF plugin is installed. Later versions of MS Word are already bundled with this plugin. Secondly, you need to make sure that you have the Windows Scripting Host installed on your computer. This is basically the case for any Windows operating system. The Windows Scripting Host allows us to run Visual Basic scripts as this one:

' See http://msdn2.microsoft.com/en-us/library/bb238158.aspx
Const wdFormatPDF = 17  ' PDF format. 
Const wdFormatXPS = 18  ' XPS format. 

Const WdDoNotSaveChanges = 0

Dim arguments
Set arguments = WScript.Arguments

' Make sure that there are one or two arguments
Function CheckUserArguments()
  If arguments.Unnamed.Count < 1 Or arguments.Unnamed.Count > 2 Then
    WScript.Echo "Use:"
    WScript.Echo "<script> input.doc"
    WScript.Echo "<script> input.doc output.pdf"
    WScript.Quit 1
  End If
End Function


' Transforms a doc to a pdf
Function DocToPdf( docInputFile, pdfOutputFile )

  Dim fileSystemObject
  Dim wordApplication
  Dim wordDocument
  Dim wordDocuments
  Dim baseFolder

  Set fileSystemObject = CreateObject("Scripting.FileSystemObject")
  Set wordApplication = CreateObject("Word.Application")
  Set wordDocuments = wordApplication.Documents

  docInputFile = fileSystemObject.GetAbsolutePathName(docInputFile)
  baseFolder = fileSystemObject.GetParentFolderName(docInputFile)

  If Len(pdfOutputFile) = 0 Then
    pdfOutputFile = fileSystemObject.GetBaseName(docInputFile) + ".pdf"
  End If

  If Len(fileSystemObject.GetParentFolderName(pdfOutputFile)) = 0 Then
    pdfOutputFile = baseFolder + "\" + pdfOutputFile
  End If

  ' Disable any potential macros of the word document.
  wordApplication.WordBasic.DisableAutoMacros

  Set wordDocument = wordDocuments.Open(docInputFile)

  ' See http://msdn2.microsoft.com/en-us/library/bb221597.aspx 
  wordDocument.SaveAs pdfOutputFile, wdFormatPDF

  wordDocument.Close WdDoNotSaveChanges
  wordApplication.Quit WdDoNotSaveChanges
  
  Set wordApplication = Nothing
  Set fileSystemObject = Nothing

End Function

' Execute script
Call CheckUserArguments()
If arguments.Unnamed.Count = 2 Then
 Call DocToPdf( arguments.Unnamed.Item(0), arguments.Unnamed.Item(1) )
Else
 Call DocToPdf( arguments.Unnamed.Item(0), "" )
End If

Set arguments = Nothing

Copy this script and save it on your machine. Name the file something like doc2pdf.vbs. I will at this point not go into the details of Visual Basic scripting since this blog is addressed to Java developers. In a nutshell, this scripts checks for the existence of two command line arguments. The first of these arguments represents the DOC(X) file to be converted. The second parameter is optional and represents the output file. If no such parameter can be found, the script will simply append .pdf to the DOC(X) file and save this output in the same directory. The conversion is achieved by calling Microsoft Word silently. There exist more advanced implementations of this functionality on the net.

You will now be able to call this script from a MS Windows console (cmd) by typing:

C:\example\doc2pdf.vbs C:\example\myfile.docx

After executing this script, you will find C:\example\myfile.docx.pdf on your machine. Make sure that this conversion works in order to confirm that your system is configured correctly.

But there is more bad news. You will not be able to call this script from Java directly. Attempting to run the script via Runtime.exec will result in an java.io.IOException. The reason for this exception can be found in its description:
Cannot run program "C:\example\doc2pdf.vbs": CreateProcess error=193, %1 is not a valid Win32 application
Apparently, Java cannot access the Microsoft Script Host and does therefore not recognize our script as a valid application. This requires us to apply another workaround: We will write a small bash script that executes the Visual Basic script for us. This script will look something like this:

@Echo off
pushd %~dp0
cscript C:\example\doc2pdf.vbs %1 %2

Save this file as doc2pdf.bat. Again, I will spare you the details of this short bash script but it generally will only execute the Visual Basic script and will additionally pass its first two command line arguments to it. (If there are any.) Try this script by typing

C:\example\doc2pdf C:\example\myfile.docx

into your command line and to see if your script is set up correctly. The advantage of this bash script over the Visual Basic implementation is that it can be called by Java:

try {
    String docToPdf = "C:\\example\\doc2pdf.bat";
    File docPath = new File(getClass().getResource("/mydocument.docx").getFile());
    File pdfPath = new File(docPath.getAbsolutePath() + ".pdf");
    String command = String.format("%s %s %s", docToPdf, docPath, pdfPath);
    Process process = Runtime.getRuntime().exec(command);
    // The next line is optional and will force the current Java 
    //thread to block until the script has finished its execution.
    process.waitFor();
} catch (IOException e) {
    e.printStackTrace();
} catch (InterruptedException e) {
    e.printStackTrace();
}

By calling Process.waitFor you can block your execution thread until the bash script has finished its execution and the PDF file was produced. Additionally, you will receive a status code as a return value which informs you whether the bash script has terminated correctly. The PDF file can be accessed by the variable pdfPath in the above script.

It remains disappointing  that this solution will most likely only run on Windows systems. However, you might get it going on Linux via Wine and winetricks. (Winetricks allows to install Visual Basic for the Windows Scripting Host by the parameter option wsh56vb.) Any feedback on such further experiments are appreciated.