@Supported design issues

Daniel Latrémolière daniel.latremoliere at gmail.com
Sun Mar 17 19:10:32 UTC 2013

> 1. I suspect that the percentage of deprecated APIs is less than 0.1 % ..
>     So removing 1 ouf every 1,000 methods is not exactly going to make
>    a huge difference here.
> 2. Some methods were deprecated at a time when the policy was to
>     encourage people to use "newer" API, even though there wasn't
>     anything very wrong. with the old one.
>     For example Component.show()/hide() were deprecated
>     in favour of Component.setVisible(boolean) although as far as I know
>     there's absolutely no problem with the former.
>     So such a policy would not be something you could apply automatically
>     you'd need to go examine each case to understand it.
Yes or no for 0,1%, depending if you include some big parts like AWT, 
Swing, CORBA which are obsolete for many developers, because they are 
not considered up-to-date for their domains (UI, RPC) and their 
development is stopped. In this case, deprecated or obsolete API are 
concerning important domains, like:

  * UI (AWT -> Swing -> JavaFX),
  * date management (Date -> Calendar -> JSR 310)
  * RPC (RMI, CORBA, WebServices, REST like JAX-RS: not all are used
    even if winner depends of project).
  * LDAP dedicated API are provided by vendors like Apache Directory,
    OpenDJ for replacing JNDI (not evolving since Java 1.4 and seen not
    sufficiently specialized).
  * Logging API is split between java.util.logging, Log4J, SLF4J
    (depending of project).

Other domains has evolved (like IO, NIO, NIO2) but contains some complex 
differences: e.g. Path vs. File. Considering File as deprecated in Java7 
is frequent even if it is not official: 

Another related problem for a developer is that many parts of API show 
their age given others enhancements: e.g. Math/StrictMath classes were 
introduced before Integer/Long/Float/Double classes but would probably 
not have existed if order was inverse (static methods are notoriously 
difficult to find, because we don't know by default the class containing 

Globally, an API designed before Java 1.5 has usually be updated for 
generics but not for enumerations and only partially for annotations. 
Now, seeing an int for describing an enumeration in an API became 
surprising (like Modifier in reflection). Marker interfaces (like 
java.io.Serializable, java.util.RandomAccess) have same problem against 
annotations. The reason is simply that Java 1.5 is old: it has 8.5 
years. API designed before have accumulated a technical debt and are not 
seen up-to-date.

I think, I have covered big parts of Java API, concerning all 
developers, with various names (deprecated, obsolete, technical debt) 
for only one problem: feeling of an old API and need of cleaning it.

NB: With static methods in interface, you will probably have the same 
problem in some years:

1) First round: add factories methods in interface.
Developer speaking: When I want an instance of an interface it is always 
difficult to search a subclass and only after that call its constructor. 
I want to go to the expected interface and call a static factory for all 
my frequent usecases, then: please add some static methods like 
followings in List class (and all other interfaces with implementations 
provided by default):
public static <E> List<E> newRandomAccessList() {
    return new ArrayList<E>();
public static <E> List<E> newLinearAccessList() {
    return new LinkedList<E>();

2) Second round (some years after): remove them from public API.
Developer speaking: I do not need to see AbstractList, ArrayList and 
LinkedList because I don't call them directly, at least in 99% of my 
usecases. This is a List-related implementation detail only useful when 
I want to create my own custom List for a highly specific and 
performance-sensitive usecase. Remove these classes from public API and 
put them in another library not seen by me by default, excepted if I 
really search it.
In Javadoc, I only see the signature of method, and not the code of 
method (implementation detail), then I don't want to see these classes 
only implementing interfaces (implementation detail): the factory method 
in interface is sufficient with one paragraph in the Javadoc giving 
tradeoffs of each implementation provided by default.

> 3. Removing methods *from the doc* and *from the runtime* each
>     have their consequences, from the doc would discourage new uses
>     but make it harder to understand old code. I think a long ago 
> ill-fated JSR
>     for javadoc improvements pondered hiding deprecated methods if
>     you didn't want to see them. Remiving from the runtime would
>     break apps, and in some cases people don't have the option to change
>     and fix.
Currently, profiles are clearly reducing some API complexity for developer.
NB: JavaFX doclet seems to remove methods with prefix impl_ from Javadoc.

I think it seems sad, that one of the biggest differences between Java 
and shorter language like JavaScript is static typing: it give an 
excellent accuracy when used for automatic refactoring in Java. Given 
static typing, IDE have added many automatic refactoring and some 
mechanisms for helping updating code (e.g. generics), JSR 308 has also 
some inference tools.

But bytecode refactoring (AOT in build process or JIT in ClassLoader) 
was mostly used for supporting new Java code with old JVM (Retroweaver, 
Retrotranslator) and not the inverse: supporting old Java bytecode on 
new JVM. I thought it was possibly used for executing JavaME program on 
JavaSE JVM but I am not sure.

I hope of a future where Java easier refactoring (given static typing) 
would help evolving Java faster by breaking direct compatibility while 
keeping sufficiently real compatibility (old programs are only slightly 
slower in compatibility ClassLoader). With easier evolution, Java API 
can be better organized and developer become happy.

NB: I never used "Java platform" because I think Java is slowly 
evolving, for developers, to become more a library for their 
application, than a platform containing application. Having an 
integrated JVM in each application is a big change in compatibility 
requirements, because developer has control on compatibility and it will 
possibly relax some constraints.
1) JavaEE applications are evolving to include server and not inverse: 
2) JavaSE applications are evolving to include JVM and not to run on a 
JVM provided by OS: mobile OS prohibiting shared libraries and security 
problems of OS-global JVM define the rules: 

More information about the core-libs-dev mailing list