Here is a few things I would do differently if I was King of Java.
Note that some of these can't be changed now, even if Sun wanted to, for compatibility reasons. It wouldn't be java any more. I'll rant away anyway.
Contents |
Bytes
Bytes are signed 8 bit numbers in jave, i.e. have the range -127 to +127. This sucks. Numbers in this range are hardly ever needed, bytes are generally used as opaque chunks of data, i.e. 8 bit octets. So, if I was King, bytes would not be numbers. They could be casted to numbers (like char can), and bitwise-operators would be allowed for them, as well as comparisons with other bytes (but not with numbers). Arithmetic operators would not be available for bytes.
Streams
InputStream, OutputStream, Reader and Writer would be interfaces.
PrintOutput
An interface PrintOutput would be very nice, which would be implemented by both PrintWriter and PrintOutputStream. This would avoid tha pain of having to implement dump/log functions for both, or constructing wrapper streams all the time. Having a common interface for the common aspects of PrintWriter and PrintOutputStream would be consistent with the DataOutput and ObjectOutput interfaces.
No more arrays
Arrays are dumb and belong into satic languages like C. For a high level language like java, I'd just want some syntactic sugar to initialize Collections: List l = new ArrayList { "foo", "bar" };. Providing a similar syntax for initializing Map objects would also be nice.
If we have to live with arrays, they could at least provide meaningfull implementations of hashCode, equals, and toString, reflecting their contents instead of their identity.
Equality
Interfaces should specify their contracts with regards to the semantics of equals/hashcode. Especially, it sucks that CharSequences are not defined to be equal if they contain the same characters. This makes that interface quite useless in many cases.
Charset Support
There should be a way to tell the compiler the encoding the source code is in *inside* the file. Like a file-level annotation.
Property files
Property files are encoded in Latin-1, per spec. They should be defined to be UTF-8 encoded, especially since they are commonly used as resource files for internationalization (via PropertyResourceBundle).
System.out
There is no way to control the charset used by System.out from insode the application. There is also no per-user config file to control this, to make it match the user LANG setting. This is unnerving.
Classpath
Jarpath
A "jarpath" option would be nice - it would add all jar files in the given directories to the classpath (perhaps even recursively).
Applet Class Loader
The Applet Class Loader insist on always checking for class files in the web directory the applet is loaded from, even if the applet is loaded from a jar file (which is the most common case). For complex applets, this causes a lot of futile HTTP requests, making the applet very sluggish. There should alt least be an option to turn this off. Perhaps I'll write more about this on a separate page soon.
Synchronization
wait timeout
The wait method should throw an exception if the timeout is reached. Or at least return a boolean indicating wether it returned because the thread was woken up by a call to notify, or because the specified time limit was reached.
InterruptedException
Threads can't be interrupted when waiting on a monitor (i.e. on a synchronized statement).
Reflection
getMatchingMethod
I want a method that gives me the method for a given class that best matches the given list of parameter types, using the same algorithem the compiler uses when determining what a method invokation should be bound to. getMethod requires an exact match of the parameter types, which makes it quite useless.
Method Access
Access checks in the reflection interface see very odd. For example, if you want to invoke a method that is declared in a (public) interface, but implemented in a non-public class, you have to use getMethod on the interface - if you get the method from the non-public class, it's still public, but trying to call it results in an IllegalAccessException, because the implementing class is not public. This is silly, and contrary to the idea of polymorphism.
Servlets
Encoding of request parameters
It's impossible to change the encodding used for decoding URI-encoded characters in GET parameters (at least in Topcat). Well, it can be changed using the URIEncoding option of the Connector in server.xml [1], but that will change it for all web applications. It's not possible to use UTF-8 in GET requests for one web app, while using Latin-1 in another. This is doubly bad since the encoding used by the browser is generally determined by the encoding the page is served in - so if one webapp has a form on a utf-8 page, and one has a form on a latin-1 page, you lose.
The only workaround seems to be to get the raw request string from HttpServletRequest.getQueryString() [2], and decode it by hand. The resultin map can be stapled to the request object using setAttribute. A fugly hack.
No good place for configuration
The seems to be no good place for configuring a servlet/web-app. init-params in the web.xml would be the obvious choice, but it's deployed from the war file, so it's overwritten on update. The next possibility I looked at was the context.xml associated (in an arcane way) with the web-app, but it only lets you define a very narrow set of things: HTTP-handling cruft, resources (like database access), etc. But no way to set init-params or something similar.
So, how about stuffing it all into a "resource"? That would require a resource-ref in the web.xml file, so the resource's name would be hard-coded. Which makes it impossible to deploy the same web-app twice, with different configurations, without messing with the web.xml again. It boild down to this: the servlet spec doesn't give a way to freely configure web-apps at deployment time. They have to be configured when the war is build, so the war file becomes deployment-specific. This sucks.
As it turns out, there's a tomcat specific solution: first of all, it's worth noting that ServletContext.getInitParameter is misnamed: it gets a context param, not an init param - that is, it accesses the values defined by <context-param> tags in the web.xml, directly inside the top level <web-app> element (application level). Now, Tomcat provides a way to set/override context-params from inside the context definition: you can put <Parameter> tags into the <Context> element (see Context Parameters). Now, if I could do the same with resource references, i'd be happy.
Other people's peeves
- Value objects WTF!!?!!1! (Kevin Bourrillion)




(no comments yet)