Todas las entradas de: xavsal

Consultas SQL sobre las vistas del diccionario de Oracle

 

Se añaden consultas para recuperar información sobre el diccionario de Oracle. La mayoría han funcionado correctamente para  la versión 10.1.0.2.0 de Oracle Database 10g release 1. Su documentación se puede encontrar en este enlace.

Consulta Oracle SQL sobre la vista que muestra el estado de la base de datos

    SELECT * FROM v$instance;

Consulta Oracle SQL que muestra si la base de datos está abierta

SELECT status FROM v$instance;

Consulta Oracle SQL sobre la vista que muestra los parámetros generales de Oracle

    SELECT * FROM v$system_parameter;

Consulta Oracle SQL para conocer la Versión de Oracle

    SELECT value FROM v$system_parameter where name = ‘compatible’;

Consulta Oracle SQL para conocer la Ubicación y nombre del fichero spfile

    SELECT value FROM v$system_parameter where name = ‘spfile’

Consulta Oracle SQL para conocer la Ubicación y número de ficheros de control

    SELECT value FROM v$system_parameter where name = ‘control_files’;

Consulta Oracle SQL para conocer el Nombre de la base de datos

    SELECT value FROM v$system_parameter where name = ‘db_name’;

Consulta Oracle SQL sobre la vista que muestra las conexiones actuales a Oracle. Para visualizarla es necesario entrar con privilegios de administrador

    SELECT osuser, username, machine, program
FROM v$session
ORDER BY osuser;

Consulta Oracle SQL para matar una sesión Oracle

    SELECT sid, serial# FROM v$session where username='<usuario>’;
    ALTER SYSTEM kill session ‘<sid, serial>’;

Consulta Oracle SQL que muestra el número de conexiones actuales a Oracle agrupado por aplicación que realiza la conexión

    SELECT program Aplicacion, count(program) Numero_Sesiones
FROM v$session
GROUP BY program
ORDER BY Numero_Sesiones desc;

Consulta Oracle SQL que muestra los usuarios de Oracle conectados y el número de sesiones por usuario

    SELECT username Usuario_Oracle, count(username) Numero_Sesiones
FROM v$session
GROUP BY username
ORDER BY Numero_Sesiones desc;

Consulta Oracle SQL que muestra propietarios de objetos y número de objetos por propietario

    SELECT owner, count(owner) Numero
FROM dba_objects
GROUP BY owner;

Consulta Oracle SQL sobre el Diccionario de datos (incluye todas las vistas y tablas de la Base de Datos)

    SELECT * FROM dictionary;

Consulta Oracle SQL que muestra los datos de una tabla especificada

    SELECT * FROM ALL_ALL_TABLES where upper(table_name) like ‘%<cadena_texto>%’;

Consulta Oracle SQL que muestra las descripciones de los campos de una tabla especificada

    SELECT * FROM ALL_COL_COMMENTS where upper(table_name) like ‘%<cadena_texto>%’;

Consulta Oracle SQL para conocer las tablas propiedad del usuario actual

    SELECT * FROM user_tables;

Consulta Oracle SQL para conocer todos los objetos propiedad del usuario conectado a Oracle

    SELECT * FROM user_catalog;

Consulta Oracle SQL para el DBA de Oracle que muestra los tablespaces, el espacio utilizado, el espacio libre y los ficheros de datos de los mismos

    SELECT t.tablespace_name «Tablespace», t.status «Estado»,
ROUND(MAX(d.bytes)/1024/1024,2) «MB Tamaño»,
ROUND((MAX(d.bytes)/1024/1024) –
(SUM(decode(f.bytes, NULL,0, f.bytes))/1024/1024),2) «MB Usados»,
ROUND(SUM(decode(f.bytes, NULL,0, f.bytes))/1024/1024,2) «MB Libres»,
t.pct_increase «% incremento»,
SUBSTR(d.file_name,1,80) «Fichero de datos»
FROM DBA_FREE_SPACE f, DBA_DATA_FILES d, DBA_TABLESPACES t
WHERE t.tablespace_name = d.tablespace_name AND
f.tablespace_name(+) = d.tablespace_name
AND f.file_id(+) = d.file_id GROUP BY t.tablespace_name,
d.file_name, t.pct_increase, t.status
ORDER BY 1,3 DESC;

Consulta Oracle SQL para conocer los productos Oracle instalados y la versión

    SELECT * FROM product_component_version;

Consulta Oracle SQL para conocer los roles y privilegios por roles

SELECT * FROM role_sys_privs;

Consulta Oracle SQL para conocer las reglas de integridad y columna a la que afectan

SELECT constraint_name, column_name FROM sys.all_cons_columns;

Consulta Oracle SQL para conocer las tablas de las que es propietario un usuario

    SELECT table_owner, table_name FROM sys.all_synonyms where table_owner like ‘<usuario>’;

Variante: Consulta Oracle SQL más efectiva

    SELECT DISTINCT TABLE_NAME
FROM ALL_ALL_TABLES
WHERE OWNER LIKE ‘HR’;

Parámetros de Oracle, valor actual y su descripción

    SELECT v.name, v.value value, decode(ISSYS_MODIFIABLE, ‘DEFERRED’,
‘TRUE’, ‘FALSE’) ISSYS_MODIFIABLE, decode(v.isDefault, ‘TRUE’, ‘YES’,
‘FALSE’, ‘NO’) «DEFAULT», DECODE(ISSES_MODIFIABLE, ‘IMMEDIATE’,
‘YES’,’FALSE’, ‘NO’, ‘DEFERRED’, ‘NO’, ‘YES’) SES_MODIFIABLE,
DECODE(ISSYS_MODIFIABLE, ‘IMMEDIATE’, ‘YES’, ‘FALSE’, ‘NO’,
‘DEFERRED’, ‘YES’,’YES’) SYS_MODIFIABLE , v.description
FROM V$PARAMETER v
WHERE name not like ‘nls%’ 

    ORDER BY 1;

Consulta Oracle SQL que muestra los usuarios de Oracle y datos suyos
(fecha de creación, estado, id, nombre, tablespace temporal,…)

    SELECT * FROM dba_users;

Consulta Oracle SQL para conocer tablespaces y propietarios de los mismos

    SELECT owner, decode(partition_name, null, segment_name,
segment_name || ‘:’ || partition_name) name,
segment_type, tablespace_name,bytes,initial_extent,
next_extent, PCT_INCREASE, extents, max_extents
FROM dba_segments
Where 1=1 AND extents > 1 

    ORDER BY 9 desc, 3;
Últimas consultas SQL ejecutadas en Oracle y usuario que las ejecutó

    SELECT distinct 
    vs.sql_text, vs.sharable_mem,
vs.persistent_mem, vs.runtime_mem, vs.sorts,
vs.executions, vs.parse_calls, vs.module,
vs.buffer_gets, vs.disk_reads, vs.version_count,
vs.users_opening, vs.loads,
to_char(to_date(

       vs.first_load_time, ‘YYYY-MM-DD/HH24:MI:SS’),’MM/DD HH24:MI:SS’) first_load_time,
rawtohex(vs.address) address, vs.hash_value hash_value ,
rows_processed , vs.command_type, vs.parsing_user_id ,
OPTIMIZER_MODE , au.USERNAME parseuser
FROM v$sqlarea vs , all_users au
where (parsing_user_id != 0) AND
(au.user_id(+)=vs.parsing_user_id)
AND (executions >= 1) ORDER BY buffer_gets/executions desc;

Consulta Oracle SQL para conocer todos los tablespaces

    SELECT * FROM V$TABLESPACE;

Consulta Oracle SQL para conocer la memoria Share_Pool libre y usada

SELECT name, to_number(value) bytes
FROM v$parameter where name =’shared_pool_size’
union all
SELECT name,bytes
FROM v$sgastat where pool = ‘shared pool’ AND name = ‘free memory’;

Cursores abiertos por usuario

SELECT b.sid, a.username, b.value Cursores_Abiertos
FROM v$session a,
v$sesstat b,
v$statname c
where c.name in (‘opened cursors current’)
AND b.statistic# = c.statistic#
AND a.sid = b.sid
AND a.username is not null
AND b.value >0
ORDER BY 3;

Consulta Oracle SQL para conocer los aciertos de la caché (no debería superar el 1 por ciento)

SELECT sum(pins) Ejecuciones, sum(reloads) Fallos_cache,
trunc(sum(reloads)/sum(pins)*100,2) Porcentaje_aciertos
FROM v$librarycache
where namespace in (‘TABLE/PROCEDURE’, ‘SQL AREA’, ‘BODY’, ‘TRIGGER’);

Sentencias SQL completas ejecutadas con un texto determinado en el SQL

    SELECT c.sid, d.piece, c.serial#, c.username, d.sql_text
FROM v$session c, v$sqltext d
WHERE c.sql_hash_value = d.hash_value
AND upper(d.sql_text) like ‘%WHERE <nombre_campo> LIKE%’
ORDER BY c.sid, d.piece;

Una sentencia SQL concreta (filtrado por sid)

    SELECT c.sid, d.piece, c.serial#, c.username, d.sql_text
FROM v$session c, v$sqltext d
WHERE c.sql_hash_value = d.hash_value
AND sid = 105
ORDER BY c.sid, d.piece;

Consulta Oracle SQL para conocer el tamaño ocupado por la base de datos

    SELECT sum(BYTES)/1024/1024 MB FROM DBA_EXTENTS;

Consulta Oracle SQL para conocer el tamaño de los ficheros de datos de la base de datos

    SELECT sum(bytes)/1024/1024 MB FROM dba_data_files;

Consulta Oracle SQL para conocer el tamaño ocupado por una tabla concreta sin incluir los índices de la misma

    SELECT sum(bytes)/1024/1024 MB FROM user_segments
where segment_type=’TABLE’ AND segment_name='<nombre_tabla>’;

Consulta Oracle SQL para conocer el tamaño ocupado por una tabla concreta incluyendo los índices de la misma

SELECT sum(bytes)/1024/1024 Table_Allocation_MB FROM user_segments
where segment_type in (‘TABLE’,’INDEX’) AND
(segment_name='<nombre_tabla>’ OR segment_name in
(SELECT index_name FROM user_indexes where table_name='<nombre_tabla>’));

Consulta Oracle SQL para conocer el tamaño ocupado por una columna de una tabla

    SELECT sum(vsize(‘<nombre_columna’))/1024/1024 MB 
    FROM <nombre_tabla>;

Consulta Oracle SQL para conocer el espacio ocupado por usuario

    SELECT owner, SUM(BYTES)/1024/1024 MB FROM DBA_EXTENTS
GROUP BY owner;

Consulta Oracle SQL para conocer el espacio ocupado por los diferentes segmentos
(tablas, índices, undo, rollback, cluster, …)

    SELECT SEGMENT_TYPE, SUM(BYTES)/1024/1024 MB FROM DBA_EXTENTS
GROUP BY SEGMENT_TYPE;

Consulta Oracle SQL para obtener todas las funciones de Oracle: NVL, ABS, LTRIM, …

    SELECT distinct object_name
FROM all_arguments
WHERE package_name = ‘STANDARD’
ORDER BY object_name;

Consulta Oracle SQL para conocer el espacio ocupado por todos los objetos de la base de datos,
muestra los objetos que más ocupan primero

    SELECT SEGMENT_NAME, SUM(BYTES)/1024/1024 MB FROM DBA_EXTENTS
GROUP BY SEGMENT_NAME
ORDER BY 2 desc;

Consulta Oracle SQL para recuperar los indices de una tabla específica

    SELECT  index_name, index_type, table_owner, table_name, table_type
FROM user_indexes
WHERE table_name = ‘<nom_taula>’;

Consulta Oracle SQL para obtener todas las tablas que utilizan un campo concreto

    SELECT  table_name
FROM all_tab_columns
WHERE column_name = ‘<nom_columna>’;

Una variante sobre la consulta incluyendo el propietario y un tipo de dato específico:

    SELECT  table_name
FROM all_tab_columns
WHERE column_name = ‘<nom_columna>’ and
data_type = ‘NVARCHAR2’    and
owner = «<schema_owner>
ORDER BY table_name;

Ejecución de Maven des de consola de comandos MS-DOS

Caso de Ejemplo: Se dispone de un proyecto multi-módulo del que se desean desplegar varios de sus módulos.
Se dispone de Maven en su versión 2.2 y de un servidor Weblogic 9.2 Mp4 para los módulos J2EE de las aplicaciones.
Para automatizar los despliegues de dichos módulos sin necesidad de acceder ni recorrer el árbol de directorios mediante la consola de comandos DOS del Windows 7 se ha creado el siguiente script.

Este script ejecuta los despliegues de cada  uno de los módulos que forman el proyecto J2EE en la carpeta establecida como ruta de despliegue para el servidor Weblogic en el fichero de configuración de Maven.

Además, informa de los nombres de los módulos y de los tiempos en que se ejecuta cada uno de los despliegues y lo almacena todo en un fichero llamado resultado.txt, que puede consultarse con posterioridad.

Una vez realizadas todas las tareas se publica en el fichero un mensaje de finalización de éxito:

echo =================================================
echo TODOS LOS MODULOS HA SIDO DESPLEGADOS CON EXITO  
echo =================================================

Detalle: A continuación se detalla una sección del código fuente del fichero .bat explicando un poco su funcionalidad.

La sección más importante del script es esta sección:

  • ECHO __________>>resultado.txt.
  • echo Modulo ST >>resultado.txt.  Título  del módulo.
  • time /t>>resultado.txt. Se indica el inicio del tiempo de despliegue.
  • ECHO __________>>resultado.txt. 
  • call mvn package war:exploded -f<Ruta_ubicación_fichero_pom>pomITT.xml>>resultado.txt. Se llama al maven  mediante la instrucción call de DOS para ejecutar el despliegue del módulo actual.
  • if not %ERRORLEVEL% == 0 exit /b. En caso de error salimos de la consola de comandos.
  • time /t>>resultado.txt. Se indica el final del tiempo de despliegue y se escribe la salida de pantalla al fichero de texto de resultado.txt.

Se sobreentiende que el fichero POM.xml de cada uno de los módulos o proyectos J2EE ya incluye en su  sección de despliegue la ruta correcta para el servidor Weblogic (En todo caso debe indicarse cuál es la ruta correcta para realizar los despliegues pertinentes).

Actualización del 20/01/2015

En lugar de escribir directamente la ruta de cada uno de los ficheros se utiliza el paso de parámetros en el script. En lugar de utilizar esta línea de código:

call mvn package war:exploded -f<Ruta_ubicación_fichero_pom>pomITT.xml>>resultado.txt 

se modifica esta llamada por esta otra línea de código:

call mvn install -f%1<nombre_del proyecto>pom.xml>>resultado.txt

El %1 permite recuperar la ruta en la que se encuentran los proyectos en desarrollo accediendo al fichero POM pasando dicha ruta como parámetro al script.  Puede utilizarse cualquier ruta o directorio siempre que el directorio disponga de fichero pom.xml con una configuración Maven, sino el script dará un error.
Este cambio por un lado nos permite ejectuar la llamada de Maven en todos los proyectos indistintamente de su ubicación dentro del sistema de archivos dado que la carpeta contenedora siempre se pasa por parámetro.
La configuración de Maven (dentro de la etiqueta <build><plugin>) dentro del fichero POM es la siguiente:
           <plugin>
<groupId>
org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
<attachClasses>true</attachClasses>
<classesClassifier>classes</classesClassifier>
<encoding>ISO-8859-1</encoding>
<webappDirectory>C:/Weblogic_Despliegues/${project.artifactId}</webappDirectory>
</configuration>
</plugin>

El script de ejecución puede encontrarse en este enlace.

Para un mayor detalle sobre el plugin de maven-war-plugin se puede encontrar información detallada en este enlace.

Las 14 mejores prácticas para utilizar JMeter

-No utilizar la consola para preparar las pruebas de carga. Utilizar la consola para depurar o para ejecutar pruebas pequeñas de carga para verificar que el script se ejecuta correctamente es correcto. El GUI consume una gran cantidad de memoria bajo una gran carga, por tanto, la consola no puede soportar por sí misma una carga grande.

-Utilizar servidores remotos para crear la carga. Utilizar la opción de «Remote Start All» o «Remote Start» de los servidores individuales. 

-Limitar el número de hilos por motor de pruebas a un máximo de 300. Esto implica que el número total de hilos generados por Test Plan que se haya generado debe ser inferior a 300. Por ejemplo, un test plan de 200 hilos y 4 motores de pruebas generarán una carga de 800 hilos. 

-Desactivar la opción del listener «View Result Tree» pues consume mucha memoria y puede provocar que se congele la consola o que el JMeter tenga un desbordamiento de memoria. Sin embargo, sí que es recomendable utilizar el listener «View Result Tree» cuando se marca la opción Errores. 

-Desactivar todos los grafos del JMeter pues consumen una gran cantidad de memoria. Se pueden visualizar todos los grafos de tiempo real utilizando la pestaña de JTL en la interfaz web.

-Monitorizar los ficheros de log. Cualquier error en el Test Plan o en el propio Test puede aparecer en los ficheros de log que se encuentran disponibles en la pestaña de Logs. Por ejemplo: errores de Out of Memory, desconexiones, etc.

-No olvidar borrar la ruta local del archivo de configuración utilizado como conjunto de datos (CSV Fecha Siete Config) si se ha usado alguno.

-Los nombres de archivo deben incluir solamente caracteres alfanuméricos, guiones bajos o guiones normales: [0-9], [aA-zz], [_-]. Los nombres de archivo siempre deberían incluir la extensión. 

-Limpiar las pestañas de archivos antes de cada prueba de ejecución del Test Plan. 

-Cuando se utilicen ficheros JTL, asignar nombres con significado a los ficheros pertinentes. Por ejemplo: 150210-4000t-1.jtl. No emplear espacios como separadores en los nombres de los ficheros JTL. 

-Asegurarse que el fichero JTL se guarda en formato XML i no en formato CSV. 

-Acceder al menos una vez en las pestañas JTL para generar informes en tiempo real. 

-Utilizar nombres cortos y significativos para las etiquetas para identificar controladores y creadores de muestras (por ejemplo las peticiones HTTP). Si se utilizan nombres largos, estos nombres ocuparán la mejor sección de los grafos generados utilizando las pestañas de los JTL llegando a molestar cuando se estudien los resultados. 

-Intentar hacer pruebas con el JMeter en la nube: enlace, enlace, enlace, etc …

Weblogic – Doble despliegue de una aplicación J2EE

Al trabajar con weblogic y eclipse, muchas veces da la impresión de que las aplicaciones se despliegan dos veces

  1. Una junto al arranque del servidor y, una vez éste está arrancada, vuelve a hacer el deploy correspondiente.
  2. Parece ser que el problema está en la carpeta tmp del server que no se borra durante los reinicios del servidor.

NOTA: Todos los cambios que se detallan a continuación han sido realizado en un Windows 8.

Para solucionarlo se puede modificar el script de arranque de startWebLogic.cmd añadiendo la instrucción rd de MS-DOS para borrar la carpeta tmp antes de iniciar el servidor.

La modificación quedaria de este modo:

@ECHO OFF 
@REM WARNING: This file is created by the Configuration Wizard. 
@REM Any changes to this script may be lost when adding extensions to this configuration. 
SETLOCAL 
set DOMAIN_HOME=C:OracleMiddlewareuser_projectsdomainscomercio_domain 
@REM Borrar tmp 
rd /S /Q %DOMAIN_HOME%serversAdminServertmp 
call "%DOMAIN_HOME%binstartWebLogic.cmd" %* 
ENDLOCAL

 

La modificación del fichero de arranque se ha producido mediante el servidor Bea Weblogic en su versión 9.2 MP4. 

NOTA: Se pueden aplicar dichos cambios también en los ficheros de arranque de Linux (extensión .sh) o de otros sistemas operativos. El principio de eliminación de la carpeta temporal sirve independientemente de cuál sea el sistema operativo.

OCP7 12 – Conexión JDBC en Java 7

Introducción 

JDBC (Java Database Connectivity) es un acrónimo que identifica la API mediante la cuál las aplicaciones Java pueden conectarse a sistemas gestores de bases de datos (BBDD).
Esta conexión se obtiene por la utilización de interfícies de conexión llamadas controladores JDBC (o conocidos también como drivers).
Estas bases de datos acostumbran a ser en general relacionales, aunque también existen otros drivers para otros tipos de BBDD (nosql, ficheros planos, hojas de cálculo, etc).

API JDBC en Java 7 (Paquetes principales)

La API está compuesta por dos paquetes principales:
Ambos están ya incluidos dentro del SDK estándar de Java cuándo se descarga en su versión 7.
En las notas técnicas puede encontrarse información más detallada, este post pretende ser una introducción solamente.

Uso de JDBC

El paquete java.sql consiste en ejecutar sentencias SQL de tipo consulta, aunque también permite leer y escribir datos  mediante operaciones de modificación realizando su conexión des de cualquier fuente de datos utilizando un formato tabular (en forma de tupla).

La URL del JDBC se construye mediante la plantilla siguiente:

 jdbc : subprotocolo : subnombre

El esquema sobre la operación del controlador JDBC para ejecutar una sentencia SQL en Java:
El algoritmo de ejecución detallado en la imagen anterior es el siguiente:
1.-Mediante el DriverManager se utiliza el método getConnection(…) para disponer de una conexión al SGBD.
2.-Si se ha realizado la conexión con el SGBD de forma correcta, se crea la consulta mediante la API del JDBC utilizando el método createStatement(…).
Además en este paso se parametrizan los elementos que así lo requieran (valores adicionales en los elementos WHERE, posibles alias utilizados, etc)

3.-El último paso consiste en ejecutar la sentencia SQL y gestionar la tupla obtenida como resultado de su ejecución parametrizando la información según se requiera.

Por otro lado el paquete javax.sql,  proporciona una API en la capa del servidor para el acceso a la fuente de datos y procesado del lenguaje de programación Java. Incorpora los siguientes añadidos:

  • La interfície de DataSource  como una alternativa al DriverManager para establecer la conexión con una fuente de datos.
  • Pooling de conexiones y sentencias de SQL.
  • Transacciones distribuidas.
  • Conjuntos de filas.
  • Aplicaciones para utilizar directamente las API’s DataSource y RowSet,  aunque las API’s del pooling de conexiones y de ls transacciones distribuidas se utilizan internamente por intermediarios.
Cuándo se cierran los recursos del JDBC una vez han sido utilizados se sigue el siguiente proceso:
Fig. 2. Cierre de la conexión
Fig. 2. Cierre de la conexión
  1. El cierre de Connection cierra automáticamente todos los recursos.
  2. El cierre del objeto ResultSet debe realizarse explícitamente siempre que no se utilice dado que si se deja automáticamente sólo se cerrará cuándo sea analizado por el recolector de basura. Es una buena práctica siempre cerrarlo explícitamente.
  3. Por último siempre cerrar cualquier recurso externo que sea capaz de mantener activa la conexión del SGBD.
En Java 7 para cerrar correctamente todos los recursos JDBC debe utilizarse una herramienta introducida en llamada try-with-resources:
try (Connection con = DriverManager.getConnection(url, username, password));
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
{
 // Using resources
}catch(Exception ex) {
}
Esto permite cerrar todos los recursos al final del bloque de código.
Si se produce alguna excepción el bloque try antes de ser capturada la excepción, en el bloque catch se cierran los recursos en el orden inverso al utilizado.
Para utilizar correctamente la herramienta try-with-resources entre los paréntesis que lo implementan debemos utilizar los objetos que implementen la interfaz AutoCloseable.

Sql y JDBC

La API del JDBC:

  • No restringe las sentencias que se pueden utilizar en una BBDD.
  • No controla que las sentencias enviadas a la BBDD estén correctamente formuladas.
  • Suministra tres clases y tres métodos respectivamente para el envío de sentencias SQL:
Fig. 3. Creacion de objetos SQL
Fig. 3. Creacion de objetos SQL
  • Statement: Utiliza el método de createStatement y incluye los métodos de executeQuery (para consultas) y executeUpdate(para operaciones de modificación).
  • PreparedStatement: Se utiliza para enviar consultas SQL que tengan uno o más parámetros como argumentos de entrada. Cuenta con métodos propios que nos ayudan a dar valor a estos parámetros.   Se muestra el siguiente código fuente como ejemplo:
PreparedStatement ps = con.prepareStatement(
 "select * from OWNER where ID=? AND NAME=? AND CODE=?");
ps.setInt(1,id-employee);
ps.setString(2,name);
ps.setInt(3,code);
  • CallableStatement:  Se usan para ejecutar procedimientos almacenados SQL (Stored Procedures). Éstos son un grupo de sentencias SQL que son llamados mediante un nombre. Un objeto CallableStatement hereda de PreparedStatement los métodos para el manejo de parámetros y además añade métodos para el manejo de estos parámetros.  Se muestra el siguiente código fuente como ejemplo:
String createProcedure = "create procedure SHOW_SUPPLIERS "
 + "as "+"select SUPPLIERS.SUP_NAME, COFFEES.COF_NAME "
 + "from SUPPLIERS, COFFEES "
 + "where SUPPLIERS.SUP_ID=COFFEES.SUP_ID "
 + "order by SUP_NAME";
CallableStatement cs = con.prepareCall("{call SHOW_SUPPLIERS}");

Toda acción que se realice sobre la BBDD de datos abrir/cerrar conexión, ejecutar una sentencia SQL, etc pueden lanzar una excepción del tipo SQLException que se deberá capturar o propagar.

Este error puede resultar crítico para la integridad de los datos de la BBDD: la clase SQLException hereda de Iterable lo que permite recorrer dicha cadena de fallos. Así es posible recorrer todos los objetos de tipo Throwable que haya en una excepción SQLException.

Transacción

Mecanismo para manejar grupos de operaciones como si fueran una acción realizada de forma única.

Cada transacción debe tener las propiedades ACID:

  • Atomicidad (Atomicity). Una operación se hace o se deshace por completo.
  • Consistencia (Consistency). Transformación de un estado consistente a otro estado consistente.
  • Aislamiento (Isolation). Cada transacción se produce con independencia de otras transacciones que se produzcan al mismo tiempo.
  • Permanencia (Durability). Propiedad que hace que las transacciones realizadas sean definitivas.

Con JDBC se ejecuta un COMMIT automático  (autoCOMMIT) tras cada insert, update o delete (con excepción de si se trata de un procedimiento almacenado).

Para indicar que una sentencia SQL no se ejecuta de forma automática se utilizará el método setAutommit(boolean); de la interfaz Connection pasándole como parámetro el valor false.

De este modo se pueden agrupar varias sentencias SQL en una misma transacción siendo el programador el que gestiona el momento de realizar el COMMIT de la ejecución.

ROLLBACK permite deshacer las transacciones que se hayan ejecutado dejando la BBDD en un estado consistente.
Si se cierra la conexión sin hacer COMMIT o ROLLBACK, explícitamente se ejecuta un COMMIT automático aunque el autoCOMMIT esté asignado a false.

Api RowSet

Fig. 4. RowSet
Fig. 4. RowSet Api Description
Las interfaces que componen la API son las siguientes:

 

CachedRowSet
Permite obtener una conexión des de un DataSource, además de permitir la actualización y desplazamiento de datos sin necesidad de disponer de la conexión a BBDD abierta.

FilterRowSet
Deriva de RowSet y añade la posibilidad de aplicar criterios de filtros para hacer visible cierta porción de datos de un resultado global.

JdbcRowSet
Clase que engloba el funcionamiento básico de un ResultSet y añade capacidades de desplazamiento y actualización de datos.

JoinRowSet
Deriva de WebRoseSet y añade capacidades similares al JOIN de SQL pero sin necesidad de estar conectado a la fuente de datos.

WebRowSet
Deriva de CachedRowSet y añade funcionalidad para la lectura y escritura de documentos XML.

Las clases que componen la API son las siguientes:

BaseRowSet
Clase base abstracta que provee un objeto RowSet junto a su funcionalidad básica.

RowSetMetadaImpl
Clase que proporciona implementaciones para los métodos que establecen y recuperan información de los metadatos de las columnas del objecto RowSet.

Un objeto RowSetMetaDataImpl realiza un seguimiento del número de columnas del RowSet y mantiene un Array interno de los atributos de la columna para cada una de las columnas.

Un objeto RowSet crea internamente un objeto RowSetMetaDataImpl con el fin de establecer y recuperar información sobre sus columnas.

RowSetProvider
Se utiliza para crear un objeto RowSetFactory.  A su vez, RowSetFactory se utiliza para crear instancias de implementaciones de RowSet (que deriva de ResultSet y por lo tanto contiene todas las capacidades de ResultSet pero añadiendo nuevas funcionalidades).

 

OCP7 13 – Localización

Localización

La localización o regionalización es el proceso mediante el cual un producto internacionalizado se configura para una determinada región, aprovechando las opciones que la internacionalización previa de este producto ha permitido (i18n). 

Por ejemplo, la internacionalización puede permitir utilizar distintos formatos de fecha, y la localización consiste en escoger el adecuado para una región específica.

Puede encontrase información adicional en los siguientes enlaces: aquí y aquí.

Ventajas

  • Permite que se adapte un software para una región o idioma específicos añadiendo componentes específicos locales y texto traducido a la región o idioma.
  • La mayor parte de la tarea consiste en la traducción del idioma pero existen también otras tareas como formatos de fechas, cambio de moneda,  tipo de calendario, y cualquier otro elemento distintivo de la región.
El objetivo principal de la localización persigue la adaptación a la referencia cultural sin realizar ninguna modificación en el código fuente que implementa la aplicación.
Una aplicación con localización se divide en dos bloques principales:
1) Elementos de la interfaz de usuario localizable para la referencia cultural como textos, menús, etc…
2) Código Ejecutable:  Código de la aplicación a ser utilizado por todas las referencias culturales.

Ejemplos prácticos de localización: Establecer el idioma al inglés, salir de la aplicación, etc…

 

Paquete de Recursos en Java

La clase ResourceBundle aísla los casos específicos de los locales.
Esta clase devuelve parejas clave-valor de forma independiente que pueden ser programadas en una clase que extienda de ResourceBundle en un archivo de propiedades.
Para utilizarla debe crearse el archivo de paquetes y después llamar a cada localización específica des de nuestra aplicación. Cada clave identifica un componente específico de la aplicación.

Ejemplo clave-valor:

my.hello=Hello

my.goodbye=Bye

Cada fichero del paquete de recursos, sea un fichero de properties o una clase, dispone de un nombre que sigue la siguiente estructura:

Para un fichero de properties:    Message_Bundle_<language>_<country>.properties

Para una clase:   Message_Bundle_<language>_<country>.java

 

Ejemplo de los ficheros de properties:

MessageBundle_en_EN.properties

my.hello=Hello
my.goodbye=Bye
my.question=Do you speak English?

MessageBundle_es_ES.properties

my.hello=Hola
my.goodbye=Adios
my.question=u00bfHablas inglu00e9s?

MessageBundle_sv_SE.properties

my.hello=Hejsan
my.goodbye=Hejd?
my.question=Pratar du engelska?

 

Ejemplo de implementación mediante clases

 

En el ejemplo que se muestra a continuación se implementan 3 clases correspondientes a los mismos casos de uso que en el ejemplo de los ficheros properties. 

Los puntos importantes a resaltar son:

  • Las clases implementadas deben extender de la clase ResourceBundle
  • En el nombre de la clase se debe incluir el identificador del ResourceBundle así como el idioma y el código de país.
  • Se deben implementar el método handleGetObject para acceder a los mensajes a través de su clave
  • También se debe implementar el método getKeys para poder acceder al índice de todas las claves que proporciona la implementación del ResourceBundle
  • En los ejemplos, se ha utilizado un Map como backend de los textos internacionalizados, pero este mecanismo hace posible obtener los textos des de otros soportes, como por ejemplo base de datos. Para ello sólo se tendría que modificar el método populateData para que obtuviera los datos a través de una conexión jdbc. Este método no forma parte de la API de la clase ResourceBundle y sólo sirve a afectos de mostrar un posible mecanismo para indicarle a la implementación realizada la lista de mensajes que se soporta.

MessageBundle_en_EN.java

public class MessageBundle_en_EN extends ResourceBundle 
{
 HashMap data; 
   
   
 public MessageBundle_en_EN()
 {
  data = new HashMap(); 
  populateData();
 }
 
 protected void populateData()
 {
  data.put("my.hello", "Hello");                               
  data.put("my.goodbye", "Bye");                               
  data.put("my.question", "Do you speak English?");        
 }
 
 @Override
 protected Object handleGetObject(String key) 
 {
  return data.get(key);
 }

 @Override
 public Enumeration getKeys() 
 {
  return Collections.enumeration(data.keySet());
 }
}

MessageBundle_es_ES.java

public class MessageBundle_es_ES extends ResourceBundle 
{
 HashMap data; 
   
   
 public MessageBundle_es_ES()
 {
  data = new HashMap(); 
  populateData();
 }
 
 protected void populateData()
 {
  data.put("my.hello", "Hola");                                
  data.put("my.goodbye", "Adios");                             
  data.put("my.question", "¿Hablas inglés?");                    
 }
 
 @Override
 protected Object handleGetObject(String key) 
 {
  return data.get(key);
 }

 @Override
 public Enumeration getKeys() 
 {
  return Collections.enumeration(data.keySet());
 }
}

MessageBundle_sv_SE.properties

public class MessageBundle_sv_SE extends ResourceBundle 
{
 HashMap data; 
   
   
 public MessageBundle_sv_SE()
 {
  data = new HashMap(); 
  populateData();
 }
 
 protected void populateData()
 {
  data.put("my.hello", "Hejsan");                              
  data.put("my.goodbye", "Hejd?");                             
  data.put("my.question", "Pratar du engelska?");       
 }
 
 @Override
 protected Object handleGetObject(String key) 
 {
  return data.get(key);
 }

 @Override
 public Enumeration getKeys() 
 {
  return Collections.enumeration(data.keySet());
 }
}

Formateo especial números y fechas

Existen clases específicas para formatear fechas y números:

Declaraciones de las variables para estos formatos:

NumberFormat currency;

Double money = new Double(1000000.00);

Date date = new Date();

DateFormat dtf;   
A continuación se detalla el código fuente a modo de ejemplo para la inicialización de algunas variables declaradas con anterioridad.
  • DateFormat: El Javadoc puede encontrarse aquí.
  • public void showDate() {
    
         df = DateFormat.getDateInstance(DateFormat.DEFAULT, currentLocale);
    
         pw.println(df.format(today)+" "+currentLocale.toString());
    
    }
  • NumberFormat: El Javadoc puede encontrarse aquí.
  • public void showMoney() {
    
         currency = NumberFormat.getCurrencyInstance(currentLocale);
    
         pw.println(currency.format(money)+" "+currentLocale.toString());
    
    }

A continuación se detalla un caso de ejemplo de localización que muestra mensajes de texto en distintos idiomas (español, inglés y sueco) .

La clase se llama TestLocaleI18N y su implementación es la siguiente:

package i18n; 
 
import java.util.Locale;
import java.util.ResourceBundle;
 
public class TestLocaleI18N { 
 
 /*  
 La carga del ResourceBundle puede hacerse des de fichero, des del contexto de una aplicación,  
 des del propio entorno en el que se esté ejecutando esta clase Java. 
  
 En este caso de ejemplo se utiliza el acceso al fichero properties ubicado dentro  
 del mismo paquete que la clase principal.  
 En un futuro, se realizaran pruebas con el resto de mecanismos de acceso.    
 */ 
 public static void main(String[] args) throws Exception {
 
  ResourceBundle bundle1 = ResourceBundle.getBundle("i18n.TestResourceBundle");
  visualizar(bundle1, null);
 
  Locale deLocale = Locale.getDefault();
  ResourceBundle bundle2 = ResourceBundle.getBundle("i18n.TestResourceBundle", deLocale);
  visualizar(bundle2, deLocale);
 
  Locale svLocale = new Locale("sv", "SE");
  ResourceBundle svBundle = ResourceBundle.getBundle("i18n.TestResourceBundle", svLocale);
  visualizar(svBundle, svLocale);
 
  Locale spLocale = new Locale("es", "ES");
  ResourceBundle spBundle = ResourceBundle.getBundle("i18n.TestResourceBundle", spLocale);
  visualizar(spBundle, spLocale);
   
  Locale enLocale = new Locale("en", "US");
  ResourceBundle enBundle = ResourceBundle.getBundle("i18n.TestResourceBundle", enLocale);
  visualizar(enBundle, enLocale);
   
 } 
 
 public static void visualizar(ResourceBundle bundle, Locale lo) {
  if(lo == null) { lo = Locale.getDefault();}
  System.out.println("Idioma: "+lo.getLanguage()); 
  System.out.println(".........................................................");
  System.out.println("Contenido Mensaje -->hello: " +" "+ bundle.getString("my.hello"));
  System.out.println("Contenido Mensaje -->goodbye: " +" "+ bundle.getString("my.goodbye"));
  System.out.println("Contenido Mensaje -->question: " +" "+ bundle.getString("my.question"));
  System.out.println("=========================================================");
 } 
}

 

El resultado de la ejecución se mostraría mediante la consola y sería algo así:

Idioma: es
…………………………………………………
Contenido Mensaje –>hello:  Hola
Contenido Mensaje –>goodbye:  Adios
Contenido Mensaje –>question:  ¿Hablas inglés?
=========================================================
Idioma: es
…………………………………………………
Contenido Mensaje –>hello:  Hola
Contenido Mensaje –>goodbye:  Adios
Contenido Mensaje –>question:  ¿Hablas inglés?
=========================================================
Idioma: sv
…………………………………………………
Contenido Mensaje –>hello:  Hejsan
Contenido Mensaje –>goodbye:  Hejd?
Contenido Mensaje –>question:  Pratar du engelska?
=========================================================
Idioma: es
…………………………………………………
Contenido Mensaje –>hello:  Hola
Contenido Mensaje –>goodbye:  Adios
Contenido Mensaje –>question:  ¿Hablas inglés?
=========================================================
Idioma: en
…………………………………………………
Contenido Mensaje –>hello:  Hello
Contenido Mensaje –>goodbye:  Bye
Contenido Mensaje –>question:  Do you speak English?
=========================================================

OCP7 05 – La herencia en las interfaces Java

Uso de las interfaces Java

Una interfaz representa una alternativa a la herencia multiple de objetos.
Son similares a las clases abstractas ya que contienen únicamente métodos públicos y abstractos.
Ninguno de sus métodos pueden ser implementados (ni siquiera con un conjunto vacío de llaves).
La declaración de una interfaz es similar a la declaración de una clase.
Se usa la palabra reservada interface.
Para la implementación de una interface se añade implements a la clase que implementa la interfaz.
Una interfaz puede utilizarse como un tipo de referencia. Puede utilizarse el operador instanceof con las interfaces para detectar si un objeto es del tipo de referencia indicado por la interfície implementada.
Interfaces de Marcador: definen un tipo concreto pero no describen  los métodos que deben ser implementados por una clase, sólo sirven para la comprobación de tipos.
Existen dos tipos:
* java.io.Serializable és una interfaz de marcador utilizado por la biblioteca de E/S de Java para determinar si un objeto puede tener su estado serializado.

Como convertir de un tipo de dato al tipo de la interfaz

Antes de generar una excepción en la conversión de tipos de unos objetos a otros objetos se comprueba que dicha conversión sea posible mediante la utilización del operador instanceof (ya comentado anteriormente).
En general, cuándo se utilicen referencias, éstas deben utilizar el tipo más genérico posible, es decir, que sirvan para cualquier tipo de interfaz o clase padre. Así la referencia no se vincula a una clase particular.
Una clase puede heredar de una clase padre e implementar una o varias interfaces pero siempre en este orden: primero hereda – extends – y después implementa – implements separando las interfaces mediante comas.
Una interfaz puede heredar de otra interfaz.
Java no permite la herencia múltiple de clases pero sí la herencia múltiple de interfaces:
Fig. 1 Herencia múltiple de interfaces

Si escribimos una clase que hereda de una clase que implementa una interfaz, entonces la clase que estamos escribiendo hereda también de dicha interfaz. La refactorización consiste en realizar modificaciones en el código para mejorar su estructura interna sin alterar su comportamiento externo.

Composición

Este patrón de diseño permite la creación de objetos más complejos a partir de objetos más simples. Se crea una nueva clase con referencias a otras clases. A esta nueva clase le agregaremos los mismos métodos que tienen las demás clases.

 

public class ComplexClass {
	private Single1 c1 = new Single1();
	private Single2 c2 = new Single2();
	private Single3 c3 = new Single3();
}
Fig. 4 Ejemplo de patrón Composition

Referencia al polimorfismo

Vamos a describir un ejemplo de polimorfismo. Si existe una clase nueva llamada Hombre que dispone  de un método addCoche con la configuración de clases establecida en la siguiente imagen:

Fig. 7 Ejemplo de polimorfismo erróneo  en la Composición
no se le puede pasar como argumento al método addCoche de Hombre cualquier tipo de coche.
Solución: Para soportar el polimorfismo en las composiciones cada clase usada en la composición debe disponer de una interfaz definida y así se le podrá pasar cualquier tipo de coche al método en cuestión.
Fig. 8 Ejemplo de polimorfismo correcto  en la Composición

 

OCP7 07 – Manejo de Cadenas

Argumentos y formatos de cadenas

El método main contiene el parámetro String[] args. Puede recibir zero o más argumentos.
La implementación de la clase es la siguiente.
public class Echo {
 public static void main(String[] args) {
  for (String s: args) {
   System.out.println(s);
  }
 }
}

La clase Echo puede recibir los siguientes parámetros por línea de consola de comandos.

java Echo Enero Febrero Marzo Abril

Pasándole como argumentos en la línea de comandos los cuatro primeros meses del año.

Cada uno de los meses separados por un salto de línea. Esto es así debido a que el carácter espacio se utiliza para separar los parámetros unos de otros mediante un salto de línea entre cada uno.

Si se quiere mostrar un frase o texto completo, por ejemplo

            java Echo «Enero, Febrero, Marzo, Abril son los cuatro primeros meses…»

se debe indicar la apertura y el cierre del texto mediante comillas dobles («»).

Debe tenerse en cuenta que los arrays SIEMPRE empiezan con el valor 0 nunca con el 1. Para recuperar los parámetros recibidos mediante el método main se utilizan los indices del vector. Así con el código args[0] se recupera el primer parámetro, con args[1] se recupera el segundo, etc.

Adicionalmente, si una aplicación necesita recibir argumentos de tipo numérico, debe convertirse el argumento de tipo String a un argumento que represente un número, como por ejemplo el «34», a su valor numérico equivalente, el 34.

Este snippet transforma un argumento de consola de comandos en un tipo entero:

int primerArg;
if (args.length > 0) {
    try {
        primerArg = Integer.parseInt(args[0]);

System.out.println("Se ha convertido la cadena "+args[0]+" en el número siguiente -> "+primerArg);
    } catch (NumberFormatException e) {
        System.err.println("Argumento " + args[0] + " debe ser un número entero.");
        System.exit(1);
    }
}

primerArg lanza una excepción del tipo NumberFormatException si el formato de args[0] no es valido. Todas las clases de tipo Number Integer, Float, Double y demás — disponen de métodos de conversión que transforman un String representando un número en un objeto de su tipo específico.

Formatos de cadena

Los distintos argumentos de conversión que podemos utilizar para modificar el aspecto de una objeto String son los siguientes:
Fig. 1. Argumentos_conversion_Strings
Fig.1 Argumentos de conversión de String

Cómo ejemplo inicial para limitar el número de caracteres que se visualizan por pantalla es suficiente con utilizar %2.2x dónde x corresponde al argumento de conversión que se haya pasado. 

PrintWriter

PrintWriter es una nueva clase de impresión bastante similar a Printf perteneciente a la librería java.io.  Puede encontrarse su Javadoc aquí.

PrintWriter pw = new PrintWriter(System.io, true);

pw.printf("Texto escrito mediante Pw");

 

Procesamiento de Cadenas

Dentro del JDK en su versión del Java 7 existen varias clases Java que permiten manipular y tratar los elementos de tipo cadena. Son clases ya existentes en versiones anteriores del JDK.

1.-String.

Representa una cadena de caracteres inalterable. Al modificar un objeto String lo que estamos haciendo en realidad es crear otro objeto String. No es la más eficiente ni la mejor. Ideal para tratar con cadenas de texto cuyo valor sabemos que no se modificará: mensajes de alerta, texto, informativo, etc.

 

2.-StringBulider/StringBuffer.
Debe utilizarse cuándo debamos trabajar con cadenas de texto que deban modificar su contenido en tiempo de ejecución. Ambas disponen del mismo API de desarrollo.
Como norma general utilizaremos StringBuilder en lugar de StringBuffer.
Razón: Los métodos de StringBuffer son sincronizados por lo que pueden ser utilizados de forma segura en un ambiente multihilo.

Los métodos de StringBuilder no son sincronizados por lo que su uso implica un mejor rendimiento cuándo se usan localmente.

En general, la concatenación de Strings ocurre con variables locales a un método por lo que es recomendable utilizar de forma general StringBuilder en lugar de StringBuffer.

Cuan rápido es StringBuilder sobre StringBuffer?
StringBuilder puede resultar un 50% más rápido para concatenar String.
Para esta implementación.
public class StringBuilder_vs_StringBuffer {

    public static void main(String[] args) {
        StringBuffer sbuffer = new StringBuffer();
        long inicio = System.currentTimeMillis();

        for (int n = 0; n < 1000000; n++) {
            sbuffer.append("zim");
        }

        long fin = System.currentTimeMillis();
        System.out.println("Time using StringBuffer: " + (fin - inicio));

        StringBuilder sbuilder = new StringBuilder();

        inicio = System.currentTimeMillis();

        for (int i = 0; i < 1000000; i++) {
            sbuilder.append("zim");
        }

        fin = System.currentTimeMillis();
        System.out.println("Time using StringBuilder: " + (fin - inicio));


    }
}
obteniendo casi una mejora del 50% utilizando StringBuilder.
Fig. 2. Tiempos de ejecución
Fig. 2 Tiempo en concatenar Strings

Clases Auxiliares en la Manipulación de cadenas

StringTokenizer

Extrae información (en forma de tokens) de una cadena de texto cuyos caracteres están separados por un carácter o símbolo especial o separador. Recorre la cadena de texto y obtiene las cadenas obtenidas (tokens) a partir del símbolo especial o separador indicado en la llamada al método.

// Inicialización
StringTokenizer  st = new StringTokenizer("this is a test");

// Utilización
while(st.hasMoreTokens())  {
      System.out.println(st.nextToken())
}

Puede encontrarse información más detallada dentro de la API de Java 7 en la siguiente dirección.

Scanner

Extrae información de una cadena o flujo de datos como StringTokenizer. Cambia el  tipo de dato a las divisiones mientras se itera sobre ellas (StringTokenizer no puede), es decir, ante un flujo de datos podremos capturar enteros, decimales, etc en función de nuestro método de iteración utilizando Scanner.

Error de codificación Unicode en un mensaje Javascript

Descripción del Problema

Cuando se publica un mensaje que contiene un carácter en formato Unicode no muestra el texto correctamente. No se renderiza el carácter Unicode en Javascript sino que se muestra directamente la codificación

Análisia del Problema

En el fichero JSP contenedor se encuentra la siguiente llamada:

        <a  
                onclickreturn(confirm(«Mensaje de llamada previo al mu00E9todo?«));» 
                href=»<ruta_web_navegacion>»
        >

Cuando el navegador renderiza el botón y procesa la funcionalidad del atributo onclick no renderiza correctamente el texto contenido dentro de los confirm como carácter Unicode desde el Javascript, sino que lo interpreta como un string que forma parte de la cadena contenida dentro del confirm .

Solución

Hay que añadir en el JSP una sección Javascript donde se implementa la siguiente función:

        <script>
function metodo() {
return confirm(«Mensaje de llamada previo al mu00E9todo?»);
}
</script>

Esta nueva función renderiza directamente el texto contenido en el mensaje desde Javascript no desde HTML.

En el código HTML del enlace <a> hay que indicar en el atributo onclick el siguiente código para ejecutar correctamente la ventana confirm y posteriormente el envío del resultado al onclick del botón:      

       <a   
                onclickreturn(metodo());» 
                href=»<ruta_web_navegacion>»
        >

Esto permite que la codificación Unicode sea interpretada correctamente y se obtiene el carácter é lugar de la codificación ue00E9 cuando se muestra el mensaje por pantalla.

Detalle

El método confirm devuelve el resultado de la opción elegida cuando se abre la ventana mediante Javascript.

Lo que se está haciendo se redirigir este regreso (sea true o false) hacia el botón onclick de manera que se ejecute directamente o no según la selección de las opciones del confirm Javascript que se haya efectuado.

JMeter – Plugin Statistical Aggregate Report

Página principal

http://rubenlaguna.com/wp/better-jmeter-graphs/

Visión General

Muestra de una manera diferente de presentar los datos de forma más clara y sencilla que los informes estándar por defecto del JMeter.

A grandes rasgos, el eje vertical de la izquierda indica el ratio de salida, el número de hilos por segundo durante la ejecución y el eje horizontal muestra el tiempo en el que se ha ejecutado la prueba. Por último, el eje vertical de la derecha muestra el tiempo de respuesta de todas las muestras.

Así, con este informe se puede ver la interacción entre el tiempo de la prueba, el número de hilos cargados por segundo y el tiempo de respuesta para cada uno de ellos.

http://rubenlaguna.com/wp/wp-content/uploads/2006/12/stataggvisualizer.zip

Instalación

Aunque se detalla en la propia página oficial incluye el proceso de instalación como guía rápida.

La instalación se ha efectuado en la versión Apache JMeter (2.11 r1554548) del JMeter.

Para instalar el añadido evidentemente es necesario disponer del fichero StatAggVisualizer.zip. 

Hay que descomprimir el archivo completo. Seguidamente hay que acceder al directorio de instalación del 2.2.

El archivo comprimido dispone de cuatro archivos en su interior: Tres de ellos vale directamente a la carpeta $JMETER_HOME/lib y los otros fichero hay que colocarlos directamente en el directorio $JMETER_HOME/lib/ext.

Cuando se descomprime el archivo ya se genera la estructura de archivos apropiada, como por si acaso, los archivos jcommon-1.0.5.jar, jdnc-0.6-all.jar i el fitxer jfreechart-1.0.2.jar hace falta colocarlos directamente a la carpeta $JMETER_HOME/lib y el jar StatAggVisualizer.jar es necesario también colocarlo en $JMETER_HOME/lib/ext.

Una vez instalado, es necesario arrancar el JMeter y podrá verse la opción de «Statistical Aggregate Report» en la opción de menú Añadir -> Receptor haciendo clic sobre el Grupo de Hilos con el botón derecho del ratón.