Java code from https://github.com/forcedotcom/wsc contains some deprecated code to create new instances
Transport is an interface
public interface Transport {
}
......
Transport t = (Transport) config.getTransport().newInstance();
t.setConfig(config);
return t
methods that I have tried to fix by using
Transport t = (Transport) config.getTransport().getDeclaredConstructor().newInstance();
t.setConfig(config);
return t
This creates a warning "Unchecked call to getDeclaredConstructor(Class..) as a member of raw type 'java.lang.Class' '
I am looking for a better way to fix this deprecated call.
This code was not written by me. It provides a Java SOAP connection to Salesforce.com. I have written my own code to use it with Java 8, however, I thought it would be useful to update the code to work with Java 9+
Thanks for the excellent suggestions
I have applied the recommendations in the following way to make it a little easier to read
Class<?> transClass = config.getTransport();
Transport t = (Transport) transClass.getDeclaredConstructor().newInstance();
t.setConfig(this);
There are two further aspects that need to be considered when following the recommendation in the Javadoc by replacing:
clz.newInstance()
with:
clz.getDeclaredConstructor().newInstance()
Firstly, Class#getDeclaredConstructor
may throw InvocationTargetException
or NoSuchMethodException
(both forms of ReflectiveOperationException
), where as Class#newInstance
throws InstantiationException
for these conditions.
As these are not types of RuntimeException
, they need to be explicitly handled, arguably by catching them and setting them as a cause for a (new) InstantiationException
that can be thrown, to preserve the signature for the calling code.
Secondly, Class#getDeclaredConstructor
can cause an additional "accessDeclaredMembers"
security check to be made (as well as the checkPackageAccess()
check that Class#newInstance
also makes).
Therefore, additional steps (such as the use of AccessController#doPrivileged
) may need to be taken to ensure the caller does not fail this additional check.
So, a method like this:
Object createInstance(Class clz)
throws InstantiationException, IllegalAccessException {
return clz.newInstance();
}
might, once correctly modified, look something more like this:
Object createInstance(Class<?> clz)
throws InstantiationException, IllegalAccessException {
try {
return AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws InstantiationException, IllegalAccessException {
try {
return clz.getDeclaredConstructor().newInstance();
} catch (InvocationTargetException|NoSuchMethodException e) {
throw (InstantiationException)((new InstantiationException()).initCause(e));
}
}
});
} catch (PrivilegedActionException pae) {
Exception e = pae.getException();
if (e instanceof InstantiationException) throw (InstantiationException)e;
throw (IllegalAccessException)e;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With