Not in an application scope – start OC4J with the -userThreads switch if using user-created threads

Cuándo dentro del servidor OC4J se produce el siguiente error:
Not in an application scope – start OC4J with the -userThreads switch if using user-created threads
Este error se produce dentro de un proyecto J2EE que dispone de código fuente que genera hilos bajo demanda del programador. El servidor detecta dicha generación manual y muestra el mensaje de error dando una pista sobre cómo solucionar el problema de compatibilidad.

En el caso concreto comentado es obligatorio utilizar el atributo -userThreads («Enables context lookup support from user-created threads») del servidor OC4J. Esto permite que el servidor sea capaz de gestionar además de los hilos internos propios también los creados manualmente por el usuario desde la aplicación J2EE.

Este parámetro debe indicarse en el Script de arranque del servidor (en caso de ejecutarse des de consola también debe añadirse como parámetro):
java -jar oc4j.jar -userthreads
Documentación Oficial:

Hilite.me – decorador de código fuente para blogs y otras publicaciones

Página web que permite transformar secciones de código fuente en HTML para incrustarlo de forma legible y atractiva en publicaciones en Internet.

Al acceder a la página principal se muestran dos secciones, una para añadir el código fuente original y la otra para obtener el código fuente formateado en HTML con el estilo escogido .

Como parámetros de configuración se pueden configurar el lenguaje, el estilo, indicar si se desean añadir líneas de código y la opción de aplicar estilos CSS directamente. Todo ello se puede aplicar de forma sencilla y amena.

Por último, una vez establecida la configuración interesada sólo resta hacer clic en el botón Highlight para obtener el código HTML final.

Posteriormente es suficiente con copiar el HTML generado y incrustarlo en el código fuente de la página web destino. Una vez guardado dicho cambio, al acceder a la página debería mostrarse correctamente el código fuente formateado.

Más información en la página oficial: http://hilite.me/api

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;

Creación de un Fat Jar con Apache ANT

Normalmente para construir el distribuible de una aplicación Java se empaqueta el código principal de esta dentro de un fichero jar ejecutable, esto es, que contiene dentro de su fichero de definición MANIFEST.MF una entrada que especifica qué clase contiene el metodo main() y junto a este se crea una carpeta que contenga todas las dependéncias que este (habitualmente se llama a esta carpeta lib).

Seguir leyendo Creación de un Fat Jar con Apache ANT

Obtener la conexión a base de datos a través de Hibernate 4

Si estáis trabajando en una aplicación en la que la persistencia se hace a través de Hibernate 4, os habréis dado cuenta que ha desaparecido la posibilidad de obtener el objecto Connection a través de la Session de Hibernate. Esto sucede porque en el paso de Hibernate 3 a Hibernate 4 ha desaparecido el método connection() a través del que se podía obtener.

Seguir leyendo Obtener la conexión a base de datos a través de Hibernate 4

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 06 – Genéricos y colecciones – Introducción

Tipos de Genéricos

Los objetos genéricos se describen de forma abstracta mediante la siguiente notación:
Objetos Genéricos <T>
Por convención en Java dentro del operador diamante se ha establecido la siguiente convención:
  • T – Tipo
  • E – Elemento
  • K – Key
  • V – Valor
  • S, U – Se emplea si hay 2, 3 o más tipos definidos.
El Operador Diamante es <..> y permite evitar el uso del tipo genérico T en la construcción de un objeto dado que a partir de su declaración se infiere el tipo T asociado. Además, el operador simplifica y mejora la lectura del código fuente.

Tipos de Colecciones

Una colección es un objeto único que maneja un grupo de objetos.  A esta agrupación de objetos también les llamamos elementos, tienen operaciones de inserción, borrado y consulta.
El framework de colecciones en Java es un arquitectura unificada que representa y maneja las colecciones independientemente de los detalles de implementación. Implementan pilas, colas, etc… y sus clases se almacenan en java.util.
Fig. 1. Detalle interface Collection
Fig. 1 Detalle Interfície Colecciones.
List
Una lista es una interfaz que define el comportamiento de una lista genérica. Colección ordenada en que cada elemento ocupa una posición identificada por un índice. Las listas crecen de forma dinámica. Se pueden añadir, eliminar, sobrescribir elementos existentes, y se permiten elementos duplicados.
List<T> lista = new ArrayList<>(3)

Un ArrayList es la implementación más conocida de una Collection, aunque también existen LinkedList y otras implementacions no detalladas en este post. En este enlace se puede profundizar en su conocimiento de forma más exahustiva.

Además de List existe otra interfície que deriva de Collection llamada Set cuyas implementaciones más conocidas son Hashset y TreeSet (implementación ésta de la interfaz SortedSet).

Existe una tercera interfaz que también deriva de Collection llamada Queue. En este enlace puede encontrarse información más detallada.

Para un mayor detalle y nivel de profundidad respecto a la clase Collections de Oracle, puede consultarse su documentación oficial online en este enlace para el JDK 7.

 

Autoboxing & Unboxing

Los tipos primitivos (int , float, double, etc…..) usados en Java no forman parte de su jerarquía de clases por cuestiones de eficiencia.
Java permite un mecanismo de envoltura llamado Wrapper para poder encapsular un tipo primitivo en un objeto. Una vez encapsulado dicho tipo primitivo, su valor puede ser recuperado mediante los métodos asociados a la clase de envoltura.
Nomenclatura de los procesos:
  • AutoBoxing: Encapsular el valor de un tipo primitivo en un objeto Wrapper.
  • Unboxing: Extraer el valor de un tipo primitivo de un objeto Wrapper.
Su utilización simplifica la sintaxis y produce código más limpio y legible para los programadores.
import java.util.ArrayList;
import java.util.List;

public class UnboxingAndAutoboxing {
    public static void main(String[] args) {
        //  Autoboxing
        int inNumber=50; 
        Integer a2 = new Integer(a);  //Boxing 
        Integer a3 = 5;               //Boxing 
        System.out.println(a2+" "+a3);
        // Unboxing
        Integer i = new Integer(-8);
        // 1. Unboxing through method invocation
        int absVal = absoluteValue(i);
        System.out.println("absolute value of " + i + " = " + absVal);
        List<Double> ld = new ArrayList<>();
        ld.add(3.1416);    // Π is autoboxed through method invocation.

        // 2. Unboxing through assignment
        double pi = ld.get(0);
        System.out.println("pi = " + pi);
    }

    public static int absoluteValue(int i) {
        return (i < 0) ? -i : i;
    }
}

Fig. 2 Ejemplo de Autoboxing & Unboxing

OCP7 09 – Principios básicos de E/S

Streams

El término define una corriente de datos de una fuente a un destino.

Todos los datos fluyen a través de un ordenador desde una entrada (fuente) hacia una salida (destino).

Los fuentes y destinos de datos son nodos de los flujos en la comunicación del ordenador. Todos los flujos presentan el mismo modelo a todos los programas Java que los utilizan:

flujo de entrada: para leer secuencialmente datos desde una fuente (un archivo, un teclado por ejemplo). Llamado también como input stream.
flujo de salida: para escribir secuencialmente datos a un destino (una pantalla, archivo, etc). Llamado también como outputstream.
Estos nodos pueden ser representados por una fuente de datos, un programa, un flujo, etc..

 

Flujos de Datos (Bytes y carácteres)

 

La tecnología Java admite dos tipos de datos en los flujos: bytes y carácteres.
Fig. 1 Tipos de Datos admitidos en Java

En el lenguaje Java los flujos de datos se detallan mediante clases que forman jerarquías según sea el tipo de dato char Unicode de 16 bits o byte de 8 bits.

A su vez, las clases se agrupan en jerarquías según sea su función de lectura (Read) o de escritura (Write).

La mayoría de las clases que se utilizan con Streams se encuentran ubicadas en el paquete java.io.  En la cabecera del código fuente debe escribirse el importe del paquete import java.io.*;

  • Métodos básicos de lectura de Streams
    • Clase InputStream (Bytes)
      • int read()
      • int read(byte[] buffer)
      • int read(byte[] buffer, int offset, int length)
    • Clase Reader (Caracteres)
      • int read()
      • int read(char[] buffer)
      • int read(char[] buffer, int offset, int length)
  • Métodos básicos de escritura de Streams 
    • Clase OutputStream (Bytes)
      • void write(int c)
      • void write(byte[] buffer)
      • void write(byte[] buffer, int offset, int length)
    • Clase Writer (Caracteres)
      • void write(int c)
      • void write(char[] buffer)
      • void write(char[] buffer, int offset, int length)
      • void write(String string)
      • void write(String string, int offset, int length)

Lectura/escritura en ficheros

Los tipos fundamentales de nodos o elementos a los que puede entrar y salir un flujo de datos que se pueden encontrar en el JDK 1.7 de Java son los siguientes:

Fig. 2 Tipos fundamentales de elementos en un flujo de datos

 

Todos los flujos deben cerrarse una vez haya finalizado su uso, forzando un close dentro de la cláusula finally.

Flujos en Memoria Intermedia

Para la lectura de archivos cortos de texto es mejor utilizar FileInputStream en conjunción con FileReader. A continuación se añaden algunos ejemplos con código fuente para la memoria intermedia.

1.-Ejemplo TestBufferedStreams

package bufferedstreams;

import java.io.*;

public class TestBufferedStreams {

    public static void main(String[] args) {
        try (
           BufferedReader bufInput = 
       new BufferedReader(new FileReader("src\bufferedstreams\file1.txt"));
           BufferedWriter bufOutput = 
       new BufferedWriter(new FileWriter("src\bufferedstreams\file2.txt"))
        ){
            String line = bufInput.readLine();
            while (line != null) {
               
                bufOutput.write(line, 0, line.length());
                bufOutput.newLine();               
                line = bufInput.readLine();                
            }
        } catch (IOException e) {
            System.out.println("Exception: " + e);
        }
    }
}

2.-Ejemplo TestCharactersStreams

package bufferedstreams;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class TestCharactersStreams {

    public static void main(String[] args) {
        try (FileReader input = new FileReader("src\bufferedstreams\file1.txt");
             FileWriter output = new FileWriter("src\bufferedstreams\file2.txt")) {

            int charsRead;
            while ((charsRead = input.read()) != -1) {
                output.write(charsRead);
            }
        } catch (IOException e) {
            System.out.println("IOException: " + e);
        }
    }
}

 

Ejemplo de entrada y salida estándar

Existen en Java 7 tres flujos estándar principales:
  • System.in. Campo estático de entrada de tipo InputStream lo que permite leer desde la entrada estándar.
  • System.out. Campo estático de salida de tipo PrintStream lo que permite escribir en la salida estándar.
  • System.err. Campo estático de salida de tipo PrintStream lo que permite escribir en el error estándar.
A continuación se indican los métodos principales print y println de la clase PrintStream
  • Métodos print con parámetros distintos
    • void print(boolean b)
    • void print(char c)
    • void print(char[] s)
    • void print(double d)
    • void print(float f)
    • void print(int i)
    • void print(long l)
    • void print(Object obj)
    • void print(String s)
  • Métodos print con parámetros distintos
    • void println()
    • void println(boolean x)
    • void println(char x)
    • void println(char[] x)
    • void println(double x)
    • void println(float x)
    • void println(int x)
    • void println(long x)
    • void println(Object x)
    • void println(String x)
Ambos métodos son métodos sobrecargados de la clase PrintStream. A continuación se añade un ejemplo con código fuente para la entrada y salida estándar.

1.-Ejemplo KeyboardInput
import java.io.*;

public class KeyboardInput {

    public static void main(String[] args) {

        try (BufferedReader in = new BufferedReader(new InputStreamReader(System.in))) {
            String s = "";
            while (s != null) {
                System.out.print("Type xyz to exit: ");
                s = in.readLine().trim();                
                System.out.println("Read: " + s);
                System.out.println("");

                if (s.equals("xyz")) {
                    System.exit(0);
                }
            }
        } catch (IOException e) {
            System.out.println("Exception: " + e);
        }
    }
}

 

Persistencia

La persistencia consiste en el proceso de serialización (secuencia de bytes) y la deserialización (reconstrucción del objeto obteniendo una copia a partir de los bytes) de un objeto en Java.
Un objeto tiene capacidad de persistencia cuándo puede almacenarse en disco o mediante cualquier otro dispositivo de almacenamiento o enviado a otra máquina y mantener su estado actual correctamente.
Dentro de una aplicación Java, cualquier clase que quiera ser serializada debe implementar la interfaz java.io.Serializable, marcador utilizado para indicar que la clase puede ser serializada.
Puede producirse la excepción NotSerializableException cuándo un objeto no se puede serializar.
Los campos marcados con los modificadores static o transient no pueden ser serializados por lo que al deserializar un objeto dichos campos apuntaran a un valor nulo o cero al finalizar la reconstrucción del objeto. A continuación se añade un ejemplo con código fuente para obtener la persistencia de los datos de un estudiante. Se incluyen la definición del objeto Student, y las clases para la persistencia junto a la clase de ejecución.

1.- Ejemplo DeserializeMyClass

package persistence;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class DeserializeMyClass {

    public static void main(String[] args) {
        
        MyClass myclass = null;
        
        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("file1.ser"))) {
            myclass = (MyClass) in.readObject();
            
        } catch (ClassNotFoundException | IOException e) {
            System.out.println("Exception deserializing file1.ser: " + e);
        }
        System.out.println("a = " + myclass.a);
        System.out.println("b = " + myclass.b);
        System.out.println("cad1 = " + myclass.getCad1());
        System.out.println("cad2 = " + myclass.getCad2());
    }
}

2.- Ejemplo MyClass

package persistence;

import java.io.Serializable;

public class MyClass implements Serializable {

    public int a = 0;
    private String cad1 = "";
    static int b = 0;    
    private transient String cad2 = "";
    Student student = new Student();

    public String getCad1() {
        return cad1;
    }

    public void setCad1(String cad1) {
        this.cad1 = cad1;
    }

    public String getCad2() {
        return cad2;
    }

    public void setCad2(String cad2) {
        this.cad2 = cad2;
    }
}

3.- Ejemplo SerializeMyClass

package persistence;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class SerializeMyClass {

    public static void main(String[] args) {
        
        MyClass myclass = new MyClass();
        myclass.a = 100;
        myclass.b = 200;
        myclass.setCad1("Hello World");
        myclass.setCad2("Hello student");

        try (ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("file1.ser"))) {
            o.writeObject(myclass);
            
        } catch (IOException e) {
            System.out.println("Exception serializing file1.ser: " + e);
        }
    }
}

4.- Ejemplo Student

package persistence;

public class Student {

    String name = "Darío";
    int age = 3;
}

 

Recordatorio 

Las clases BufferedReader y BufferedWriter aumentan la eficacia de las operaciones de entrada y salida. Estas clases permiten gestionar el búfer y escribir o leer línea por línea. A continuación se añade un ejemplo sencillo utilizando un BufferedReader para leer la cadena «xyz» y finalizar la ejecución.1.-Ejemplo utilizando BufferedReader

try (BufferedReader in = new BufferedReader(
  new InputStreamReader(system.in)))) {
   String s = "";
   System.out.print("Type xyz to exit");
   s = in.readline().trim();
   System.out.print("Read "+s);

   // ...
}