Will deprecated items in Java be removed - java

We know that there are several deprecated items in Java.
Will they be removed?
Have any deprecated items ever been removed from Java?

Will they be removed?
Unlikely since java has always been about maintaining backward compability, but it can happen. I see deprecations as a warning that the API is either unreliable or somehow seriously flawed.
(Thread has several of these).
Has any of the deprecated items in the past has been removed from java?
AFAIC not removed but never implemented Thread.destroy(), as it was along with several other Thread methods inherently unsafe.

This question has been asked elsewhere.
Quite frankly, what the Java team usually do, is to deprecate the method and remove its implementation to the suggested method instead. The deprecated method is just an unimplemented method.

According to the documentation here.
You can see that it says
A program element annotated #Deprecated is one that programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists.
So a deprecated method or class is basically a older method or class that is discouraged from being used as there are newer more logical ways to perform that action.
Will these methods ever be removed?
Probably not. It will continue to work as before the deprecation, you just have to deal with the pesky warning. In order to keep older programs still running correctly that aren't being updated, almost all deprecated classes and methods won't be removed solely for that reason.
Deprecated APIs are interfaces that are supported only for backwards compatibility. The javac compiler generates a warning message whenever one of these is used, unless the -nowarn command-line option is used. It is recommended that programs be modified to eliminate the use of deprecated APIs, though there are no current plans to remove such APIs – with the exception of JVMDI and JVMPI – entirely from the system.
Have any deprecated items been removed?
In the java.* class, no. There have been a few changes in the javax.* class but in regular java there has never been a deprecated method or class removed.

Related

what else we can use instead of import com.sun.management.OperatingSystemMXBean as this import is giving me Sonar issue

Due to project sec. issues . Not allowed to use com.sun.management.OperatingSystemMXBean . Instead i am trying to use java.lang.management.OperatingSystemMXBean . But in my method i need to know the cpuLoad (getSystemCpuLoad) . how can i get the same using lang.management ? is there any method present in java. lang.* to get the systemcpuLoad ?
I don't think there is an alternative. At least not in the standard Java SE class libraries1.
Not all com.sun.* packages are considered to be closed APIs. In this case the javadocs include this interface. I take that as an implicit statement that this is an open API.
If this is just the generic warning from SonarQube that you shouldn't depend on com.sun.* and sun.* APIs (see RSPEC-1191), my advice is to suppress the warning for this particular case.
I don't see how this is a project "security" issue. Please explain why you think that.
Okay. Let me put my question in this way : How to getSystemCpuLoad method in java.lang.management.OperatingSystemMXBean.
One way is just like your current code (presumably) does. Cast the MXBean instance to a com.sun.management.OperatingSystemMXBean and call the method. (And suppress the SonarQube warning.)
The one thing to note is that the getSystemCpuLoad method is marked as deprecated in Java 17. You should now use getCpuLoad instead.
1 - If you found and used a 3rd-party library2 that provides this functionality, or it you implemented your own (in native code, for example), I think you will be making the problem worse. Now you have an extra dependency to track or extra code to maintain. Bear in mind that the implementation of this functionality is OS specific, so you would need to find or write an implementation that works on all of your platforms, both now and in the future.
2 - Beware of posts that suggest using the SIGAR library. It hasn't been updated in a long time, and there are reports that its problematic on some platforms.

How to use the HotSpot JVM #DontInline annotation?

I'm currently working on optimizing a particular method, which is unfortunately inlined by the JVM, which prevents it from being properly vectorized. I've noticed that there is an annotation to forbid inlining, namely jdk.internal.vm.annotation.DontInline . However, it cannot be accessed from the default module.
Is there a clean way of gaining access to this annotation or to prevent the inlining of the offending method some other way?
DontInline, ForceInline, etc. are JDK internal annotations, they cannot be applied to user code. Even if you somehow manage to open these annotations, HotSpot JVM has an explicit check to disallow them for non-privileged classes.
The reasons are understandable. These annotations are the implementation detail of the particular JVM version; JDK developers are free to add/remove/change meaning of such annotations without notice, even in a minor JDK update.
Using #DontInline to force vectorization does not seem a good approach anyway. In general, inlining should not prevent from other optimizations. If you encounter such problem, it's better to report an issue on hotspot-compiler-dev mailing list.
Now the good news.
Since JDK 9, there is a public supported API to manually tune JIT compiler. This is JEP 165: Compiler Control.
The idea is to provide compiler directives in a separate JSON file, and start the JVM with -XX:CompilerDirectivesFile=<file> option. If your application is sensitive to certain compiler decisions, you may provide the directives file along with the application.
{
match: "*::*",
inline: "-org/package/MyClass::hotMethod"
}
It is even possible to apply compiler directives programmatically in runtime using DiagnosticCommand API:
ManagementFactory.getPlatformMBeanServer().invoke(
new ObjectName("com.sun.management:type=DiagnosticCommand"),
"compilerDirectivesAdd",
new Object[]{new String[]{"compiler.json"}},
new String[]{"[Ljava.lang.String;"}
);
By the way, there is Vectorize: true option among the directives list, which may probably help in vectorizing the particular method.

Marking indirect usages of classes, methods etc

Is there a standard way in Java to mark classes, methods etc. that are used by other parts of the program in indirect ways (think: reflection) which are not discoverable by the usual search-functions of IDEs?
In one particular example I have a bunch of classes with a couple of hundred small validation methods. Validation occurs basically by listing all methods of those classes via reflection and executing one by one them on the given object. (It's more complicated than that, but that's the underlying idea)
Now my IDE understandably marks each and everyone of those methods as "unused" because there are never directly called, only via reflection.
A similar problem occurs in another part of the program where several dozen helper classes reside, some of which are almost certainly unused and could be deleted. But: In some rare cases the fields of these classes are accessed via reflection and the usual search functions of the IDE cannot find these usages (again: very understandably so).
I know that it is impossible for the IDE to solve this problem without outside help. Hence my question whether there are already established ways like annotations for example to clearly mark these cases. Of course I could define such an annotation myself, but I'd rather go with an accepted standard if one exists.
Is there even an IDE that can recognise them and warn me automatically if I'm doing stuff like that?
No, there is not a standard way to mark indirect control flow (reflection, Android intents, callbacks, etc.).
There are some tools that provide their own ways to analyze indirect control flow.
For example, the Checker Framework's reflection resolution uses the #MethodVal annotation to indicate the possible targets of a reflective invocation. It also has ways to indicate Android intents.
You typically annotate those classes with #SuppressWarnings("unused") to get rid of IDE warnings

What does a striked through method means in Eclipse?

I'm using Eclipse to develop a Java program. But in my program I have some methods in Eclipse which are striked through. What does it mean ?
It means that your method are deprecated. You may find another way to do the same thing
All those methods/class which eclipse found start with #Deprecated annotation is displayed with a strike through.
A method is made deprecated to discourage the user/client of the method not to use it. Because this method might be remover from the later release of the API/package. In this case the there may be an alternative method to use. A good java doc should contains what to use in alternate of the deprecated method.
It is a deprecated method. 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.

Is it possible to redefine core JDK classes using instrumentation?

I want to redefine the bytecode of the StackOverflowError constructor so I have a "hook" for when a stack overflow occurs. All I want to do is insert a single method call to a static method of my choosing at the start of the constructor. Is it possible to do this?
You should be able to do it using one of two ways (unless something changed in the last 1-2 years, in which case I'd love some links to changelogs/docs):
Mentioned in a comment, not very feasible I guess, modify the classes you are interested in, put them in a jar and then use the -bootclasspath option to load them instead of the default ones. As was mentioned before this can have some legal issues (and is a pain to do in general).
You should be able to (or at least you used to be able to) instrument almost all core classes (iirc Class was the only exception I've seen). One of many problems you might have is the fact that many of core classes are being initialized before the agents you provide (or well their premain methods to be exact) are consulted. To overcome this you will have to add Can-Retransform-Classes property to your agent jar and then re-transform the classes you are interested in. Be aware that re-transformation is a bit less powerful and doesn't give you all the options you'd have normally with instrumentation, you can read more about it in the doc.
I am assuming you know how to do instrumentation?
There are several things to consider.
It is possible to redefine java.lang.StackOverflowError. I tried it successfully on 1.7.0_40. isModifiableClass(java.lang.StackOverflowError.class) return true and I successfully redefined it inserting a method invocation into all of its constructors
You should be aware that when you insert a method call into a class via Instrumentation you still have to obey the visibility imposed by the ClassLoader relationships. Since StackOverflowError is loaded by the bootstrap loader it can only invoke methods of classes loaded by the bootstrap loader. You would have to add the target method’s class(es) to the bootstrap loader
This works if the application’s code throws a StackOverflowError manually. However, when a real stackoverflow occurs, the last thing the JVM will do is to invoke additional methods (keep in mind what the error says, the stack is full). Consequently it creates an instance of StackOverflowError without calling its constructor (a JVM can do that). So your instrumentation is pointless in this situation.
As already pointed out by others, a “Pure Java Application” must not rely on modified JRE classes. It is only valid to use Instrumentation as add-on, i.e. development or JVM management tool. You should keep in mind that the fact that Oracle’s JVM 1.7.0_40 supports the redefinition of StackOverflowError does not imply that other versions or other JVMs do as well.

Categories

Resources