warpedjavaguy

Imperative by day and functional by night

Renegading Java Classics


Anything that is deprecated and superseded can be considered classic and should be renegaded.
 

The Java API has undergone many changes since the original 1.0 and classic 1.1 and 1.2 versions. The changes include both enhancements and deprecations. Any classes, interfaces, and methods that have been marked as deprecated should no longer be used. They are supported for backwards compatibility purposes and are likely to never be removed from future Java releases. It is recommended (but not enforced) that programmers never use them in their programs. I can understand the rationale behind this. Backwards compatibility is important and all reasonable measures should be taken to ensure that it is always preserved. Deprecation provides a means of providing this compatibility. The problem is that in doing so, it forever supports something that is deprecated without strictly enforcing that it no longer be used.

I would like to propose the idea of introducing a new and specialised type of deprecation called renegation whereby anything that is superseded and unsupported can be physically demoted to ‘classic’ status and not be supported in source code but in bytecode only. A Java compiler that supports this would error when attempting to compile any code that makes any direct use of anything marked renegaded. Anything that is already marked and compiled as renegaded would be fully supported at runtime but strictly controlled at compile time. This would ensure that all bytecode remains valid and that any source code that does not have any compile time dependencies on anything marked renegaded still compiles. In this way, all newly written and compiled code would be clean and free of any renegaded code and will still be able to make use of any new or existing precompiled binaries. Programmers would then be forced to not write or compile any code that makes direct use of anything that is renegaded. They would be forced to use the preferred alternatives instead. Compatibility would still be supported through binaries and any existing code that requires recompilation would have to be updated to ensure that all renegaded code fragments are replaced with the preferred alternatives first.

Renegation should not have any impact on deprecation and should not be applied to everything that is already deprecated. It should instead only be applied to types that may or may not already be deprecated and are suitable because they are obsolete and superseded by preferred alternatives (like the java.awt.List.clear() method for example). Furthermore, it would also make it easier to deprecate and avoid using certain ‘classic’ types that have not yet been deprecated but should have been (like the java.util.Enumeration interface for example). The Enumeration interface is a primary candidate for renegation, especially when you consider that it is only reactively used and has a special note included in it’s Javadoc comments stating that Iterators should be considered in preference.

Enumeration Javadoc comment:

NOTE: The functionality of this interface is duplicated by the Iterator interface. In addition, Iterator adds an optional remove operation, and has shorter method names. New implementations should consider using Iterator in preference to Enumeration.

In order to support renegation and preserve deprecation, the existing @Deprecated annotation would need to be extended, or a new core Java annotation type or type modifier would need to be introduced.

Here are some suggestions:

/* Option 1:
Extending the existing @Deprecated annotation type */

@Deprecated (renegation = "classic")
public interface Enumeration<E> {
...
}

/* Option 2:
Introducing a new @Renegaded annotation type */

@Renegaded (status = "classic")
public interface Enumeration<E> {
...
}

/* Option 3:
Introducing a new classic type modifier */

public classic interface Enumeration<E> {
...
}

Of course, renegation should be supported at the type, method, and attribute levels. Its use should not just be limited to just the Java API either. Any code in any codebase should be able to be renegaded if deemed suitable.

Advertisements

Written by warpedjavaguy

October 10, 2007 at 11:33 am

Posted in java, programming

Tagged with

8 Responses

Subscribe to comments with RSS.

  1. This smells more like a coding convention thing to me — which I don’t think really belongs in the core API.. However, it would be a menial task to write a custom annotation that would perform the very function that you are talking about without adding more bloat to the API — you could even start a java.net project to enforce coding conventions at compile time through the use of annotations.

    Personally, I think the core Java API is already uber-bloated and needs to be componentized — and while I like the concept of your idea, it seems like this should be an optional component for your codebase as opposed to being part of the underlying API

    Chris Schmidt

    October 11, 2007 at 1:52 am

  2. I could solve the problem at the project level using checkstyle too. But if I really wanted to renegade something from my project I’d delete it. I could always retrieve it again from the SCM if I wanted it back.

    What I’d rather have though is a stronger deprecation mechanism. One that forces programmers to use the preferred alternatives that supersede what is deprecated. Deprecation is a core Java feature. It’s more than merely just a coding convention. Renegation would take deprecation that one step further and would eliminate the ‘classic’ bloat from all new code that we write instead of just encouraging us not to write it.

    WarpedJavaGuy

    October 11, 2007 at 9:24 am

  3. You might also have to think about existing APIs that require their clients to use the “renegated” features. Not sure how you’d decide what’s safe to “renegate” and what isn’t – if there are APIs using something, you need ability to write source code that talks to those APIs as well as letting existing already-compiled code use it.

    Take that example of java.util.Enumeration. There are methods in the Servlet API that return Enumeration. Any source code that calls those methods is going to have Enumerations to deal with. Same for any other old API that’s still taking Enumerations, Vectors etc as method arguments or returning them (and this presumably accounts for why they can’t even be officially deprecated).

    Mike Kaufman

    October 11, 2007 at 9:55 am

  4. The idea would be to only renegade what is superseded (not necessarily deprecated). Dependent API’s would still be functional because the renegaded objects would still be supported at the bytecode level.

    A compiler option could be introduced to enable API’s to still compile. Eliminating renegaded features from those API’s could then be a gradual process that would ultimately lead to official deprecation. Any new API’s though, could immediately take advantage of the mechanism.

    WarpedJavaGuy

    October 11, 2007 at 10:22 am

  5. This is an absolutely terrible idea.

    I’ve worked on systems which are seven or eight years old, whose API use seems almost entirely deprecated. But there are still bugs which require fixing in these systems, and it is still someone’s job to fix them.

    Are you seriously suggesting that it should no longer be possible to compile changes to systems which use old APIs, purely because it appeals to the aesthete in you not to see the ‘old’ methods?

    Christ on a bike.

    sporty

    October 11, 2007 at 6:28 pm

  6. sporty,

    I’m not sure if you missed it but I did mention in comment #4 above that a compiler option could be introduced to allow codebases that still use the older stuff to still compile. When disabled there would be no impact at all and all would be the same as it is now. But when enabled, it would provide a stronger deprecation mechanism that would make anything marked ‘renegaded’ seem invisible to the compiler and the programmer but not the runtime.

    Remember also that not everything that is deprecated should be renegaded. Only the superseded stuff.

    WarpedJavaGuy

    October 11, 2007 at 8:37 pm

  7. You might be interested in Jackpot which provides the ability to define source code transformations, most notably those which will upgrade Java code from an older form to a new replacement form (for example StringBuffer –> StringBuilder).

    I think tools like this this, in combination with IDE/compiler warnings for use of deprecated code is sufficient. If you have the will and ability to modify your code (to annotate or otherwise mark it as using something old) you should simply fix it.

    Alex Miller

    October 11, 2007 at 11:48 pm

  8. The Jackpot API can be used to transform existing code to not use anything deprecated and would sure be useful at a project level. But it would be nice if Java could keep everything that is obsolete out of sight and out of mind whilst still maintaining backwards compatibility.

    Maybe ‘renegaded’ is too harsh a word. A stronger deprecation mechanism is what I am really suggesting though.

    WarpedJavaGuy

    October 12, 2007 at 8:40 am


Comments are closed.

%d bloggers like this: