Casting collections in Java

Assuming two classes A and B as

class A {}
class B extends A {}

It is just logical that casting B to A works fine:

A anObjectOfClassA = new B();

But when it comes to collections of As and Bs, a strange phenomenon appears in Java:

Collection<B> collectionOfBs = new LinkedList<B>();
Collection<A> collectionOfAs = (Collection<A>)collectionOfBs; // this line does not compile!

That is, though the collection wrapper (the java.util.Collection class) is the same and B extends A, casting a collection of objects of class B to a collection of objects of class A throws an compile-time error.

But it works using generics (the whole class for the sake of completeness and reusability):

import java.util.Collection;
import java.util.LinkedList;

public class CollectionCastingExample {

  class A {}
  class B extends A {}
	
  Collection<B> collectionOfBs = new LinkedList<B>();
//  Collection<A> collectionOfAs = (Collection<A>)collectionOfBs;
	
  Collection<A> collectionOfAs = downCastCollection(collectionOfBs, A.class);
	
  /**
   * Casts a collection of objects of class B where B extends A to a collection of objects of class A.
   * 
   * @param <T> Base class
   * @param collection Collection of objects of a class extending T 
   * @param aClass Representation of T
   * @return Collection of objects of T casted from given collection of objects of a class extending T.
   */
  @SuppressWarnings("unchecked")
  public static <T> Collection<T> downCastCollection(Collection<? extends T> collection,
      Class<T> aClass) {
    return (Collection<T>) collection;
  }
}

Despite the fact that a @SuppressWarnings("unchecked") is required, it avoids iterating over the whole collection of Bs and casting each of them from B to A plus adding them to a new collection of As.

Adding a New Service (GWT)

Adding a new servlet/service to you GWT application is quite straight forward, e.g. by copying the example “greetingService” or creating a new servlet. But it’s easy to overlook a required change/adjustment of your project’s configuration and you might end up with an error message like “Blocked attempt to access interface ‘some.package.SomeService’, which is not implemented by ‘some.other.package.SomeOtherServiceImpl’; this is either misconfiguration or a hack attempt”.

Check list (some should be replaced with whatever you want to call your new service):

  • Copy or create files:
    SomeService.java and SomeServiceAsync.java in client package
    SomeServiceImpl.java in server package + change implementation statement to SomeService
  • Adjust web.xml:
    <servlet>
    	<servlet-name>someServlet</servlet-name>
    	<servlet-class>some.package.SomeServiceImpl</servlet-class>
    </servlet>
    <servlet-mapping>
    	<servlet-name>someServlet</servlet-name>
    	<url-pattern>/[copy base directory name from other service declaration]/some</url-pattern>
    </servlet-mapping>
  • Annotate interface SomeService.java:
    @RemoteServiceRelativePath("some")
  • Connect to your new service in the client:
    private final SomeServiceAsync someService = GWT.create(SomeService.class);

Definitely some possibilities to make a mistakes or miss something here.