Skip to main content

When should deprecated classes and members be removed from the JDK?

Immediately upon deprecation
5% (43 votes)
One full version after their deprecation
35% (330 votes)
Two full versions after their deprecation
37% (346 votes)
More than two full versions after their deprecation
7% (63 votes)
Never
13% (123 votes)
Something else (please comment)
4% (33 votes)
Total votes: 938

Comments

Differing Interests of Server Side versus Client Side Developers

i do desktop development in Swing as well as serverside webapps. if i only developed webapps i would be far more keen to see the benefits of deprecation sooner rather than later - in a server environment you are much more likely to have control over which JRE is running, you can refactor and recomplie, you may also have the option of just not upgrading the JRE ... and with a future module system, you will be able to make such any "legacy modules" are installed ... but as a desktop (or mobile) developer you may not have an ongoing relationship with your end users and so have little to no control over what JRE they are running - which means a JRE upgrade that removes a single deprecated method could see you app just stop working ... if the end users wants to keen using the upgraded JRE to run other new apps, you will be forced to release a new version of your app, possibly with every new JRE release ... so i wonder: are desktop and mobile app developers are less keen in general on deprecation than server side developers? ...

Differing Interests of Server Side versus Client Side Developers

if you can't be bothered to update an application when something is deprecated over the 4-5 years it takes to create and release 2 new versions of the JDK after the one that deprecated the functionality (2 versions is IMO a good benchmark, it's what most manufacturers use for support timeframes of APIs) you can't complain about it not running anymore...

And if your users refuse to upgrade their applications and supporting environments for that long a period of time they can no longer blame you for not envisioning future changes in the platform.

Deprecated APIs and Desktop Java Deployment.

its not a matter of "can't be bothered to update" (i would aim to release new versions or updates annually) but of wanting non-technical home users to have an "it just works" experience. i agree, customers can only reasonably expect so much, but i would rather have customers who are happy because they got more than they expected than ones who are unhappy but resigned to fact that it would be unreasonable to complain ... the more often a non-technical home user has to upgrade, the more factors (app version, JRE version, operating system version) are involved in the upgrade the more chance of something going wrong and/or the end users switching to a competing product ... the simplest upgrade path is no upgrade at all ... also, i might be wrong, but i imagine if an end user updated their JRE, that it would still succesfully load a class containing a call to a method in a deprecated API, but would then fail if and when the method is called. (is this correct?) from a non-technical end users perspective, that would produce unexplainable behaviour ... a negative experience ... the Java Platform(s) is/are huge and obviously a lot of different developers have an interest in how it/they evolves ... at the end of the day, Java is strongest on the server. so server side developers will likely have the most influence ... and rightly so ... as a webapp developer, i see cleaning out the cruft and even rewritting core APIs (eg. URL and URLConnection, ...) as very appealing and i imagine other server side developers might feel the same way ... ... but desktop Java is gaining a support at the moment and i wonder how a future regime of removing deprecated APIs would effect its viability, given that deployment is already its biggest problem ... on the corporate desktop, which is a controlled environment, upgrades can be managed by technical staff, but their is no helpdesk for home users running browser based "Rich Internet Applications" and the sort of dekstop apps that get featured on www.java.com ... of course, if the JRE could automagically load older versions of classes using "legacy modules" with the end user knowing the difference, there would not be a problem ...

Deprecated APIs and Desktop Java Deployment.

The decision so far to keep every deprecated class and method forever effectively makes the entire idea of deprecating things one big joke.

Deprecation is meant to be a mechanism to mark APIs for future removal, if that removal never comes you could just as well not mark it as deprecated. Another annotation like "@PleaseDontUseInTheFutureAsINowThinkItWasABadIdeaToDoThis" would be more correct...

Users may be surprised to see ancient applications fail when updating their JVMs, but they're hardly unused to that. When upgrading their operating systems old applications also fail from time to time (or display unexpected behaviour). They're used to that, see it as either a reason to not upgrade their OS or a reason to upgrade their applications with their OS. The former group shouldn't be a problem for you as they're not potential customers for your new versions anyway, the latter group might not have been a customer but will be now.

All that's really required for people shipping Java applications is to not only list a minimum JVM version but also (if known) a maximum JVM version or a notice that the application can't be guaranteed to work in its current version on JVMs with a version of x.xx or higher.

And that would already be more than most software publishers do. They just tell the user that the system is tested on this and that version of the targeted operating system and that they're on their own if they want to use it on anything else. That too is accepted by endusers, so why should Java be special and aim to guarantee backwards compatibility into eternity?

What are we deprecating again?

I think it depends what are you deprecating.

If it's just a matter of a simple "instead of using this method, use that other method", I would tend to agree with the people that say to just remove it from the javadocs, but leave it in the runtime.

There is a much broader interpretation, though. Say we want to evolve a library, such as java.util.Date, or make Swing use Collections. How do we transition? Shall we leave the whole library there, for backward compatibility (do we actually deprecate it)? For these kinds of things, I agree with the people that support the module system: just say you depend on Java 7 instead of Java 8.

IMHO, the latter case is much more interesting. There are already enough cases in Java where I have to give an "historical perspective" to junior programmers when I want them to really understand why things are that way... I think that's where Java shows its signs of age (the evolution of io, collections, Swing, Thread, Generics, ...), not the fact that we have a few deprecated methods here and there...

Can the Java Module System (JSR 277) make History "History" ?

yes, i agree there are too many libraries in the JDK that only make sense with an "historical perspective" ... and that perspective should not be necessary when you have a job to do now ... an API should have a single self-consistent logical approach that speaks for itself ... in many areas (Java2D, Printing, Threads, AWT/Swing, Dates, etc ..) there are 2 or 3 complete ways to approach using the library ... newer approaches are generally better (having corrected mistakes of the past) but they are often built on older packages that must therefore still be included in the JRE ... so a lot of time can be wasted sorting out what to use and what to ignore ... it would be great to see the duplication removed, so the JDK provides one standard approach to each area ... and i agree, it would also be great for standard libraries to make use of improved APIs internally ... really fixing the JDK in this way would mean breaking backward compatibility in a really big way ... this will not be popular and i imagine there would be calls for compromise ... but that might do as much harm as good - in the past, with the noble intention of maintaining backward compatibility, new APIs were often wrapped around old ones or depended on older classes (eg. Swing extends AWT) but this practice has created the vast size, complexity and confused muliple approaches the same task that people now want to fix ... so the more i think about it, the more the proposed Java Module System (JSR 277) seems crucial to how well deprecation can be managed ... if it can address these issues, allowing deprecated classes/packages to be loaded in versioned legacy modules, then removing deprecated APIs can hopefully be done without messy compromises and without breaking backward compatibility ... and with Sun's Java now GPL, the time is right for "many eyes" to contribe to cleaning things up ... i really hope JSR 277 can deliver this - the opportunities seem really great ...

Proxy?

I wonder if the features could be removed (in such a way that they won't show up in (for instance) IDEs), but then use Proxy in some cunning way to make them available in some fashion.

If Proxy won't let you do that, maybe someone should hit it until it does (and then deprecate the old one... ;-0 )

Remove them from the Javadoc...

But keep them in the libraries. What would be nice is a 'show/hide deprecated APIs' link in the API documentation (something similar to the FRAMES - NO FRAMES links). In some cases it can be very difficult to get rid of deprecation warnings (e.g. you implement an interface that declares deprecated methods) - so I'm not sure that blindly turning deprecation warnings into errors in the compiler would work (pity).

Remove them from the Javadoc...

To eliminate the warnings when implementing a deprecated method, just mark your method as deprecated as well. You may also need to know about deprecated methods when extending a class which contains them.

Depends.

Some APIs features are so spectacularly bad they should be removed in an update release.

For the most part, you can't kill deprecated features, without running the risk of seriously annoying end-users. We have seen deprecated feature degrade in functionality. For instance old applets that use Thread.suspend are more likely to hang in 1.6 (because it uses the new j.u.c.l locks, as they were faster, but only in 1.5).

So what I suggest is that after one cycle, javac will not compile code using deprecated features. Piss the shoddy developers off instead of their unfortunate end-users. javac already does this for some com.sun classes (although it is very easy to work around).

Depends.

Some APIs features are so spectacularly bad they should be removed in an update release.

For the most part, you can't kill deprecated features, without running the risk of seriously annoying end-users. We have seen deprecated feature degrade in functionality. For instance old applets that use Thread.suspend are more likely to hang in 1.6 (because it uses the new j.u.c.l locks, as they were faster, but only in 1.5).

So what I suggest is that after one cycle, javac will not compile code using deprecated features. Piss the shoddy developers off instead of their unfortunate end-users. javac already does this for some com.sun classes (although it is very easy to work around).

Depends.

Some APIs features are so spectacularly bad they should be removed in an update release.

For the most part, you can't kill deprecated features, without running the risk of seriously annoying end-users. We have seen deprecated feature degrade in functionality. For instance old applets that use Thread.suspend are more likely to hang in 1.6 (because it uses the new j.u.c.l locks, as they were faster, but only in 1.5).

So what I suggest is that after one cycle, javac will not compile code using deprecated features. Piss the shoddy developers off instead of their unfortunate end-users. javac already does this for some com.sun classes (although it is very easy to work around).

Removing is good

Properly removing deprecated code is a good thing because it keeps the focus on on the new features not on the compatibility "mode". Systems get a mess after some time if you do not clean up. After some time of development your innovation speed drops to zero because you can not implement new things without breaking the compatibility. The JRE 1.4 for example broke lots of UI code with its new focus management. It was necessary to change it for further development and to make it right. I still use this old code with an old JRE, where is the problem? Most programs I use are far younger than the 3 years discussed and the rest runs with an old JRE.

Java Module System (JSR 277),

Move them to Java Module System (JSR 277) Do not trow them away. Some old timer till depend on that... Best choice is Java Module System (JSR 277). Java Module System (JSR 277)! Java Module System (JSR 277)! Java Module System (JSR 277)!

never remove deprecated elements

deprecated classes, methods, ... etc should not be removed, just we can change their implementation. for example if we have a method called fun1 which has been deprecated by another method called fun2 then we can change fun1 implementation to be void fun1(){ fun2(); } this can be done whenever possible, otherwise we can leave the deprecated methods as they are; this will help old applications to upgrade to newer JDKs

Automatic, Transparent, Remote Fetching and Loading of Classes i

having just taken a lot longer than expected to get my head around printing in the JDK, i am sure removing deprecated apis would make it simpler to learn new parts of the JDK ... great! ... but i never want software i have written and released to suddenly stop working ... no customer satisfaction there! ... so, if deprecated apis are removed, there needs to be a simple way for a newer JVM that load classes that use the deprecated apis to 1) recognize they it has done so, and 2) get the legacy versions it needs. i am no expert here, but i imagine the JVM could check the method signatures on classes in all packages in the JDK to determine if legacy versions are required. (would this cause unacceptably slow loading?) assuming a modular JDK becomes reality, if legacy versions are required, the JVM would request them remotely from Sun and download then in jars using the standard module system. if the internet is not accessable, the JVM would have to give intelligible notification to the user advising them that they need to connect to get the "update" ... the legacy jars would contain the original classes from an early version of the JDK compiled with that version of the JDK - these would be loaded instead of the newer versions. the extra download would be an inconvenience to the user, but once the correct version of the class had been obtained it would behave exactly as it did when the developer build and tested the app - that is crucial. although it might seem more appealing for the JVM to perform some transforming magic on loading classes converting them to use new APIs (saving a download and possibly doing some optimizations) that could introduce a whole range of potential bugs and subtle differences in behavior not experienced by the developer when they built and tested the original software ... i believe a well-know desktop operating system owed a lot of its instability to transforming itself to run in various backward compatibility modes ... i would hate the JVM to get the same reputation .. obviously, developers could use things like Jackpot to transform their own old source code to use new APIs as they develop new apps because they can compile, test and debug it before they is released ... i would really like to see cruft removed from the "core" JDK, but only if there is a simple, reliable and standard way for newer JVMs to automatically access the legacy versions of classes using the same module system used to access other "non-core" JDK components ... if it cannot be made automated and transparent to the user, the deprecated APIs should never be removed ... if it can, then why not remove deprecated APIs immediately? Does this sound feasible?

Why remove the code

You should only remove the code if there is specific substantial reasons to do so. Why break code if you don't have to. I predict that in a 100 years, the only code from today that still runs would be Java code. You could add compiler flags that turn deprecated warnings into errors.

Automated transforms of deprecated methods

Where it is possible to automatically transform use of a deprecated method or class, then an earlier removal could be contemplated. Perhaps after only one full release. When loading a classfile the JVM could check the version and if 'old' it could further check for use of deprecated items and apply the transform if found. The transforms could also be applied offline (to jar files or class file directories) and to source code. Deprecations for which no automatable transform exists should probably be kept indefinitely (or until we learn how to create a transform).

Automated transforms of deprecated methods

Where it is possible to automatically transform use of a deprecated method or class, then an earlier removal could be contemplated. Perhaps after only one full release. When loading a classfile the JVM could check the version and if 'old' it could further check for use of deprecated items and apply the transform if found. The transforms could also be applied offline (to jar files or class file directories) and to source code. Deprecations for which no automatable transform exists should probably be kept indefinitely (or until we learn how to create a transform).

Automated transforms of deprecated methods

I agree with this proposal, but preferably after two version than one. And when there is no automatic way to transform the old method to the new one, then do not delete the old method at all. But I think this should not be some sort of automatic thing. People should be aware that methods SHOULD be deleted after two full versions, if there is no "automatic" way to convert it to the recommended one , even if the deprecated method is harmful (I'm thinking of some old Thread methods). And for the notion of "automatic way" to convert, I propose a Jackpot thing, then the associated conversion scripts could be provided as a convenience.

Move this to a "legacy compatibility" module

I think the code should not be removed, but moved to a legacy module that would be different from the core module. This is applicable for classes or packages deprecated (old printing for instance) but not for methods (where the rest of the class has not been deprecated). Doing so, the "legacy module" implementation must use only the new core module implementation reainting backward compatibility. IE, the core module code will no mode be poluted with "legacy code" and would be 100% working without any legacy code. On a middle term perspective, Classes with more than 50% members deprecated (Date anybody ?) should be analysed and considered for full deprecation (moved to "legacy module") and replaced with new ones only integrating the new way of doing. This would be an opportunity to rethink way of doing certain things that are not consistent with the rest of the platform or have been done in an über-complex way (JNDI or JAAS anybody ?). So, javadoc should be by default only showing non deprecated things (core module). And a dedicated javadoc would show the legacy module. This way would retain the compatibility but would show a clear "red line" between legacy and recomanded ways. Any thoughts ?

Move this to a "legacy compatibility" module

I think the legacy module is a good idea.

Move this to a "legacy compatibility" module

The idea is very good, but maybe it would not be so easy to implement. Any ideas ?

Move this to a "legacy compatibility" module

This can be done simply implementing the upcoming JSR177 and moving all deprecated class to this dedicated legacy module. Nothing tricky (appart from JSR177 implementation I mean) ! I also agree with the proposition of hazem that indicates, deprecated methods staying in core module should be modified in order to have "legacy code only". This means, code accesing the new ways of doing. This will have positive (although minimal) performance impact for people not using deprecated API but without any sacrifice with the legacy ! Go legacy module :o)

Move this to a "legacy compatibility" module

Might work, but ONLY if attempting to compile anything in that module will lead to a compiler ERROR instead of a warning. Else we'll continue to see people use it in new code and not updating existing code.