The language itself is a bit dated, lacking features such as enums and properties, but the worst part is the libraries.
Something as basic as a date can be manipulated with either the java.util.Date or java.util.Calendar. There is probably a neat history to explain why one would want two different versions of the same structure, but it should not be that way. The stock library should have a one-fits-all approach.
When working with the Calendar type, the annoying use of factory patterns result in less readable code, such as:
Rather than just:
Calendar date = Calendar.getInstance(); date.setDate(year, month - 1, day);
Calendar date = new Calendar(year, month, day);
You can opt to use java.util.GregorianCalendar instead, which does allow a non-factory type initialization, but that is still one extra hurdle to work with.
As an incomprehensibly strange decision, the month numbering starts with 0, but day starts with 1 as does day of week. This makes it unnecessarily awkward to work with dates, for no apparent gain.