Code review request: 7146763: Warnings cleanup in the sun.rmi and related packages
Kurchi Hazra
kurchi.subhra.hazra at oracle.com
Fri Feb 24 19:01:18 UTC 2012
Hi Stuart,
Thanks for the detailed explanation. Here is an updated webrev:
http://cr.openjdk.java.net/~khazra/7146763/webrev.02/
- Kurchi
On 2/24/2012 12:54 AM, Stuart Marks wrote:
> On 2/22/12 1:25 PM, Kurchi Hazra wrote:
>> On 2/22/2012 10:01 AM, Rémi Forax wrote:
>>> Hi Kurchi, hi all,
>>>
>>> in ReliableLog, you can get ride of the @SupressWarnings,
>>> getLogClassConstructor should return a Constructor<?> and not a
>>> Constructor<?
>>> extends LogFile>,
>>> the field logClassConstructor should be typed Constructor<?> and
>>> in openLogFile, the log should be constructed like this
>>>
>>> log = (logClassConstructor == null ?
>>> new LogFile(logName, "rw") :
>>>
>>> (LogFile)logClassConstructor.newInstance(logName, "rw"));
>>>
>>> The idea is that a cast on a LogFile is typesafe but not a cast on a
>>> Constructor<? extends LogFile>.
>>
>> If I change the return type to Constructor<?>, I get the following
>> error:
>> ../../../../src/share/classes/sun/rmi/log/ReliableLog.java:122: error:
>> incompatible types
>> logClassConstructor = getLogClassConstructor();
>> ^
>> required: Constructor<? extends LogFile>
>> found: Constructor<CAP#1>
>> where CAP#1 is a fresh type-variable:
>> CAP#1 extends Object from capture of ?
>> And the following warning:
>>
>> ../../../../src/share/classes/sun/rmi/log/ReliableLog.java:350: warning:
>> [unchecked] unchecked cast
>> cl.getConstructor(String.class,
>> String.class);
>> ^
>> required: Constructor<? extends LogFile>
>> found: Constructor<CAP#1>
>> where CAP#1 is a fresh type-variable:
>> CAP#1 extends Object from capture of ?
>>
>>
>> Thanks,
>> Kurchi
>
> Hi Kurchi,
>
> To implement Rémi's suggestion fully, you would also have to change
> the type of logClassConstructor to Contructor<?> near line 122, remove
> the cast of cl.getConstructor() near line 350, and then add the cast
> to LogFile at the call to newInstance() near line 546.
>
> This works to get rid of the warnings and errors, but the declaration
> of Constructor<?> is somewhat imprecise. The code checks to make sure
> that the loaded class is a subclass of LogFile (that's what the
> isAssignableFrom check is doing). Thus the type of the loaded class
> really should be Class<? extends LogFile>, and correspondingly the
> logClassConstructor should be Constructor<? extends LogFile>. That's
> how logClassConstructor is declared now and it would be nice to keep
> it that way.
>
> It turns out that Class.asSubclass() does this conversion without
> generating an unchecked warning. This internally does an
> isAssignableFrom() check and casts to the right wildcarded type, so
> this can simplify the code in getLogClassConstructor() somewhat as
> well. (Incidentally, asSubClass() has @SuppressWarnings on its
> implementation.) I've appended some diffs below (to be applied on top
> of your most recent webrev) to show how this can be done.
>
> The behavior is slightly different, as it throws ClassCastException
> (which is caught by the catch clause below, emitting a log message)
> instead of silently returning null. This is probably an improvement,
> since if the user specifies the wrong class in the property name, the
> exception stack trace should indicate what happened.
>
> s'marks
>
>
>
>
> diff -r 72d32fd57d89 src/share/classes/sun/rmi/log/ReliableLog.java
> --- a/src/share/classes/sun/rmi/log/ReliableLog.java Fri Feb 24
> 00:01:53 2012 -0800
> +++ b/src/share/classes/sun/rmi/log/ReliableLog.java Fri Feb 24
> 00:39:02 2012 -0800
> @@ -330,9 +330,7 @@
> * property a) can be loaded, b) is a subclass of LogFile, and c)
> has a
> * public two-arg constructor (String, String); otherwise returns
> null.
> **/
> - @SuppressWarnings("unchecked")
> - private static Constructor<? extends LogFile>
> - getLogClassConstructor() {
> + private static Constructor<? extends LogFile>
> getLogClassConstructor() {
>
> String logClassName = AccessController.doPrivileged(
> new GetPropertyAction("sun.rmi.log.class"));
> @@ -345,11 +343,9 @@
> return
> ClassLoader.getSystemClassLoader();
> }
> });
> - Class<?> cl = loader.loadClass(logClassName);
> - if (LogFile.class.isAssignableFrom(cl)) {
> - return (Constructor<? extends LogFile>)
> - cl.getConstructor(String.class,
> String.class);
> - }
> + Class<? extends LogFile> cl =
> +
> loader.loadClass(logClassName).asSubclass(LogFile.class);
> + return cl.getConstructor(String.class, String.class);
> } catch (Exception e) {
> System.err.println("Exception occurred:");
> e.printStackTrace();
>
>
--
-Kurchi
More information about the core-libs-dev
mailing list