Below you can see an image of the source code (in eclipse) where the warnings are occurring. I am new to this, and am therefore unaware of how to solve this.
Source code image
Thanks
Andrew
Your example of warnings is related to usage of deprecated classes.
If you have the need to use that deprecated class (for a big reason) in that case you can add this:
#SuppressWarnings( "deprecation" )
That will remove the warnings.
But, ... Here is big but...
You should to avoid usage of deprecated classes/methods because of every part which is marked as deprecated is marked as deprecated for a reason. For example, some code (method, class, etc) is marked as deprecated because it is planned to be removed, have better solution, works non-predictive or some other reason.
From other side, everything what is annotated as #Deprecated have to discourage all the programmers using it and try to implement his replacement or another solution.
Like Felix mentioned, hover over those "warnings/messages" and it will show you a hint.
In this case, you are calling a deprecated class:
https://developer.android.com/reference/android/support/v7/app/ActionBarActivity.html
Related
In my application lot of warnings are coming. For removing that warnings I'm using #SuppressWarnings annotations, anything would be happen in my code if I used several suppress warning annotations.
The #SuppressWarnings annotation does not change anything to the way your code works. The only thing it does is not make your compiler or IDE complain about specific warnings.
If you feel you need to use #SuppressWarnings a lot, then you should take a close look at why you get those warnings. It's a sign that you might be doing things incorrectly - you get warnings for a reason.
The #SuppressWarnings annotation disables certain compiler warnings. In this case, the warning about deprecated code ("deprecation") and unused local variables or unused private methods ("unused"). This article explains the possible values.
Depends on what warnings you are suppressing. If they are related to APIs that available only in new versions, your app will crash on older versions. Some warnings on the other hand are informational and point to common causes of bugs, so it really depends on what warning you are suppressing.
If you mean will my project break? or will it run slower most probably the answer is no. You can be fine suppressing warnings if they are trivial and you understand what are they signaling you and why are they there.
For example, an unused variable warning. Maybe you have defined it and plan to use in the near future, but the warning annoys you. Although I strongly suggest you to use a Source Code Version Control System like Git/Mercurial so you can safely delete code and recover a few days later.
But always check every warning you're suppressing: they are there for a purpose. For example, deprecated warnings: maybe your code runs fine, but in the next version of the JVM that deprecated method/class may have disappeared.
Always understand what you're doing
is it possible to suppress all warnings in IntelliJ for all unchanged lines? I am working in a project with java files larger than 2000 lines and there are warnings everywhere. To get a better overview of my code I want to only inspect my changed or added lines.
Summary from comment conversation:
Bad luck. Turning warnings off is the only solution (no one care about them anyway).
I don't think there is a way to do this. However, going forward you can use the annotation #SuppressWarnings( "unchecked" ) to suppress warnings that you do not care about. This does nothing for existing code unless you apply it to each warning (not what I would recommend), but will achieve the desired effect going forward.
We have a Java project. We enable -Xlint (enable warnings) and -Werror (treat warning as error) flags for javac, to make sure our code is warning-free. Recently we decide to deprecate a class. The problem is in some cases #SuppressWarnings("deprecation") will not suppress the deprecation warning at all, resulting in build failure. Below is a list of use cases that I ran into:
Imported in other non-deprecated classes.
Imported in other deprecated classes.
Parent class.
Type parameter. For example
#SuppressWarnings("deprecation")
public class Foo extends Bar<DeprecatedClass>
{ ... }
However, this one has no warning even without suppress:
#Deprecated
public class DeprecatedClass extends Bar<DeprecatedClass>
{ ... }
AFAIK, there is no syntax for annotating imports, so for case 1 and 2 our solution is to either import * or avoid importing. For case 3 and 4, both Java 6 and 7 do not suppress the warning. Java 8 will correctly suppress it (maybe a bug is fixed). So far no solution for this.
Unfortunately, we have to support Java 6, 7 and 8 at this point. Is there way to deal with the problem? It is a road block for our Java API evolution.
ADDENDUM
Many people ask why do we still use the deprecated class in our own codebase. The reason is that the project is a library, supporting many different clients. When introducing new replacement API, we have to first deprecate our old API, keep it in our codebase, wait for all clients to migrate then remove it. There are three common use cases:
We deprecate class Foo and Bar, where Foo extends Bar. This is the case 2 and 3 in my question.
We deprecate class Foo and Bar, where Foo extends Collection<Bar>. This is the case 2 and 4.
We must keep all test code for class Foo and Bar. The test code imports these classes. This is the case 1.
Why keep the test? Don't forget that if a serious bug (e.g. memory leak, security issue) is discovered, and the clients can't easily migrate to the new version, we still need to provide bug fix to the old API. And all changes must be tested.
I feel our situation should be fairly common in software library development and API evolution. Surprisingly it took Java such long time (until Java 8) to fix the bug.
I'm sorry to say that I don't have a solution to the problem you're facing, though as you've observed, there has been some progress. We've been trying to get rid of all the Java compilation warnings in the JDK itself, and this has been a long, difficult process. During JDK 8 development in 2011 I helped kick off the warnings cleanup effort and I later co-presented a JavaOne talk (slides and audio) on the subject.
More recently, my colleage Joe Darcy has continued the warnings cleanup work and has worked through the different warnings categories and has finally reached deprecation warnings. As you noted, there have been some bugs in the compiler's handling of suppression of deprecation warnings, such as JDK-6480588 which was fixed in JDK 8. Unfortunately, it is still not possible in JDK 8 to suppress warnings on imports of deprecated items. This bug, JDK-8032211, was fixed quite recently in our JDK 9 development line. In fact, we're still tuning up the handling of the #Deprecated annotation. For example, bug JDK-6481080 clarifies that attempting to use #Deprecated in a package-info.java file does not in fact deprecate the package; this bug was fixed just last week. And there is more work to be done but it's somewhat speculative at this point.
The JDK is facing similar problems to yours, in that we have to maintain deprecated APIs for clients that are still using them. But since we use and implement such APIs internally, we have a lot of deprecation warnings to suppress. As of this writing, in our JDK 9 development line, we still have not been able to compile the system without deprecation warnings. As a result, the javac options for lint warnings are still:
-Xlint:all,-deprecation
You will probably have to disable deprecation warnings in your compilation as well, especially if you are still building on JDK 6. I don't see a way around it at this point.
One final note on one of your deprecation cases:
#Deprecated
public class DeprecatedClass extends Bar<DeprecatedClass> { ... }
This does not issue a deprecation warning, nor should it. The Java Language Specification, section 9.6.4.6, specifies that deprecation warnings are not issued if the use of a deprecated entity is within an entity that is itself deprecated.
Consider using -Xmaxwarns, you can control how many warnings before stop.
Or try collect the number of warnings and fail the integration process, not compiling.
For example: https://issues.apache.org/jira/browse/HADOOP-11252.
Every code commit to the hadoop project need to pass the automated CI and it give -1 for increase number of warnings.
Normally, when you deprecate class, you don't want anybody to use it in later versions. Also, YOUR codebase should stop using deprecated class too. It looks strange, when you say everybody not to use MySuperDeprecatedUtil class but continue using it in your codebase.
If you need to use your MySuperDeprecatedUtil class in some other class - you should mark class where you use it as #Deprecated - every class that used deprecated code should be either deprecated, or would produce compilation warnings, or should be removed, or should stop using deprecated code.
If you can't stop using your class - maybe it's too early to deprecate it?
In my practice, when I want to deprecate some class, I create replacement class e.g. MySuperFreshUtil. Switch all classess using MySuperDeprecatedUtil to MySuperFresh util preserving interfaces where possible(if not possible - use FQCN and mark method as deprecated). Mark MySuperDeprecatedUtil as #Deprecated and add comment which class and how should be used instead. Then I commit this changes in single changelist.
I would like to mark usage of certain methods provide by the JRE as deprecated. How do I do this?
You can't. Only code within your control can have the #Deprecated annotation added. Any attempt to reverse engineer the bytecode will result in a non-portable JRE. This is contrary to Java's write once, run anywhere methodology.
you can't deprecate JRE methods, but you can add warnings or even compile errors to your build system i.e. using AspectJ or forbid the use of given methods in the IDE.
For example in Eclipse:
Go to Project properties -->Java Compiler --> Errors Warnings, Then enable project specific settings, Expand Deprecated and restrited APIs category
"Forbidden reference (acess rule)"
Obviously you could instrument or override the class adding #Deprecated annotation, but it's not a clean solution.
Add such restrictions to your coding guidelines, and enforce as part of your code review process.
You only can do it, if and only if you are building your own JRE! In that case just add #Deprecated above the corresponding code block! But if you are using Oracle's JRE, you are no where to do so!
In what context? Do you mean you want to be able to easily configure your IDE to inhibit use of certain API? Or are you trying to dictate to the world what APIs you prohibit? Or are you trying to do something at runtime?
If the first case, Eclipse, and I assume other IDEs, allow you to mark any API as forbidden, discouraged, or accessible at the package or class level.
If you mean the second, you can't, of course. That would be silly.
If you are trying to prohibit certain methods from being called at runtime, you can configure a security policy to prevent code loaded from specified locations from being able to call specific methods that check with the SecurityManager, if one is installed.
You can compile your own version of the class and add it to the boot class path or lib/ext directory. http://docs.oracle.com/javase/tutorial/ext/basics/install.html This will change the JDK and the JRE.
In fact you can remove it for compiling and your program won't compile if it is used.
Snihalani: Just so that I get this straight ...
You want to 'deprecate methods in the JRE' in order to 'Making sure people don't use java's implementation and use my implementation from now on.' ?
First of all: you can't change anything in the JRE, neither are you allowed to, it's property of Oracle. Uou might be able to change something locally if you want to go through the trouble, but that 'll just be in your local JRE, not in the ones that can be downloaded from the Oracle webpage.
Next to that, nobody has your implementation, so how would we be able to use it anyway? The implementations provided by Oracle do exactly what they should do, and when a flaw/bug/... is found it'll be corrected or replaced by a new method (at which point the original method becomes deprecated).
But, what mostly worries me, is that you would go and change implementations with something you came up with. Reminds me quite lot of phishing and such techniques, having us run your code, without knowing what it does, without even knowing we are running your code. After all, if you would have access to the original code and "build" the JRE, what's to stop you from altering the code in the original method?
Deprecated is a way for the author to say:
"Yup ... I did this in the past, but it seems that there are problems with the method.
just in order not to change the behaviour of existing applications using this method, I will not change this method, rather mark it as deprecated, and add a method that solves this problem".
You are not the author, so it isn't up to you to decide whether or not the methods work the way they should anyway.
We're trying to move our very large codebase from Guava 11 to Guava 14 and would like to catch uses of removed or deprecated APIs. Can FindBugs perform such checking? If so, how?
One solution would be to just use Oracle's Java compiler javac to do this.
Removed methods in the API would result in compiler errors if they are used so it should be possible to find these by compiling the code.
Deprecated methods can be found using the javac -deprecation option. More on -deprecation here:
http://docs.oracle.com/javase/6/docs/technotes/tools/windows/javac.html
You could also use PMD Sourceforge for this task. There are rules out there that let you find deprecated methods
One aspect that I believe javac will not cover is if you cannot change the 3rd party code to add #Deprecated annotations. If you just want to avoid a method which has not been marked as deprecated, you can use this plugin I wrote for FindBugs:
https://github.com/Grundlefleck/FindBugs4Deprecating3rdParty
There's very little documentation, so you may need to explore a little yourself. It allows configuring methods and classes to avoid in a properties file. I use it to deprecate org.junit.Assert.assertThat.