@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:
http://stackoverflow.com/questions/6903335/java-7-path-vs-file
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
them).
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.
<utopia>
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.
</utopia>
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:
http://www.adam-bien.com/roller/abien/entry/why_not_one_application_per
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:
http://fxexperience.com/2012/06/application-deployment-with-javafx/
More information about the core-libs-dev
mailing list