Tratamiento de las excepciones en Java - Junta de Andalucía
←
→
Transcripción del contenido de la página
Si su navegador no muestra la página correctamente, lea el contenido de la página a continuación
Published on Marco de Desarrollo de la Junta de Andalucía (http://madeja.i-administracion.junta- andalucia.es/servicios/madeja) Tratamiento de las excepciones en Java Área: Gestión de Errores y Excepciones Carácter del recurso : Recomendado Tecno lo gías: Java Có digo : RECU-0214 Tipo de recurso : Referencia Descripción Objetivos y Estrategia del tratamiento de excepciones Los objetivos que se deben buscar al diseñar un mecanismo de control de excepciones deben ser: 1. Evitar que la ocurrencia de excepciones se muestre al usuario final en pantalla de forma incontrolada. 2. No perder información de las excepciones lanzadas a más bajo nivel en la aplicación. 3. Mantener un Log de todas las excepciones que ocurren en el sistema y que sea lo más legible posible. 4. Dar soporte al sistema de validaciones de la aplicación. La estrategia planteada deberá ser en líneas generales la siguiente (planteamiento para JSF/ADF): Diseñar una jerarquía de excepciones especificando en qué casos se debe utilizar cada una de ellas. Establecer un conjunto de reglas para determinar que excepciones deben ser capturadas. Unas recomendaciones podrían ser: Las excepciones controladas deben ser capturadas en el método en el que se producen, transformadas en las excepciones de aplicación adecuadas y enviadas hacia las capas superiores. Las excepciones de tipo no controladas que se lancen en la capa de acceso a datos deberán ser capturadas en la capa de servicio y traducidas en una excepción de tipo Aplicación. Las excepciones de tipo no controlado que se produzcan en la capa de servicio se considerarán en general errores del sistema. Para evitar que su ocurrencia se muestre al usuario se tendrá que utilizar el mecanismo de control de errores Web. En la capa de vista / controlador se tendrán que capturar tanto las excepciones de tipo Aplicación que provienen de las capas inferiores como las que se produzcan en esta capa. Las excepciones serán capturadas en el backing bean dentro de cada uno de los métodos donde se ejecuta el acceso a la capa de servicio. El sistema deberá gestionar los mensajes orientados a los usuarios y a los administradores. Los primeros serán los que se muestren en las páginas de la aplicación y los segundos los que se registren en el Log del sistema. Si se considera necesario, se tendrá que adaptar el mecanismo de ejecución de las acciones de los backing beans, para que todas compartan el mismo comportamiento respecto a las excepciones. Jerarquía de clases de excepciones Para la gestión de excepciones, lo más recomendable será definir una jerarquía de clases propias para el Sistema que se esté desarrollando. Esta jerarquía la formará un conjunto de clases con distinta funcionalidad dentro del sistema y su complejidad vendrá dada en función de: Complejidad del sistema que se está desarrollando. Granuralidad en la distinción de tipos de excepción. Estrategia a seguir en la diferenciación de excepciones: por funcionalidad, por capa, por subsistema asociado, etc A continuación se muestra una propuesta genérica de jerarquía de clases de excepción que aporta la suficiente funcionalidad como para que sea suficiente en la mayoría de las aplicaciones de tamaño medio. 1
SistemaExceptio n: excepción base del sistema que contiene los métodos necesarios para la escritura de los mensajes de error en el Log. Hereda de java.lang.RuntimeException. SistemaValidatio nExceptio n: clase de excepciones para tener un envoltorio de los errores de validación que se produzcan en la capa de negocio y modelo del sistema. Esta clase contendrá una colección de errores de validación, representados por la clase ErrorBean. Las validaciones serán implementadas en el componente que corresponda y diseñado a tal efecto (servicio de negocio, backing bean, etc.). Erro rBean: clase para encapsular los errores de validación que se produzcan en el sistema. Estos errores de validación estarán compuestos por los siguientes datos: código de error, lista de parámetros asociados, entidad del modelo de negocio y atributos asociados. Sirve de elemento de apoyo a la lista de errores de validación y al componente de validación. SistemaApplicatio nExceptio n: clase para capturar excepciones controladas que se consideren errores del sistema / errores de programación, pero que no deben impedir que se continúe trabajando con él. Pueden ser consideradas errores de aplicación: Ficheros no encontrados. Errores en operaciones aritméticas. Intentar modificar entidades que no se encuentren en base de datos. SistemaFaultExcepcio n: clase para la captura de excepciones que se consideran errores críticos en el sistema y que impedirán que se continúe trabajando en la aplicación. Implementa la interfaz ThrowsAdvice, lo que permite insertarla como un aspecto de la aplicación. Se utilizará para: Fallos de configuración. Caídas del sistema. Problemas relacionados con la instalación. Base de datos no disponible. Clases de soporte al tratamiento de excepciones Las siguientes clases dan soporte al tratamiento de las excepciones: ServicioDePresentacion: clase de soporte a tareas útiles para la capa de presentación (por ejemplo, traducción de mensajes de error en mensajes para las páginas JSF). Es un managed bean de aplicación utilizado por los backing beans. UtilidadesJSF: se trata de utilidades genéricas para la transformación de los mensajes de error en mensajes para ser mostrados en el sistema de mensajería JSF. Servicio DeExcepcio nes: clase utilizada para realizar un tratamiento centralizado de las excepciones ocurridas en la capa de negocio y modelo del sistema. Será un bean manejado por Spring. Esta clase implementa los métodos necesarios para particularizar los mensajes mostrados en el caso de excepciones generadas por restricciones de base de datos. Exceptio nHelper: clase con utilidades genéricas para la manipulación de la jerarquía de clases de excepciones del Sistema. Registro de excepciones Todas las excepciones del sistema tienen que ser registradas en el momento en que son encapsuladas por una excepción de 2
la jerarquía de excepciones establecida. Para su registro se hace uso del sistema de Log. Cada una de las excepciones tiene características distintas para las siguientes propiedades: Nivel de criticidad con el que se graba en el Log. Indicador de impresión de la pila de errores. Mensaje de error impreso en el Log para usuarios administradores (con fines de registro). Mensaje de error para mostrar a los usuarios. SistemaValidacio nExceptio n: tiene un nivel de Log Info. No se imprime ninguna pila de errores y el mensaje que se imprime contiene los códigos de error de cada una de las validaciones que han fallado. SistemaApplicatio nExceptio n: tiene un nivel de Log Warning, se imprime la pila de errores y el mensaje de error deberá ser recuperado del fichero de recursos para mensajes definido en la Aplicación, con los parámetros adecuados sustituidos. SistemaFaultExceptio n: tiene un nivel de Log Error. Se imprime la pila de errores, el mensaje puede estar basado en el fichero de recursos y contiene la traza origen del error. Captura y flujo de las excepciones En el siguiente diagrama se presenta la captura y el flujo de las excepciones: Las excepciones generadas en la capa de acceso a datos serán siempre DataAccessExceptio n lanzadas desde el contenedor de Spring. Todas las excepciones debidas a acceso desde la capa de servicio a otros sistemas o componentes serán encapsuladas en la capa de servicio. Para realizar esa tarea, las clases de servicio usan la clase Servicio DeExcepcio nes. Esta clase traduce las excepciones que se lanzan dentro de la ejecución de una clase de servicio a la excepción del tipo de la Aplicación adecuada. Esta traducción se realiza mediante la configuración almacenada en el fichero excepcio nes.xml, en el cual se establece la traducción correspondiente para los diferentes tipos de excepciones que se puedan producir. Las excepciones lanzadas en una clase de servicio por acceso a otras capas de la arquitectura (por ejemplo acceso a datos, acceso a un tramitador de expedientes, acceso a servicios Web, etc.) también son gestionadas por esta clase de servicio. Desde la capa de servicio tan sólo se lanzan hacia la capa de vista / controlador excepciones de tipo de la Aplicación convenientemente encapsuladas. En la capa de vista / controlador se capturan las excepciones provenientes de las capas inferiores además de las excepciones que se generan en la ejecución de las tareas propias de esa capa. Para la presentación de los mensajes de excepción y su puesta a disposición de las páginas de la aplicación, como para la gestión de las excepciones que se puedan producir en la propia capa de presentación, se utilizará la clase Servicio DePresentacio n, que será un managed bean de aplicación que contiene otras funcionalidades de apoyo para la capa de presentación. Utilización del fichero de recursos Los mensajes de error que se muestran por pantalla y en el sistema de Log se deberán almacenar en un fichero de recursos que puede denominarse por ejemplo excepciones.properties. En este fichero se incluirán el código y mensaje de error tanto para las excepciones del sistema como para los mensajes que se mostrarán en la pantalla de la aplicación. Se propone la 3
siguiente nomenclatura del código de error: .error.|comun.. Si el error es generado por una restricción de base de datos la nomenclatura deberá seguir la siguiente estructura: .validacion.constraint. excepciones.properties #Errores de aplicación sistema.comun.borrarentidad=Error al borrar %0 con identificador %1 sistema.error.comun.divisor.incorrecto=División por 0 o valor nulo sistema.error.comun.fichero.noexiste=El fichero no existe en el sistema sistema.error.comun.fichero.noexiste_detalle=El fichero %0 no existe en el sistema #Errores de validación relacionados con actores sistema.error.act.actorduplicado=La entidad %0 está duplicada sistema.error.act.actornoexiste=Actor %0 no existe en el sistema sistema.error.act.validar.idnulo=Valor de identificación de actor nulo sistema.error.act.validar.idgrande=Valor de identificación de actor demasiado grande sistema.error.act.nif.nocero=El valor del nif no puede ser 0 sistema.error.act.nif.menorqueuno=El valor del nif no puede ser menor de uno sistema.validacion.constraint.ASDO_UK1=la asociación entre el profesional y el evento está repetida sistema.validacion.constraint.PERF_UK1=Existe un perfil con el mismo nombre Si el final del código contiene la extensión “_detalle”, este será el mensaje adoptado con fines de registro para las excepciones de aplicación y de fallo del sistema. El mensaje de error podrá contener espacios marcados con “%[número]” que serán completados mediante el sistema de excepciones con los parámetros que se le pasen en el constructor de la excepción. Generalidades Los bloques try/catch son poco costosos en términos de rendimiento, cuando la excepción no se produce. El esfuerzo de proceso para establecer un bloque try/catch es muy pequeño; sin embargo, el coste del tratamiento de la excepción cuando ésta se produce no es trivial, pudiéndose llegar a penalizar el rendimiento si la excepción salta con relativa frecuencia (en cuyo caso no sería una excepción y no debería ser tratada como tal).Por ello, se recomienda la utilización de excepciones para tratar condiciones de error en un programa Java cuando se espera que éstas se produzcan de forma esporádica. La principal alternativa al uso de excepciones es la utilización de retorno de códigos de estado; sin embargo este último no ofrece mayor rendimiento, ya que el uso de excepciones, reduce el número de parámetros en las llamadas a método y por consiguiente que éstos se ejecuten más rápidamente que utilizando códigos de estado. Muchas veces, resulta más eficaz dejar que salte la excepción y capturarla, que ir controlando que dicha excepción no se produzca. Trazas Un sistema de trazas en Java debe de presentar las siguientes características: Diferenciar las trazas en distintos niveles Filtrar la información que se muestran en función de los usuarios Tener la posibilidad de enviar las trazas a destinos diversos (archivo, consola, bbdd) Ser configurable por ficheros Diferentes formatos de visualización. Definir niveles de prioridad y la filtración de la información Es imprescindible definir una estructura de prioridad de los mensajes de las trazas. Si seguimos el modelo recomendado por MADEJA usando log4j, tendremos la siguiente clasificación OFF, no se muestra en ningún caso FATAL, para mostrar mensajes de situaciones que probablemente harán abortar la aplicación ERROR, para mostrar mensajes de errores que no son deseados pero que no interrumpirán la aplicación WARN, para mostrar mensajes de contextos peligros para la aplicación, o ciertas operaciones de uso no recomendado INFO, para mostrar mensajes de información sobre la ejecución de la aplicación, o eventos importantes dentro de la misma DEBUG, para mostrar mensajes interesantes para depurar la aplicación. Muy orientado al tiempo de desarrollo ALL, se muestra en todos los casos Con esta división , se puede escribir las trazas de forma jerarquizada para que se visualicen en función de los tipos de usuario 4
que están ejecutando la aplicación. Normalmente se aplica por defecto el nivel de prioridad de INFO, por lo que los mensajes de nivel DEBUG no son visualizados. Este nivel genera un caudal elevado de trazas por lo que su uso suele estar restringido a entornos de desarrollo. Hay que considerar el manejo de las trazas en los casos de las excepciones y errores. Se sigue la recomendación de publicar la menor información posible acerca del error. No se recomienda escribir las trazas de excepciones a nivel de error, ya que en algunos casos no interesa que se visualicen. Enviar las trazas por destinos diversos Una vez establecido el nivel de trazas de nuestro código hay que configurar donde queremos que nuestras trazas sean escritas o direccionadas. Es necesario poder enviar las trazas para diferentes destinos de salida. Siguiendo el uso de la librería log4j se pueden enviar a consola, archivos, componentes Swing, servidores sockets remotos, JMS, Loggers de eventos NT y demonios remotos Syslog de UNIX. Pro cada destino de salida (conocido como "Appender" ) es necesario realizar una configuración. Para configurar un appender es necesario configurar: El tipo de destino de salida El nivel de traza Asignarle un stream Diseñar diferentes formatos de salida Es importante que no sólo permita personalizar el destino de salida, sino también el formato de salida. Esto es posible asociando un layout con un appender. El layout es el responsable de formatear la petición de logging de acuerdo a los deseos del usuario, mientras que el appender se encarga de enviar la salida formateada a su destino. Cada appender tiene su propio layout privado. Rendimiento con el sistema de trazas El incluir un sistemas de trazas provoca retrasos dentro de la ejecución de una aplicación. Normalmente se ralentiza la ejecución de entre 5 y 50 nanosegundos cuando esta deshabilitada. Si esta habilitada depende del tipo de appender y del layout. La mayor parte de este tiempo se gasta en construir el String del mensaje. En el caso de que la velocidad sea un factor crítico se recomienda utilizar las facilidades que ofrece Log4j para reducir el impacto de esta situación. Log4j tiene operaciones de que permiten habilitar y deshabilitar los logs a través de una condición. De esta manera podemos ahorrar bastante tiempo a cambio de escribir la condición. Buenas prácticas y recomendaciones de uso Como resumen de las recomendaciones: Almacenar los mensajes de error dentro del fichero properties Utilizar un log para registrar la información sobre las excepciones Definir niveles de prioridad dentro del log Diseñar diversos formatos de salida de la información de las excepciones Ejemplos Un ejemplo básico sería el siguiente: import java.io.IOException; // ... public static void main(String[] args) { try { // Se ejecuta algo que puede producir una excepción } catch (IOException e) { // manejo de una excepción de entrada/salida } catch (Exception e) { // manejo de una excepción cualquiera } finally { // código a ejecutar haya o no excepción } } Más información: Documentación sobre Logging del centro Java de la Junta de Andalucía 5
Pautas Área: Desarrollo » Seguridad » Gestión de Errores y Excepciones Có digo Título Tipo Carácter LIBP-0281 Tratamiento de excepciones Directriz Obligatoria Seguridad Source URL: http://madeja.i-administracion.junta-andalucia.es/servicios/madeja/contenido/recurso/214 6
También puede leer