Friday, October 21, 2011

A somewhat bizarre exception

Have you ever seen this error?

java.lang.SecurityException: Prohibited package name: java.lang
It was tough looking it up on the internet. Usually, there are many postings about any one error message or exception. But not in this case.  Actually, the explanation is quite accurate and helpful, providing that you believe it.  It says that you've created a package called java.lang in your project, which is not allowed.  nevertheless, you probably didn't mean to do that so you may be mystified by the description.

I suppose the villain of this particular piece is the otherwise-wonderful Eclipse. Eclipse allowed me to (inadvertently) create the java.lang package in my project when I sub-classed a class in java.lang. Many of those are final so can't be extended thus you won't often run into this problem (it's taken me about 16 years!).  And in any case, the package only defaults to that of the sub-class when you click New in the type hierarchy window.  In and of itself, having a java.lang package is not fatal. Eclipse will run it.

But if you create a jar file with that class in it, you cannot add the jar file to your class loader -- the exception mentioned above will be thrown.

OK, back to work!

Monday, February 28, 2011

Things that Java got wrong, part 2: interface method bodies

The concept of the interface in Java is undoubtedly one of the best things about the language.  It almost, but not quite, makes up for not having pure multiple inheritance.  I particularly like the fact that you can define zero or more method signatures as well as zero or more constants.

But why not allow abstract method bodies?  If that sounds like a contradiction in terms, let me try to explain.  I'm using the term abstract in the sense of non-concrete.  Let's take an example.  You define an interface called SetOperable<T> and you define the following methods:

public abstract SetOperable<T> intersect(SetOperable<T> s);

 public abstract SetOperable<T> union(SetOperable<T> s);

 public abstract Collection<T> members();

 public abstract SetOperable<T> clear();

 public abstract SetOperable<T> add(T t);
Now, whereas you want to be able to implement the set operations on any type T, you are clearly going to have to define, in a concrete type, either the intersect or the union method.  But the other method is normally derivable in terms of the first.

So, in Java, you must create an abstract class which implements the required interface and which looks something like the following:

public abstract class SetOperable_<T> implements SetOperable<T> {

 @Override
 public SetOperable<T> union(final SetOperable<T> s) {
  final Collection<T> temp = new ArrayList<T>(members());
  temp.addAll(s.members());
  final SetOperable<T> intersection = intersect(s);
  final SetOperable<T> result = intersection.clear();
  final Collection<T> duplicates = intersection.members();
  final Iterator<T> iterator = temp.iterator();
  while (iterator.hasNext()) {
   final T t = iterator.next();
   if (duplicates.contains(t)) {
    iterator.remove();
    duplicates.remove(t);
   }
  }
  for (final T t : temp)
   result.add(t);
  return result;
 }
}

Concrete classes will extend this abstract class, defining the details of intersect, members, clear, add, etc.  But it would be so much nicer to be able to define this union method in the interface itself and not have to bother with an abstract class, assuming of course that you can define the method in terms of the interface (or its super-interfaces).  Scala allows you to do just that, at least in its own way, but not Java.

I admit that it's not the end of the world, but it can be awkward if you have a concrete class that should extend some other type as well as extending the above abstract class.  You can't have it extend both.  In the given example, you might want your concrete class to extend AbstractSet, for example.

OK, back to work!