JDK-4677290 : Image.getGraphics() throws IllegalAccessError
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.4.1,5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic,solaris_7
  • CPU: generic,sparc
  • Submitted: 2002-04-30
  • Updated: 2004-03-22
  • Resolved: 2003-09-23
Related Reports
Duplicate :  
Description
Image.getGraphics() throws an IllegalAccessError when called for a non-off-screen image.  The spec does not state what error/exception should be thrown in this case, only that the getGraphics() method can only be called for off-screen images.   An IllegalAccessError seems kind of harsh, it may make more sense to throw an UnsupportedOperationException.   The spec should also probably be updated to state which exception should be thrown.

Comments
EVALUATION The JDK has always thrown this error so I would be reluctant to change it. However we should document that we throw this error. ###@###.### 2002-05-01 An IllegalAccessError is inappropriate to use in this case. The spec for IllegalAccessError states "this error can only occur at run time if the definition of a class has incompatibly changed." PersonalBasisProfile (J2ME), which is derived from JDK 1.3, does throw an UnsupportedOperationException in this case. If the JDK is changed to throw an UnsupportedOperationException, the risk of incompatibility is probably very low because it is negative behavior (programs shouldn't be calling this method for non-offscreen images), and errors in general are not recommended to be caught by applications. Finally, developers should not be relying on something that is not in the spec if they want their application to be portable. ###@###.### 2002-05-08 I should note that the comment from IllegalAccessError is taken out of context. The "only occur" is not meant to state that "this is the only condition in which this error is allowed", but to indicate that most instances of where this error would be thrown are caught at compile time and so it is rare at runtime. The IllegalAccessError is meant to indicate that a method is called which the caller has no access to. If the acess violation is due to the public or protected nature of the method then the compiler will indeed catch this at compile time, but it is possible to construct bytecodes which would cause this condition to occur at runtime (though a spec-compliant compiler would not let that occur because it would fail to compile the file). It's a weak analogy, but in some case the access to the getGraphics() method is Illegal because it is statically known within the definition of the API of the Image class which images will allow that method to be accessed and which will not. It was a bad design to include a method on a class which was known to fail under pre-determined circumstances as well. The proper API would have made a separate subclass of Image which would contain the getGraphics method and only use that subclass in cases where it was appropriate. In a sense, if we did redesign the classes this way then old code would end up getting an IllegalAccessError when called on a non-writable image so one can view this error as representing a "virtual redesign" of the class hierarchy which was not undertaken due to the need to maintain source compatibility. The UnsupportedOperationException does seem to also be appropriate to this case, but was not introduced until version 1.2, two releases after the getGraphics() method was spec'd as part of the Image object. Switching to that Error would make it difficult for someone to write code that caught this condition and also worked on 1.1 runtimes. Possible 1.1 Exceptions and Errors that might be equally appropriate and supported on 1.1 runtimes would be IllegalStateException, AbstractMethodError (though again this would normally be caught by the compiler), or IllegalComponentStateException. We could also create a new subclass of one of these exceptions with a better description of when it is intended to be thrown and 1.1-compliant applications could always catch the superclass even if it isn't the most specific instance of the Throwable being thrown. ###@###.### 2002-05-09 Thanks Jim for the detailed description. One more datapoint: PersonalProfile (J2ME), which, like PersonalBasisProfile is derived from JDK 1.3, does not throw an exception or error in this case. It simply returns null. ###@###.### 2002-05-13 My thanks to Jim too for the detailed response. The main reason why I'm not comfortable with IllegalAccessError is that it's a subclass of LinkageError - the one responsible for binary compatibility. A LinkageError may be thrown way in advance of the actual getGraphics() call, perhaps even at application startup. This is why it's highly unlikely that someone would actually try to catch it, unless he learned by trial and error that this is how Sun's implementation works. I really think that compatibility risk in changing this error to something more appropriate is pretty low. A separate question is what is more appropriate. I'm not sure if compatibility with 1.1 is still a big concern. At least it's not the case in the J2ME space. Note also that PersonalJava, which is AWT 1.1 based, already includes UnsupportedOperationException. If 1.1 compatibility is really an issue though, IllegalStateException doesn't fit quite well since it implies dependency on timing. I cannot think of any proper exception other than RuntimeException itself. ###@###.### 2002-05-13
13-05-2002