Tratamento de Exceções em Java

Alberto Paulo Rabelo Barcelos Iure Guimarães João Bertolino

Goiânia 3 de abril de 2007

1. Abstract There are scenarios when our programs have to handle special conditions like an unrecheable database server over a network. This document approach a very important branch of programming called exception handling. We begin our study describing a typical scenario wich is necessary to handle with the exceptions. We keep on understanding the keywords involved in this field and the java syntax used to describe our problem. After the study of the “ins and outs” of the syntax we analyse the very dense Java Exception API. By the moment we have fineshed studying API we are ready to apply these concepts in the real world. 2. Resumo Suponha que um erro ocorra enquanto um programa esteja rodando. Estes erros podem ser causados por uma indisponibilidade da rede, por falta de espaço em disco ou o término inesperado da conexão de um banco de dados, até mesmo um index inválido para determinado vetor pode ocasionar um erro uma aplicação. Os usuários finais esperam que o programa saibam lidar com erros que possam ocorrer. Quando um erro ocorre em um programa devemos agir de duas formas: retornar a um estado seguro e permitir o usuário executar uma nova ação ou permitir que o usuário salve todas as informações e terminar o programa corretamente. 3. Visão Geral Primeiro tentaremos entender o que é uma exceção e para isso caminharemos pela definição de alguns termos importantes usando um exemplo. Imagine um programa que deve abrir uma conexão usando um socket para abrir um arquivo pela rede. O que acontece quando o servidor no qual você está tentando conectar pela rede está desligado, não disponível por uma série de razões? Duas coisas poderão acontecer o programa trava e termina e o usuário terá uma péssima experiência ou você pode fazer um tratamento de exceção. exceções são condições excepcionais que você não pode controlar como a indisponibilidade de um servidor. A responsabilidade do programador é criar um caminho alternativo para a execução do programa caso a exceção ocorra, evitando assim que o programa termine inesperadamente e o usário tenha uma péssima experiência. Noce pode tratar a exceção de várias formas como emitindo uma mensagem ao usuário dizendo que o servidor esta indisponível e pedindo a ele que selecione um outro servidor. Dessa forma seu software se torna muito mais confiável e amigável ao usuário final. Quando o Java encontra uma exceção durante a sua execução dizemos que ele "lança"(throw) a exceção. Essa condição excepcional lançada pela JVM é tratada como um objeto. O código do programa tratará a exceção, você será responsável por escrever o código responsável por lidar com a exceção quando ela ocorrer. Toda vez que uma exceção for lançada você deve "pegá-la"(patch) com o tratamento da exceção. Foquemos a partir de agora na sintaxe. 4. Termos Exceções. Throw. Exception Handling( tratamento de excessões). Erros. Java

5. Sintaxe básica para tratar excessões Corpo da do código que tratará a exceção: public class Exception1{ public static void main( String[ ] args){ try{ // Chamada de região protegida("Guarded Region") // Coloque aqui código que pode lançar uma exceção } catch(MinhaPrimeiraExcessao){ // Código que trata a exceção } catch(MinhaSegundaExcessao){ // Código que trata a exceção } ... ... ... catch(MinhaUltimaExcessao){ // Código que trata a exceção } } } Todo tipo de método que é chamado lança uma exceção em particular, e a exceção é um tipo de objeto. O que ocorre aqui é que o método incia sua execução no bloco "try". A partir do bloco se uma exceção for lançada ela deve ser tratada pelo bloco "catch". Observe que podem exister quantos blocos catch quanto quisermos. Suponha que uma exceção foi lançada pelo blobo "try" a JVM começa a buscar um bloco "catch" que possa tratar aquela exceção específica. Ela começa na primeira exceção até chegar a última exceção. Se a exceção lançada não pode ser tratada por nenhum dos blocos então o método mandará uma mensagem a virtual machine que terminará o programa inesperadamente. Em Java dependendo do método que você usa você não pode mesmo compilar sua classes se você não fizer o tratamento de exceção. O que é uma coisa boa já que evita transtornos futuros. Imaginemos agora um exemplo mais real usando pseudo-código. public class Exception1{ public static void query( ){ try{ Crie um objeto para conexão com o banco de dados Inicie a conecão com o banco de dados Crie um objeto para consultar o banco de dados // Terminará a execução do bloco sem executar os comandos subsequentes Execute a consulta Mostre os resultados Feche a conexão // Clean-up code } catch(DatabaseConnectionException){ Escolha outro servidor de banco de dados Escolha outro banco de dados Forneça outras credencias de logon

... // Pode haver centenas de motivos que nos impede de conectar ao banco de dados } catch(QueryException){ // Código que trata a exceção } ... ... ... catch(MinhaUltimaExcessao){ // Código que trata a exceção } finally{ // Sempre executa // Coloque aqui seu "Clean-up code" } } } Suponha que o banco de dados não esteja disponível, imediatamente ao tentar conectar ao banco de dados o método lançará a exceção e passará a buscar um bloco que possa tratá-la. Chegamos ao primeiro bloco catch. Entenda que terminamos a execução do bloco try antes de executar os outros comandos subsequentes. Dessa forma depois de tratada a exceção não estaríamos habilitados a terminar a conexão com o banco de dados. Mas sabemos que sempre devemos liberar nossas fontes para que outros objetos possam usálas(consulte threads). Uma fonte("resource") pode ser um stream para um arquivo, uma conexão com um banco de dados, entre outras. Um pedaço de código que deve liberar uma "resource" é chama de clean-up code. No final de nossos blocos podemos colocar o bloco "finally". O código dentro desse bloco sempre executa não importa o que possa acontecer, ele sempre executa. O fluxo dentro do método vai do bloco try para o bloco catch apropriado caso seja lançada uma exceção e depois para o bloco finally que sempre executará mesmo que uma exceção não seja lançada. Portanto nesse bloco é que devemos colocar nosso clean-up code. 6. Sintaxe básica para gerar uma exceção String trickyMethod() throws IOException
{ int result = readAnotherChar(); if ( result < 0 ) throw new IOException( "bad data" ); return result;

}

7. A API das excessões Java é uma linguagem rica em excessões e não poderemos abordar todas aqui. Se navegarmos pela API de Java podemos ver que dentro de uma package teremos as interfaces, as classes e as excessões. Por exemplo consideremos o pacote java.lang temos dentro dele varias interfaces, classes e excessões que corresponde as principais funcionalidades da linguagem. Esse é o pacote que encapsula a maioria das funcionalidades básicas de java. Diferentes excessões são implementadas como classes diferentes, apara citarmos alguns exemplos: Exception, ArithmeticException, ArrayIndexOutOfBoundsException, ArrayStoreException, ClassNotFoundException, CloneNotSupportedException, Exception, IndexOutOfBoundsException, InstantiationException, InterruptedException, NegativeArraySizeExceptionNoSuchFieldException, NullPointerException ,NumberFormatException, RuntimeException, SecurityException, StringIndexOutOfBoundsException, UnsupportedOperationException. Diante de tantos tipos de excessões devemos saber identificar cada tipo de exceção e usá-las quando em nosso método para lançarmos uma exceção. 8. Estrutura da API

Type codes used in describing Exceptions Letter R E C Type Runtime Error Checked Parent Class java.lang.RuntimeException java.lang.Error java.lang.Exception Checked? (declare throws?) Use Error that can occur in almost any code e.g. NullPointerException. Serious error you really should not try to catch, e.g. OutOfMemoryError. Likely exceptional condition that can only occur in specific places in the code e.g. EOFException.

Specific Exceptions Exception Name AbstractMethodError AccessControlException AccessException AclNotFoundException ActivateFailedException ActivationException AlreadyBoundException ApplicationException ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException AttributeInUseException AttributeModificationException AuthenticationException AuthenticationNotSupportedException AWTError AWTError AWTException BadLocationException BatchUpdateException BindException CannotProceedException CannotRedoException CannotUndoException CertificateEncodingException CertificateException CertificateExpiredException CertificateNotYetValidException CertificateParsingException ChangedCharSetException CharConversionException ClassCastException ClassCircularityError ClassFormatError ClassNotFoundException CloneNotSupportedException CMMException CommunicationException ConcurrentModificationException ConfigurationException ConnectException ConnectIOException ContextNotEmptyException CRLException DataFormatException DigestException EmptyStackException E R C C C C C C R R R C C C C E E C C C C C R R C C C C C C C R E E C C R C R C C C C C C C R Type java.lang java.security java.rmi java.security.acl java.rmi.activation java.rmi.activation javax.naming org.omg.CORBA.portable java.lang java.lang java.lang javax.naming.directory javax.naming.directory javax.naming javax.naming java.awt java/awt java.awt javax.swing.text java.sql java.net javax.naming javax.swing.undo javax.swing.undo java.security.cert java.security.cert java.security.cert java.security.cert java.security.cert javax.swing.text java.io java.lang java.lang java.lang java.lang java.lang java.awt.color javax.naming java.util javax.naming java.rmi java.rmi javax.naming java.security.cert java.util.zip java.security java.util Thrown by methods in the Stack class to indicate that the stack is empty. Does not refer to the system CRL (Certificate Revocation List) Exception. This exception may be thrown by methods that have detected concurrent modification of a backing object when such modification is not permissible. E.g. two threads modifying a HashMap simultaneously. notes. notes. notes. notes. Signals that an error occurred while attempting to bind a socket to a local address and port This exception is to report bad locations within a document model. Used for reporting application level exceptions between ORBs and stubs Most commonly a divide by zero. notes. Can be handled more generically with IndexOutOfBoundsException. notes. Thrown to indicate that an attempt has been made to store the wrong type of object into an array of objects. notes. This is an exception that is thrown whenever a reference is made to a non-existent ACL (Access Control List). notes. Thrown by certain methods of the java.rmi.Naming class. Thrown whenever a reference is made to a nonexistent ACL (Access Control List). thrown by the RMI runtime when activation fails during a remote call to an activatable object. Package Notes

Specific Exceptions Exception Name EOFException Error Exception ExceptionInInitializerError ExceptionInInitializerError ExpandVetoException ExportException FileNotFoundException FontFormatException GeneralSecurityException IllegalAccessError C E C E E C C C C C E Type java.io java.lang java.lang java.lang java.lang javax.swing.tree java.rmi.server java.io java.awt java.security java.lang notes. Thrown when an application tries to load in a class, but the currently executing method does not have access to the definition of the specified class, because the class is not public and in another package. Most common exception to reject a bad parameter to a method. Package stack. notes. Catches any serious error such as OutOfMemoryError that you unlikely can recover from. generic. Catches any specify Exception plus general Runtime exceptions, but not Errors. notes. Notes

IllegalAccessException

C

java.lang

IllegalArgumentException IllegalComponentStateException IllegalMonitorStateException IllegalPathStateException IllegalStateException IllegalThreadStateException ImagingOpException IncompatibleClassChangeError IndexOutOfBoundsException IndirectionException InstantiationError InstantiationException InsufficientResourcesException InternalError InterruptedException InterruptedIOException InterruptedNamingException IntrospectionException InvalidAlgorithmParameterException InvalidAttributeIdentifierException InvalidAttributesException InvalidAttributeValueException InvalidClassException InvalidDnDOperationException InvalidKeyException InvalidKeySpecException InvalidMidiDataException InvalidNameException InvalidObjectException InvalidParameterException InvalidParameterSpecException InvalidSearchControlsException InvalidSearchFilterException InvalidTransactionException InvocationTargetException IOException JarException KeyException KeyManagementException KeyStoreException LastOwnerException LdapReferralException LimitExceededException LineUnavailableException LinkageError LinkException

R R R R R R R E R R E C C E C C C C C C C C C R C C C C C R C C C C C C C C C C C C C C E C

java.lang java.awt java.lang java.awt.geom java.lang java.lang java.awt.image java.lang java.lang org.omg.CORBA.portable java.lang java.lang javax.naming java.lang java.lang java.io javax.naming java.beans java.security javax.naming.directory javax.naming.directory javax.naming.directory java.io java.awt.dnd java.security java.security.spec javax.sound.midi javax.naming java.io java.security java.security.spec javax.naming.directory javax.naming.directory javax.transaction java.lang.reflect java.io java.util.jar java.security java.security java.security java.security.acl javax.naming.ldap javax.naming javax.sound.sampled java.lang javax.naming

Signals that a method has been invoked at an illegal or inappropriate time.

notes.

Thrown when a thread is waiting, sleeping, or otherwise paused for a long time and another thread interrupts it using the interrupt method in class Thread.

This is a GeneralSecurityException. See IllegalArgumentException.

notes.

Specific Exceptions Exception Name LinkLoopException MalformedLinkException MalformedURLException MarshalException MidiUnavailableException MimeTypeParseException MissingResourceException NameAlreadyBoundException NameNotFoundException NamingException NamingSecurityException NegativeArraySizeException NoClassDefFoundError NoInitialContextException NoninvertibleTransformException NoPermissionException NoRouteToHostException NoSuchAlgorithmException NoSuchAttributeException NoSuchElementException NoSuchFieldError NoSuchFieldException NoSuchMethodError NoSuchMethodException NoSuchObjectException NoSuchProviderException NotActiveException NotBoundException NotContextException NotOwnerException NotSerializableException NullPointerException NumberFormatException ObjectStreamException OperationNotSupportedException C C C C C C R C C C C R E C C C C C C R E C E C C C C C C C C R R C C Type javax.naming javax.naming java.net java.rmi javax.sound.midi java.awt.datatransfer java.util javax.naming javax.naming javax.naming javax.naming java.lang java.lang javax.naming java.awt.geom javax.naming java.net java.security javax.naming.directory java.util java.lang java.lang java.lang java.lang java.rmi java.security java.io java.rmi javax.naming java.security.acl java.io java.lang java.lang java.io javax.naming Unexpected data appeared in an ObjectInputStream trying to read an Object. Occurs when the stream contains primitive data instead of the object that is expected by readObject. The EOF flag in the exception is true indicating that no more primitive data is available. The count field contains the number of bytes available to read. By the time this happens it is almost too late. gc has already done what it could. Possibly some process has just started gobbling RAM, or perhaps the problem you are trying to solve is just too big for the size of the allotted virtual ram. You can control that with the java.exe command line switches. notes. Actually a null reference exception. notes. Commonly thrown when a String is converted to internal binary numeric format. notes. notes. Thrown when serialization or deserialization is not active notes. notes. Package Notes

OptionalDataException

C

java.io

OutOfMemoryError

E

java.lang

ParseException PartialResultException PolicyError PrinterAbortException PrinterException PrinterIOException PrivilegedActionException ProfileDataException PropertyVetoException ProtocolException ProviderException RasterFormatException ReferralException RemarshalException RemoteException RMISecurityException RuntimeException SchemaViolationException SecurityException ServerCloneException

C C E C C C C R C C R R C C C C R C R C

java.text javax.naming org.omg.CORBA java.awt.print java.awt.print java.awt.print java.security java.awt.color java.beans java.net java.security java.awt.image javax.naming org.omg.CORBA.portable java.rmi java.rmi java.lang javax.naming.directory java.lang java.rmi.server Error that can occur in almost any code e.g. NullPointerException. Use this when to catch general errors when no specific exception is being thrown.

Specific Exceptions Exception Name ServerError ServerException ServerNotActiveException ServerRuntimeException ServiceUnavailableException SignatureException SizeLimitExceededException SkeletonMismatchException SkeletonNotFoundException SocketException SocketSecurityException SQLException StackOverflowError StreamCorruptedException StringIndexOutOfBoundsException StubNotFoundException SyncFailedException SystemException TimeLimitExceededException TooManyListenersException TransactionRequiredException TransactionRolledbackException UndeclaredThrowableException UnexpectedException UnknownError UnknownException UnknownGroupException UnknownHostException UnknownHostException UnknownObjectException UnknownServiceException UnknownUserException UnmarshalException UnrecoverableKeyException UnsatisfiedLinkError UnsupportedAudioFileException UnsupportedClassVersionError UnsupportedDataTypeException UnsupportedEncodingException UnsupportedFlavorException UnsupportedLookAndFeelException UnsupportedOperationException UserException UTFDataFormatException VerifyError VirtualMachineError WriteAbortedException ZipException E C C C C C C C C C C C E C R C C R C C C C R R E R C C C C C C C C E C E C C C C R C C E E C C Type java.rmi java.rmi java.rmi.server java.rmi javax.naming java.security javax.naming java.rmi.server java.rmi.server java.net java.rmi.server java.sql java.lang java.io java.lang java.rmi java.io org.omg.CORBA javax.naming java.util javax.transaction javax.transaction java.lang.reflect java.rmi java.lang org.omg.CORBA.portable java.rmi.activation java.rmi java.net java.rmi.activation java.net org.omg.CORBA java.rmi java.security java.lang javax.sound.sampled java.lang java.io java.io java.awt.datatransfer javax.swing java.lang org.omg.CORBA java.io java.lang java.lang java.io java.util.zip notes. notes. Use for code not yet implemented, or that you deliberately did not implement. notes. undocumented. notes. notes. notes. notes. ObjectStream data are scrambled. notes. Can be handled more generically with IndexOutOfBoundsException. notes. Package Notes

9. Bibliografia ● Core Java vol.2 7ª ed. ● CBT Nuggets. Java: on the job series. ● Thinking in Java 3ª ed.