United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4191708 Doc issue: inconsistency in java.awt.dnd.DropTarget
JDK-4191708 : Doc issue: inconsistency in java.awt.dnd.DropTarget

Details
Type:
Bug
Submit Date:
1998-11-20
Status:
Closed
Updated Date:
2004-09-15
Project Name:
JDK
Resolved Date:
2004-09-15
Component:
client-libs
OS:
solaris_2.5,generic
Sub-Component:
java.awt
CPU:
sparc,generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
1.2.0,5.0
Fixed Versions:
5.0 (tiger)

Related Reports
Relates:

Sub Tasks

Description
Name: sdC67446			Date: 11/20/98


There is inconsistency exists in java.awt.dnd.DropTarget:
Methods 
  dragEnter(DropTargetDragEvent evnt)
  dragOver(DropTargetDragEvent evnt)
  dragExit(DropTargetEvent evnt)
  dropActionChanged(DropTargetDragEvent evnt)
  drop(DropTargetDropEvent evnt)

work on 'evnt'==null differently.
Currently dragEnter, dragOver and dropActionChanged throw
NullPointerException, dragExit and drop ignores null parameter.
Should be fixed for consistency.

The doc says:
------------------------------------------------------------
public void dragEnter(DropTargetDragEvent dtde)
      The DropTarget intercepts dragEnter() notifications before
      the registered DropTargetListener gets them.

public void dragOver(DropTargetDragEvent dtde)

      The DropTarget intercepts dragOver() notifications before the
      registered DropTargetListener gets them.

public void dropActionChanged(DropTargetDragEvent dtde)

      The DropTarget intercepts dropActionChanged() notifications
      before the registered DropTargetListener gets them.

public void dragExit(DropTargetEvent dte)

      The DropTarget intercepts dragExit() notifications before the
      registered DropTargetListener gets them.

public void drop(DropTargetDropEvent dtde)

      The DropTarget intercepts drop() notifications before the
      registered DropTargetListener gets them.


The test demonstrating the bug:
-------------------------------------------------------------
import java.awt.dnd.*;
import java.awt.Button;

public class Test implements DropTargetListener {

    public void dragEnter(DropTargetDragEvent dsde) {}

    public void dragOver(DropTargetDragEvent dsde) {}

    public void dropActionChanged(DropTargetDragEvent dsde) {}

    public void dragExit(DropTargetEvent dsde) {}

    public void drop(DropTargetDropEvent dsde) {}
    
    public static void main(String[] args) {
	DropTarget dt = new DropTarget(new Button(), new Test());
	
	try {
	    dt.dragExit(null);
	    System.out.println("dragExit: OK.");
	} catch (NullPointerException e) {
	    System.out.println("drop: "+e);
	}

	try {
	    dt.drop(null);
	    System.out.println("drop: OK.");
	} catch (NullPointerException e) {
	    System.out.println("drop: "+e);
	}

	try {
	    dt.dropActionChanged(null);
	} catch (NullPointerException e) {
	    System.out.println("dropActionChanged: "+e);
	}

	try {
	    dt.dragEnter(null);
	} catch (NullPointerException e) {
	    System.out.println("dragEnter: "+e);
	}

	try {
	    dt.dragOver(null);
	} catch (NullPointerException e) {
	    System.out.println("dragOver: "+e);
	}
    }
}

Test output:
------------------------------------------------------------
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
Font specified in font.properties not found [-urw-itc zapfdingbats-medium-r-normal--*-%d-*-*-p-*-sun-fontspecific]
dragExit: OK.
drop: OK.
dropActionChanged: java.lang.NullPointerException
dragEnter: java.lang.NullPointerException
dragOver: java.lang.NullPointerException
------------------------------------------------------------

======================================================================

                                    

Comments
EVALUATION

This inconsistency will not be fixed. We have attempted to make similar changes
in the past (see BugID 4374176) and have been rebuffed by the TRC. The main
arguments are that:
  1. Changing the behavior of a method of a non-final class in response to
     a 'null' argument affects all existing subclasses. Every subclass would
     have to be updated to conform to the new specification.
  2. It's simply not worth the time to worry about the behavior of the method
     in response to client code *incorrectly* written in this manner.

E-mail from Bill Shannon concerning TRC's position on 'null' arguments:

-----

From: shannon <###@###.###>
Subject: Re: CCC request; bug 4374176: unneeded NPE's in java.awt.datatransfer package
To: ###@###.###
Cc: ###@###.###, ###@###.###, ###@###.###
MIME-Version: 1.0
Content-MD5: szqx+4lnW2ejBEu4itM0VQ==

[...]

We went through a general case of this in TRC some time ago, trying to
decide whether Java APIs in general should check for null parameters
and handle them specially (possibly explicitly throwing an NPE) and we
decided that, in general, that was not necessary.  There may be some
special cases where handling null explicitly may be useful, but I'm
not yet convinced that *changing* these APIs to do so is important.
If you have other arguments you haven't presented, I'd be interested
in hearing them.  In particular, if you have important use cases
that are significantly simplified by these changes, I'd like to see
them.

-----

Please keep these issues in mind when filing future JCK bugs.
david.mendenhall@east 2001-01-11

----------------
###@###.### 2001-01-19

If it's impossible to fix implementation to make these method's behavior
unified in respect to the null argument, then an appropriate solution
would be to reflect in the specification that the behavior of these
methods is undefined for null evnt. This will resolve inconsistency and
allow do not test this behavior in JCK tests. Reopening this as
specification bug.

-------------------------------------------------------------------- 

Should resolve this spec issue.  Since spec changes probably won't be 
allowed in Hopper, committing to Tiger.  
###@###.### 2001-12-02


Name: agR10216			Date: 06/27/2003


CCC had objections on the following CCC request
and the CCC request was withdrawn.

 4191708: Doc issue: inconsistency in java.awt.dnd.DropTarget
 Release: Tiger
 Type: bug-fix

 Problem
 
 The behavior of the following methods of the class
 java.awt.dnd.DropTarget with respect to the null parameter
 is unspecified and inconsistent:
     dragEnter(DropTargetDragEvent)
     dragOver(DropTargetDragEvent)
     dropActionChanged(DropTargetDragEvent)
     drop(DropTargetDropEvent)
     dragExit(DropTargetEvent)
 
 dragEnter, dragOver and dropActionChanged always throw
 NullPointerException. dragExit and drop may or may not throw
 NPE depending on the behavior of the associated
 DropTargetListener. More presice, dragExit and drop throw
 NPE if and only if the respective method of the associated
 DropTargetListener throws NPE.
 
 This inconsistency should be fixed: all methods listed above
 should throw NPE for null parameter, and the new consistent
 behavior should be specified in the javadoc to allow
 development of JCK tests.
 

 Solution
 
 Throw NullPointerException in the beginning of the following
 methods of DropTarget: dragEnter, dragOver,
 dropActionChanged, drop, dragExit if the parameter is null.
 Specify it in the javadoc comments for these methods.
 
 
 Interface summary
 
 exported  external  method  java.awt.dnd.DropTarget.dragEnter
 exported  external  method  java.awt.dnd.DropTarget.dragOver
 exported  external  method  java.awt.dnd.DropTarget.dragExit
 exported  external  method  java.awt.dnd.DropTarget.dropActionChanged
 exported  external  method  java.awt.dnd.DropTarget.drop
 
 
 Specification
 
 java.awt.dnd.DropTarget:
 
     /**
      * The <code>DropTarget</code> intercepts
      * dragEnter() notifications before the
      * registered <code>DropTargetListener</code> gets them.
      * <P>
      * @param dtde the <code>DropTargetDragEvent</code>
 +    * @throws NullPointerException if <code>dtde</code> is null
      */
     public synchronized void dragEnter(DropTargetDragEvent dtde)
 
     
     /**
      * The <code>DropTarget</code>
      * intercepts dragOver() notifications before the
      * registered <code>DropTargetListener</code> gets them.
      * <P>
      * @param dtde the <code>DropTargetDragEvent</code>
 +    * @throws NullPointerException if <code>dtde</code> is null
      */
 
     public synchronized void dragOver(DropTargetDragEvent dtde)
     
 
     /**
      * The <code>DropTarget</code> intercepts
      * dropActionChanged() notifications before the
      * registered <code>DropTargetListener</code> gets them.
      * <P>
      * @param dtde the DropTargetDragEvent
 +    * @throws NullPointerException if <code>dtde</code> is null
      */
 
     public synchronized void dropActionChanged(DropTargetDragEvent dtde)
 
     
     /**
      * The <code>DropTarget</code> intercepts
      * dragExit() notifications before the
      * registered <code>DropTargetListener</code> gets them.
      * <P>
      * @param dte the <code>DropTargetEvent</code>
 +    * @throws NullPointerException if <code>dte</code> is null
      */
 
     public synchronized void dragExit(DropTargetEvent dte)
     
 
     /**
      * The <code>DropTarget</code> intercepts drop() notifications before the
      * registered <code>DropTargetListener</code> gets them.
      * <P>
      * @param dtde the <code>DropTargetDropEvent</code>
 +    * @throws NullPointerException if <code>dtde</code> is null
      */
 
     public synchronized void drop(DropTargetDropEvent dtde)
 
 
 
 Compatibility risk: low
 
 The risk is low, though the fix changes the existing
 behavior. It is unlikely that any existing application
 relies on the behavior of these methods with respect to null
 parameter. Typically these methods aren't directly called
 from the client code. Instead Java Drag and Drop subsystem
 invokes them internally to notify the DropTargetListener
 associated with the DropTarget.
 
----------------------------------------------------------------


But the following CCC request documenting
existing behaviour was approved.

 4191708: Doc issue: inconsistency in java.awt.dnd.DropTarget
 Release: Tiger
 Type: bug-fix

 Problem
 
 The behavior of the following methods of the class
 java.awt.dnd.DropTarget with respect to the null parameter
 is unspecified and inconsistent:
     dragEnter(DropTargetDragEvent)
     dragOver(DropTargetDragEvent)
     dropActionChanged(DropTargetDragEvent)
     drop(DropTargetDropEvent)
     dragExit(DropTargetEvent)
 
 dragEnter(), dragOver() and dropActionChanged() throw
 NullPointerException for null parameter if the DropTarget is
 active (i.e. DropTarget.isActive() returns true). dragExit()
 thows NPE if the DropTarget is active and the method
 dragExit of the registered DropTargetListener throws NPE.
 drop() throws NPE if 1) the DropTarget is active and the
 method drop() of the registered DropTargetListener throws
 NPE, or 2) the parameter is null and at least one of the
 following is true: the DropTarget is not active, or there
 is no a DropTargetListener registered.
 
 This inconsistency should not be fixed since behavoir
 changes are objectionable, so the current behavior
 should be specified to allow development of JCK tests.
 

 Solution
 
 Specify the current behavoir of these methods to cover
 possible cases where an exception may be thrown in response
 to null parameter. The proposed specification was approved
 by the submitter of this bug, a member of JCK team.
 
 
 Interface summary
 
 exported  external  method  java.awt.dnd.DropTarget.dragEnter
 exported  external  method  java.awt.dnd.DropTarget.dragOver
 exported  external  method  java.awt.dnd.DropTarget.dragExit
 exported  external  method  java.awt.dnd.DropTarget.dropActionChanged
 exported  external  method  java.awt.dnd.DropTarget.drop
 
 
 Specification
 
 java.awt.dnd.DropTarget:
 
     /**
      * Calls <code>dragEnter</code> on the registered
      * <code>DropTargetListener</code> and passes it
      * the specified <code>DropTargetDragEvent</code>.
      * Has no effect if this <code>DropTarget</code>
      * is not active.
      *
      * @param dtde the <code>DropTargetDragEvent</code>
      *
      * @throws NullPointerException if this <code>DropTarget</code>
      *         is active and <code>dtde</code> is <code>null</code>
      *
      * @see #isActive
      */
     public synchronized void dragEnter(DropTargetDragEvent dtde)
 
     
     /**
      * Calls <code>dragOver</code> on the registered
      * <code>DropTargetListener</code> and passes it
      * the specified <code>DropTargetDragEvent</code>.
      * Has no effect if this <code>DropTarget</code>
      * is not active.
      *
      * @param dtde the <code>DropTargetDragEvent</code>
      *
      * @throws NullPointerException if this <code>DropTarget</code>
      *         is active and <code>dtde</code> is <code>null</code>
      *
      * @see #isActive
      */
     public synchronized void dragOver(DropTargetDragEvent dtde)
     
 
     /**
      * Calls <code>dropActionChanged</code> on the registered
      * <code>DropTargetListener</code> and passes it
      * the specified <code>DropTargetDragEvent</code>.
      * Has no effect if this <code>DropTarget</code>
      * is not active.
      *
      * @param dtde the <code>DropTargetDragEvent</code>
      *
      * @throws NullPointerException if this <code>DropTarget</code>
      *         is active and <code>dtde</code> is <code>null</code>
      *
      * @see #isActive
      */
     public synchronized void dropActionChanged(DropTargetDragEvent dtde)
 
 
     /**
      * Calls <code>dragExit</code> on the registered
      * <code>DropTargetListener</code> and passes it
      * the specified <code>DropTargetEvent</code>.
      * Has no effect if this <code>DropTarget</code>
      * is not active.
      * <p>
      * This method itself does not throw any exception
      * for null parameter but for exceptions thrown by
      * the respective method of the listener.
      *
      * @param dte the <code>DropTargetEvent</code>
      *
      * @see #isActive
      */
     public synchronized void dragExit(DropTargetEvent dte)
 
 
     /**
      * Calls <code>drop</code> on the registered
      * <code>DropTargetListener</code> and passes it
      * the specified <code>DropTargetDropEvent</code>
      * if this <code>DropTarget</code> is active.
      *
      * @param dtde the <code>DropTargetDropEvent</code>
      *
      * @throws NullPointerException if <code>dtde</code> is null
      *         and at least one of the following is true: this
      *         <code>DropTarget</code> is not active, or there is
      *         no a <code>DropTargetListener</code> registered.
      *
      * @see #isActive
      */
     public synchronized void drop(DropTargetDropEvent dtde)
 
 
 Compatibility risk: minimal


###@###.###  2003-06-27


======================================================================
                                     
2003-06-27
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
tiger

FIXED IN:
tiger

INTEGRATED IN:
tiger
tiger-b13

VERIFIED IN:
1.5


                                     
2004-09-17



Hardware and Software, Engineered to Work Together