Will using deprecated classes cause severe problems to the program?
What is the meaning of deprecated?
Can I still work with deprecated classes?
An example for it is the ProgressDialog view in Android. It deprecated from API 26 and the replacement is the ProgressBar view. What happens if I will still use the ProgressDialog? It is extremely comfortable and exactly what I was aiming for.
From the documentation:
A program element annotated #Deprecated is one that programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists. Compilers warn when a deprecated program element is used or overridden in non-deprecated code.
So you can use some deprecated methods but it won't be the best practice because there are better alternative exists(but in some cases this can even be dangerous)
Yes and no. You can use them for maintaining old API levels, tacking into account that in newer android versions these classes may be removed. So usually you would wrap its usage in a if/else condition to use them only to maintain such functionality in old Android versions, only when there is no compatible replacement in newer versions.
Google has a bad habit of not maintaining back-compatibility which is an essential best practice in computer science and technology. I appreciate that deprecated means there are better alternatives and the comment "In theory, the deprecated libraries you are using should be supported indefinitely. However, the Google Play Store may at some point not support your API level, which means you might not be able to keep updating your app." is very pertinent. API level should be able to continue supporting those "deprecated" classes. I am very sure many of us can find several examples where so called "deprecated" are much better than their "updated" alternatives.
MapMaker maximumSize in google guava library is marked as #Beta. It's a very useful feature to set the maximum size when you use it as a cache and I would like to use it in production code. From experience with other google products beta can be pretty solid. Anyone know why it's a #Beta?
It is used in production at Google and there are no immediate plans on API changes. There is consensus to support weighted entries and we'll likely continue to evolve the algorithm to be closer to ConcurrentLinkedHashMap's. In this case #Beta is just to indicate that the method contract isn't officially set in stone.
From the javadoc:
Signifies that a public API (public class, method or field) is subject to incompatible changes, or even removal, in a future release. An API bearing this annotation is exempt from any compatibility guarantees made by its containing library.
So it doesn't mean it's questionable quality, or unsuitable for production use, they just reserve the right to change it later.
If your project is an end application that is not intended to be embedded in other peoples' applications, then anything with #Beta is totally safe to use. The API may change later and IMO the greatest risk you run is that you might have to change your code a little bit because a method signature changed.
If, on the other hand, you are developing some sort of framework where you expect your project will be on the classpath of many clients, you probably want to avoid #Beta. You never know if your clients will have a different version of Guava on the classpath -- in which case unpredictable things can happen.
ColinD explains this best here: Best Way To Use Guava
edit: Ah yes, and to answer your specific question of why call it #Beta -- it's just to document this fact that MapMaker maximumsize is still subject to change in the next release (It's not that the code is thought to be flaky, unstable, or unsuitable for production)
It seems like every java project I join or start on always has commons-lang as a dependency - and for good reason. commons-lang has tons of classes and utility methods that are pretty standard fair with the most standard APIs in other languages. Why hasn't Sun/Oracle/JCP adopted some of the things in commons-lang in to the standard api?
As pointed out already, some features in the commons API have made it into Java, often implemented (IMHO) better than they were originally in the commons library. Enums is the classic example.
In terms of why they don't adopt more of commons-lang, well with some classes there's the element of confusion. Take StrBuilder for example, it's more powerful than the Java StringBuilder and it's extensible. But I'm not sure I'd be for adding such a class into the Java core API, StringBuilder/StringBuffer are perfectly good enough for most purposes and having another one in there would really just become a bit confusing. They couldn't really alter StringBuilder in a way that would accommodate all of the changes either because that could break existing code. Even if they did add one, what about when someone else came along with another more powerful version? StrBuilder2? Before long everything's a big mess (some argue that the core API is already, let alone with such additions.)
And as always with these things, the big point is what should be included from commons-lang. Some people would probably want to see the MutableXXX classes added, others the XXXUtils classes, others the time package... there isn't really a common consensus.
The other big thing is that the Java developers have to be a lot more careful what goes in the core Java API than the Apache developers do for commons-lang. If a crappy design in commons-lang is superseded in a future release, the old one can be deprecated and subsequently removed (indeed this seems to be what happens.) In the core Java API it needs to stay for backwards compatibility reasons, just causing more clutter.
For what it's worth though I do think more of the functionality in commons-lang should probably be included. I can just see the reasons, at least in part, why it's not.
Historically Apache Commons implemented some of the features that later were introduced in Java 5, such as enums and annotations. Their implementation was sufficiently different to make integration difficult.
I am using eclipse to develop a web application. Just today I have updated my struts version by changing the JAR file. I am getting warnings at some places that methods are deprecated, but the code is working fine.
I want to know some things
Is it wrong to use Deprecated methods or classes in Java?
What if I don't change any method and run my application with warnings that I have, will it create any performance issue.
1. Is it wrong to use Deprecated methods or classes in Java?
From the definition of deprecated:
A program element annotated #Deprecated is one that programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists.
The method is kept in the API for backward compatibility for an unspecified period of time, and may in future releases be removed. That is, no, it's not wrong, but there is a better way of doing it, which is more robust against API changes.
2. What if I don't change any method and run my application with warnings that I have, will it create any performance issue.
Most likely no. It will continue to work as before the deprecation. The contract of the API method will not change. If some internal data structure changes in favor of a new, better method, there could be a performance impact, but it's quite unlikely.
The funniest deprecation in the Java API, is imo, the FontMetrics.getMaxDecent. Reason for deprecation: Spelling error.
Deprecated. As of JDK version 1.1.1, replaced by getMaxDescent().
You can still use deprecated code without performance being changed, but the whole point of deprecating a method/class is to let users know there's now a better way of using it, and that in a future release the deprecated code is likely to be removed.
Terminology
From the official Sun glossary:
deprecation: Refers to a class, interface, constructor, method or field that is no longer recommended, and may cease to exist in a future version.
From the how-and-when to deprecate guide:
You may have heard the term, "self-deprecating humor," or humor that minimizes the speaker's importance. A deprecated class or method is like that. It is no longer important. It is so unimportant, in fact, that you should no longer use it, since it has been superseded and may cease to exist in the future.
The #Deprecated annotation went a step further and warn of danger:
A program element annotated #Deprecated is one that programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists.
References
java.sun.com Glossary
Language guide/How and When to Deprecate APIs
Annotation Type Deprecated API
Right or wrong?
The question of whether it's right or wrong to use deprecated methods will have to be examined on individual basis. Here are ALL the quotes where the word "deprecated" appears in Effective Java 2nd Edition:
Item 7: Avoid finalizers: The only methods that claim to guarantee finalization are System.runFinalizersOnExit and its evil twin Runtime.runFinalizersOnExit. These methods are fatally flawed and have been deprecated.
Item 66: Synchronize access to shared mutable data: The libraries provide the Thread.stop method, but this method was deprecated long ago because it's inherently unsafe -- its use can result in data corruption.
Item 70: Document thread safety: The System.runFinalizersOnExit method is thread-hostile and has been deprecated.
Item 73: Avoid thread groups: They allow you to apply certain Thread primitives to a bunch of threads at once. Several of these primitives have been deprecated, and the remainder are infrequently used. [...] thread groups are obsolete.
So at least with all of the above methods, it's clearly wrong to use them, at least according to Josh Bloch.
With other methods, you'd have to consider the issues individually, and understand WHY they were deprecated, but generally speaking, when the decision to deprecate is justified, it will tend to lean toward wrong than right to continue using them.
Related questions
Difference between a Deprecated and Legacy API?
Aside from all the excellent responses above I found there is another reason to remove deprecated API calls.
Be researching why a call is deprecated I often find myself learning interesting things about the Java/the API/the Framework. There is often a good reason why a method is being deprecated and understanding these reasons leads to deeper insights.
So from a learning/growing perspective, it is also a worthwhile effort
It certainly doesn't create a performance issue -- deprecated means in the future it's likely that function won't be part of the library anymore, so you should avoid using it in new code and change your old code to stop using it, so you don't run into problems one day when you upgrade struts and find that function is no longer present
It's not wrong, it's just not recommended. It generally means that at this point there is a better way of doing things and you'd do good if you use the new improved way. Some deprecated stuff are really dangerous and should be avoided altogether. The new way can yield better performance than the deprecated one, but it's not always the case.
You may have heard the term, "self-deprecating humor". That is humor that minimizes your importance. A deprecated class or method is like that. It is no longer important. It is so unimportant, in fact, that it should no longer be used at all, as it will probably cease to exist in the future.
Try to avoid it
Generally no, it's not absolutely wrong to use deprecated methods as long as you have a good contingency plan to avoid any problems if/when those methods disappear from the library you're using. With Java API itself this never happens but with just about anything else it means that it's going to be removed. If you specifically plan not to upgrade (although you most likely should in the long run) your software's supporting libraries then there's no problem in using deprecated methods.
No.
Yes, it is wrong.
Deprecated methods or classes will be removed in future versions of Java and should not be used. In each case, there should be an alternative available. Use that.
There are a couple of cases when you have to use a deprecated class or method in order to meet a project goal. In this case, you really have no choice but to use it. Future versions of Java may break that code, but if it's a requirement you have to live with that. It probably isn't the first time you had to do something wrong in order to meet a project requirement, and it certainly won't be the last.
When you upgrade to a new version of Java or some other library, sometimes a method or a class you were using becomes deprecated. Deprecated methods are not supported, but shouldn't produce unexpected results. That doesn't mean that they won't, though, so switch your code ASAP.
The deprecation process is there to make sure that authors have enough time to change their code over from an old API to a new API. Make use of this time. Change your code over ASAP.
It is not wrong, but some of the deprecated methods are removed in the future versions of the software, so you will possibly end up with not working code.
Is it wrong to use Deprecated methods or classes in Java?"
Not wrong as such but it can save you some trouble. Here is an example where it's strongly discouraged to use a deprecated method:
http://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
Why is Thread.stop deprecated?
Because it is inherently unsafe.
Stopping a thread causes it to unlock
all the monitors that it has locked.
(The monitors are unlocked as the
ThreadDeath exception propagates up
the stack.) If any of the objects
previously protected by these monitors
were in an inconsistent state, other
threads may now view these objects in
an inconsistent state. Such objects
are said to be damaged. When threads
operate on damaged objects, arbitrary
behavior can result. This behavior may
be subtle and difficult to detect, or
it may be pronounced. Unlike other
unchecked exceptions, ThreadDeath
kills threads silently; thus, the user
has no warning that his program may be
corrupted. The corruption can manifest
itself at any time after the actual
damage occurs, even hours or days in
the future.
What if don't change any method and run my application with warnings that I have, will it create any performance issue.
There should be no issues in terms of performance. The standard API is designed to respect some backward compatibility so applications can be gradually adapted to newer versions of Java.
Is it wrong to use Deprecated methods or classes in Java?
It is not "wrong", still working but avoid it as much as possible.
Suppose there is a security vulnerability associated with a method and the developers determine that it is a design flaw. So they may decide to deprecate the method and introduce the new way.
So if you still use the old method, you have a threat. So be aware of the reason to the deprecation and check whether how it affects to you.
what if don't change any method and run my application with warnings that I have, will it create any performance issue.
If the deprecation is due to a performance issue, then you will suffer from a performance issue, otherwise there is no reason to have such a problem. Again would like to point out, be aware of the reason to deprecation.
In Java it's #Deprecated, in C# it's [Obsolete].
I think I prefer C#'s terminology. It just means it's obsolete. You can still use it if you want to, but there's probably a better way.
It's like using Windows 3.1 instead of Windows 7 if you believe that Windows 3.1 is obsolete. You can still use it, but there's probably better features in a future version, plus the future versions will probably be supported - the obsolete one won't be.
Same for Java's #Deprecated - you can still use the method, but at your own risk - in future, it might have better alternatives, and might not even be supported.
If you are using code that is deprecated, it's usually fine, as long as you don't have to upgrade to a newer API - the deprecated code might not exist there. I suggest if you see something that is using deprecated code, to update to use the newer alternatives (this is usually pointed out on the annotation or in a Javadoc deprecated comment).
Edit: And as pointed out by Michael, if the reason for deprecation is due to a flaw in the functionality (or because the functionality should not even exist), then obviously, one shouldn't use the deprecated code.
Of course not - since the whole Java is getting #Deprecated :-) you can feel free to use them for as long as Java lasts. Not going to notice any diff anyway, unless it's something really broken. Meaning - have to read about it and then decide.
In .Net however, when something is declared [Obsolete], go and read about it immediately even if you never used it before - you have about 50% chance that it's more efficient and/or easier to use than replacement :-))
So in general, it can be quite beneficial to be techno-conservative these days, but you have to do your reading chore first.
I feel that deprecated method means; there is an alternate=ive method available which is better in all aspects than existing method. Better to use the good method than existing old method. For backward compatibility, old methods are left as deprecated.
I'm in the process of reviewing a code base (~20K LOC) and trying to determine how to migrating it from 1.4.2 to 5. Obviously, it's not an overnight project and the suggestion which I have received is to write new code against Java 5 and migrate the old code in a piece-meal fashion. Also, I'm no expert in the new features in Java 5 (i.e. I know of them, but have never written any for production use).
My questions:
What features of Java 5 are typically used in production code? (i.e. generics, auto-boxing, etc.) Are there features to be avoided / not considered to be best-practices?
What are the best refactoring strategies which I can use migrate a code base of this size? (i.e. make changes to classes one at a time only when a class is edited, etc.) Objective - reduce risk on the code base. Limitation - resources to do refactoring.
Any advice is appreciated - thanks in advance.
UPDATE - a year too late, but better late than never? =)
Thank you for all of the comments - lots of great points of view. In the life of a software developer, there's always going to be the projects you strive to finish but never get around to because of something more "urgent".
With respect to the use of Java 5 (at that time), it was something which was required in the client's production environment, so that was why we did not use Java 6.
I found that the stronger typing for collections, enums and unboxing of primitives were the features I tend to apply the most, both to old and new code. The refactoring was fairly straight-forward, but code comprehension improved significantly and standards became easier to enforce. The ones I had the most trouble with was the generics; I think it's a concept which I still haven't had a chance to fully grasp and appreciate yet, so it was difficult for me to find previous cases where the application of generics was appropriate.
Thanks again to everyone who contributed to this thread and apologies for the late follow up.
Java 5 is almost completely backwards compatible with Java 4. Typically, the only change you must make when you migrate is to rename any usages of the new enum keyword in the Java 4 code.
The full list of potential compatibility problems is listed here:
http://java.sun.com/j2se/1.5.0/compatibility.html
The only other one that I've run into in practice is related to the change in the JAXP implementation. In our case, it simply meant removing xerces.jar from the classpath.
As far as refactoring goes, I think that migrating your collection classes to use the new strongly-typed generic versions and removing unnecessary casting is a good idea. But as another poster pointed out, changing to generic collections tends to work best if you work in vertical slices. Otherwise, you end up having to add casting to the code to make the generic types compatible with the non-generic types.
Another feature I like to use when I'm migrating code is the #Override annotation. It helps to catch inheritance problems when you're refactoring code.
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Override.html
The new concurrency library is very useful if your code uses threading. For example, you may be able to replace home-grown thread pools with a ThreadPoolExecutor.
http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html#concurrency
I would definitely take the approach of updating the code as you change it during normal maintenance. Other than the compatibility issues, I don't think there is a compelling reason to use the new Java 5 features unless you're already changing the code for other reasons.
There is one very real issue with the "viral" nature of generics; once you start introducing them at a given layer in an architecture you generally want to introduce it at the layer above & below as well. I have found that introducing generics is probably best done in full "verticals". But you do not have to do all the verticals at once.
This is a really hard question to answer because it depends on what code will be affected and how critical that code is.
First and foremost, when migration is a nontrivial undertaking, do yourself a favour and upgrade to the latest version of Java, which would be Java 6 not Java 5. Java 6 has been out for a year and a half or more and is mature. There's no reason to not pick it over Java 5 (imho).
Secondly, like any software project, your goal should be to get something into production as soon as you possibly can. So you need to identify a slice of your system. The smaller the better, the more non-cdritical, the better.
The other thing to do is just try starting up your app under Java 6 and seeing what breaks. It might be worse than you expected. It might be much better.
The other thing you'll probably need to be aware of is that by the sounds of it you will have jars/libraries in your app that have since been deprecated. Some may not even be compatible with Java beyond 1.4.2. You will probably want to upgrade all of these to the latest version as well.
This will probably mean more stuff breaking but using old/deprecated APIs is just kicking the can down the street and causes you other problems.
There are exceptions to this where upgrading can have far-reaching consequences. Axis1 to Axis2 comes to mind. Those situations require more careful thought.
As for what features are used... all of them pretty much. I can't think of any that should be avoided off the top of my head.
Also, I just noticed the size of your project: ~20K LOC. That's actually quite small (eg I've written an app about that size in the last 3 months by myself).
Lastly, this also depends on how easily you will find things that break. If you have good unit test coverage then great. That's pretty rare though. If you can just run through the app and reliably find problems it's not too bad.
The problematic situations are where scenarios are hard to test and it's likely you won't uncover problems straight away. That calls for more caution.
You would want to migrate stuff that doesn't work in the transition from 1.4 to 5 (not sure what that would be), but I'd be wary of migrating stuff for the sake of it.
If you do take this route, some questions:
Do you have comprehensive test coverage ? If not, you should write unit tests for the code you're going to be migrating.
Do you have components that are widely used within your codebase ? If so, they are probably candidates to be migrated in terms of their API (e.g. using generics etc.)
In terms of what's widely used from Java 5. Generics is important and makes your life a lot easier. I don't see autoboxing too much, nor enums (this is all relative). Varargs almost never. Annotations are useful for frameworks, but I consume these. I don't think I've ever implemented one myself.
20 (non-comment) kloc should be small enough to insert generics with a big bang. Obviously make sure your code compiles an runs on Java SE 5 first. The relatively easy thing about generics is that adding them makes very little change to semantics (certain overloadings can change because of implicit cases - Iterator<char[]> iter; ... System.out.println(iter.next()); as a bad example off the top of my head).
Some cases adding generics will highlight conceptual problems with the code. Using one Map as two maps with disjoint key sets, for example. TreeMap is an example in the Java library where a single class has two distinct mode (using Comparator<T> or Comparable<T>).
Things like enhanced-for and auto-boxing are very local and can be added piecemeal. enums are rarer and might take some thinking about how you are actually going to use them.
I think you're going about this the wrong way. Your plan shouldn't be to update all current code to Java 1.5, your plan should be to ensure that all current code runs exactly the same in 1.5 as it did in 1.4.2, and that all future code written will work fine in 1.5.
I've gone through a few transitions like this of varied sized code bases. The goal was always to make sure we had a ton of unit tests so that we could easily plug in 1.5 and run our tests through it. We actually encountered about 10 problems, mostly related to regular expression libraries not supporting something or supporting something differently.
Write all new code in 1.5 then, and if you change an older class for whatever reason, spend a minute and implement generics, but there's no reason to refactor everything. That sounds a bit dangerous to me if you don't have the tests in place.